xref: /freebsd/contrib/tcsh/ed.init.c (revision cf4c5a533126ca1ddb1f070af73f8f53b9e77fd4)
1 /* $Header: /p/tcsh/cvsroot/tcsh/ed.init.c,v 3.60 2006/08/24 20:56:31 christos Exp $ */
2 /*
3  * ed.init.c: Editor initializations
4  */
5 /*-
6  * Copyright (c) 1980, 1991 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 #include "sh.h"
34 
35 RCSID("$tcsh: ed.init.c,v 3.60 2006/08/24 20:56:31 christos Exp $")
36 
37 #include "ed.h"
38 #include "tc.h"
39 #include "ed.defns.h"
40 
41 /* ed.init.c -- init routines for the line editor */
42 /* #define DEBUG_TTY */
43 
44 int     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
45 int     MacroLvl = -1;		/* pointer to current macro nesting level; */
46 				/* (-1 == none) */
47 static int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
48 static unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
49 				 * pathconf(2) */
50 
51 int     Tty_eight_bit = -1;	/* does the tty handle eight bits */
52 
53 extern int GotTermCaps;
54 
55 static ttydata_t extty, edtty, tstty;
56 #define qutty tstty
57 
58 #define SHTTY (insource ? OLDSTD : SHIN)
59 
60 #define uc unsigned char
61 static unsigned char ttychars[NN_IO][C_NCC] = {
62     {
63 	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
64 	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
65 	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
66 	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
67 	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
68 	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
69 	(uc)CTIME
70     },
71     {
72 	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
73 	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
74 	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
75 	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
76 	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
77 	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
78 	0
79     },
80     {
81 	0,		 0,		  0,		   0,
82 	0,		 0,		  0,		   0,
83 	0,		 0,		  0,		   0,
84 	0,		 0,		  0,		   0,
85 	0,		 0,		  0,		   0,
86 	0,		 0,		  0,		   0,
87 	0
88     }
89 };
90 
91 #ifdef SIG_WINDOW
92 void
93 check_window_size(int force)
94 {
95     int     lins, cols;
96 
97     /* don't want to confuse things here */
98     pintr_disabled++;
99     cleanup_push(&pintr_disabled, disabled_cleanup);
100     /*
101      * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
102      * partially hidden window gets a SIG_WINDOW every time the text is
103      * scrolled
104      */
105     if (GetSize(&lins, &cols) || force) {
106 	if (GettingInput) {
107 	    ClearLines();
108 	    ClearDisp();
109 	    MoveToLine(0);
110 	    MoveToChar(0);
111 	    ChangeSize(lins, cols);
112 	    Refresh();
113 	}
114 	else
115 	    ChangeSize(lins, cols);
116     }
117     windowchg = 0;
118     cleanup_until(&pintr_disabled);	/* can change it again */
119 }
120 
121 void
122 /*ARGSUSED*/
123 window_change(int snum)
124 {
125     USE(snum);
126     windowchg = 1;
127 }
128 
129 #endif /* SIG_WINDOW */
130 
131 void
132 ed_set_tty_eight_bit(void)
133 {
134     if (tty_getty(SHTTY, &extty) == -1) {
135 #ifdef DEBUG_TTY
136 	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
137 #endif /* DEBUG_TTY */
138 	return;
139     }
140     Tty_eight_bit = tty_geteightbit(&extty);
141 }
142 
143 
144 int
145 ed_Setup(int rst)
146 {
147     static int havesetup = 0;
148     struct varent *imode;
149 
150     if (havesetup) 	/* if we have never been called */
151 	return(0);
152 
153 #if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
154     !defined(WINNT_NATIVE)
155     {
156 	long pcret;
157 
158 	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
159 	    vdisable = (unsigned char) _POSIX_VDISABLE;
160 	else
161 	    vdisable = (unsigned char) pcret;
162 	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
163 	    for (rst = 0; rst < C_NCC; rst++) {
164 		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
165 		    ttychars[ED_IO][rst] = vdisable;
166 		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
167 		    ttychars[EX_IO][rst] = vdisable;
168 	    }
169     }
170 #else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
171     vdisable = (unsigned char) _POSIX_VDISABLE;
172 #endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
173 
174     if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
175 	if (!Strcmp(*(imode->vec), STRinsert))
176 	    inputmode = MODE_INSERT;
177 	else if (!Strcmp(*(imode->vec), STRoverwrite))
178 	    inputmode = MODE_REPLACE;
179     }
180     else
181 	inputmode = MODE_INSERT;
182     ed_InitMaps();
183     Hist_num = 0;
184     Expand = 0;
185     SetKillRing(getn(varval(STRkillring)));
186 
187 #ifndef WINNT_NATIVE
188     if (tty_getty(SHTTY, &extty) == -1) {
189 # ifdef DEBUG_TTY
190 	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
191 # endif /* DEBUG_TTY */
192 	return(-1);
193     }
194 
195     tstty = edtty = extty;
196 
197     T_Speed = tty_getspeed(&extty);
198     T_Tabs = tty_gettabs(&extty);
199     Tty_eight_bit = tty_geteightbit(&extty);
200 
201 # if defined(POSIX) || defined(TERMIO)
202     extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
203     extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
204 
205     extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
206     extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
207 
208     extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
209     extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
210 
211     extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
212     extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
213 
214 #  if defined(IRIX3_3) && SYSVREL < 4
215     extty.d_t.c_line = NTTYDISC;
216 #  endif /* IRIX3_3 && SYSVREL < 4 */
217 
218 # else	/* GSTTY */		/* V7, Berkeley style tty */
219 
220     if (T_Tabs) {	/* order of &= and |= is important to XTABS */
221 	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
222 	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
223     }
224     else {
225 	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
226 	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
227     }
228 
229     extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
230     extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
231 
232 # endif /* GSTTY */
233     /*
234      * Reset the tty chars to reasonable defaults
235      * If they are disabled, then enable them.
236      */
237     if (rst) {
238 	if (tty_cooked_mode(&tstty)) {
239 	    tty_getchar(&tstty, ttychars[TS_IO]);
240 	    /*
241 	     * Don't affect CMIN and CTIME for the editor mode
242 	     */
243 	    for (rst = 0; rst < C_NCC - 2; rst++)
244 		if (ttychars[TS_IO][rst] != vdisable &&
245 		    ttychars[ED_IO][rst] != vdisable)
246 		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
247 	    for (rst = 0; rst < C_NCC; rst++)
248 		if (ttychars[TS_IO][rst] != vdisable &&
249 		    ttychars[EX_IO][rst] != vdisable)
250 		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
251 	}
252 	tty_setchar(&extty, ttychars[EX_IO]);
253 	if (tty_setty(SHTTY, &extty) == -1) {
254 # ifdef DEBUG_TTY
255 	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
256 # endif /* DEBUG_TTY */
257 	    return(-1);
258 	}
259     }
260     else
261 	tty_setchar(&extty, ttychars[EX_IO]);
262 
263 # ifdef SIG_WINDOW
264     {
265 	sigset_t set;
266 	(void)signal(SIG_WINDOW, window_change);	/* for window systems */
267 	sigemptyset(&set);
268 	sigaddset(&set, SIG_WINDOW);
269 	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
270     }
271 # endif
272 #else /* WINNT_NATIVE */
273 # ifdef DEBUG
274     if (rst)
275 	xprintf("rst received in ed_Setup() %d\n", rst);
276 # endif
277 #endif /* WINNT_NATIVE */
278     havesetup = 1;
279     return(0);
280 }
281 
282 void
283 ed_Init(void)
284 {
285     ResetInLine(1);		/* reset the input pointers */
286     GettingInput = 0;		/* just in case */
287 #ifdef notdef
288     /* XXX This code was here before the kill ring:
289     LastKill = KillBuf;		/ * no kill buffer * /
290        If there was any reason for that other than to make sure LastKill
291        was initialized, the code below should go in here instead - but
292        it doesn't seem reasonable to lose the entire kill ring (which is
293        "self-initializing") just because you set $term or whatever, so
294        presumably this whole '#ifdef notdef' should just be taken out.  */
295 
296     {				/* no kill ring - why? */
297 	int i;
298 	for (i = 0; i < KillRingMax; i++) {
299 	    xfree(KillRing[i].buf);
300 	    KillRing[i].buf = NULL;
301 	    KillRing[i].len = 0;
302 	}
303 	YankPos = KillPos = 0;
304 	KillRingLen = 0;
305     }
306 #endif
307 
308 #ifdef DEBUG_EDIT
309     CheckMaps();		/* do a little error checking on key maps */
310 #endif
311 
312     if (ed_Setup(0) == -1)
313 	return;
314 
315     /*
316      * if we have been called before but GotTermCaps isn't set, our TERM has
317      * changed, so get new termcaps and try again
318      */
319 
320     if (!GotTermCaps)
321 	GetTermCaps();		/* does the obvious, but gets term type each
322 				 * time */
323 
324 #ifndef WINNT_NATIVE
325 # if defined(TERMIO) || defined(POSIX)
326     edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
327     edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
328 
329     edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
330     edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
331 
332     edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
333     edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
334 
335     edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
336     edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
337 
338 
339 #  if defined(IRIX3_3) && SYSVREL < 4
340     edtty.d_t.c_line = NTTYDISC;
341 #  endif /* IRIX3_3 && SYSVREL < 4 */
342 
343 # else /* GSTTY */
344 
345     if (T_Tabs) {	/* order of &= and |= is important to XTABS */
346 	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
347 	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
348     }
349     else {
350 	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
351 	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
352     }
353 
354     edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
355     edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
356 # endif /* POSIX || TERMIO */
357 
358     tty_setchar(&edtty, ttychars[ED_IO]);
359 #endif /* WINNT_NATIVE */
360 }
361 
362 /*
363  * Check and re-init the line. set the terminal into 1 char at a time mode.
364  */
365 int
366 Rawmode(void)
367 {
368     if (Tty_raw_mode)
369 	return (0);
370 
371 #ifdef WINNT_NATIVE
372     do_nt_raw_mode();
373 #else /* !WINNT_NATIVE */
374 # ifdef _IBMR2
375     tty_setdisc(SHTTY, ED_IO);
376 # endif /* _IBMR2 */
377 
378     if (tty_getty(SHTTY, &tstty) == -1) {
379 # ifdef DEBUG_TTY
380 	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
381 # endif /* DEBUG_TTY */
382 	return(-1);
383     }
384 
385     /*
386      * We always keep up with the eight bit setting and the speed of the
387      * tty. But only we only believe changes that are made to cooked mode!
388      */
389 # if defined(POSIX) || defined(TERMIO)
390     Tty_eight_bit = tty_geteightbit(&tstty);
391     T_Speed = tty_getspeed(&tstty);
392 
393 #  ifdef POSIX
394     /*
395      * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
396      * Speed was not being set up correctly under POSIX.
397      */
398     if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
399 	(void) cfsetispeed(&extty.d_t, T_Speed);
400 	(void) cfsetospeed(&extty.d_t, T_Speed);
401 	(void) cfsetispeed(&edtty.d_t, T_Speed);
402 	(void) cfsetospeed(&edtty.d_t, T_Speed);
403     }
404 #  endif /* POSIX */
405 # else /* GSTTY */
406 
407     T_Speed = tty_getspeed(&tstty);
408     Tty_eight_bit = tty_geteightbit(&tstty);
409 
410     if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
411 	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
412 	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
413     }
414 
415     if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
416 	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
417 	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
418     }
419 # endif /* POSIX || TERMIO */
420 
421     if (tty_cooked_mode(&tstty)) {
422 	/*
423 	 * re-test for some things here (like maybe the user typed
424 	 * "stty -tabs"
425 	 */
426 	if (tty_gettabs(&tstty) == 0)
427 	    T_Tabs = 0;
428 	else
429 	    T_Tabs = CanWeTab();
430 
431 # if defined(POSIX) || defined(TERMIO)
432 	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
433 	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
434 	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
435 
436 	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
437 	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
438 	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
439 
440 	extty.d_t.c_lflag = tstty.d_t.c_lflag;
441 	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
442 	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
443 
444 	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
445 	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
446 	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
447 
448 	extty.d_t.c_iflag = tstty.d_t.c_iflag;
449 	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
450 	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
451 
452 	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
453 	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
454 	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
455 
456 	extty.d_t.c_oflag = tstty.d_t.c_oflag;
457 	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
458 	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
459 
460 	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
461 	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
462 	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
463 
464 # else /* GSTTY */
465 
466 	extty.d_t.sg_flags = tstty.d_t.sg_flags;
467 
468 	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
469 	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
470 
471 	if (T_Tabs)		/* order of &= and |= is important to XTABS */
472 	    extty.d_t.sg_flags &= ~XTABS;
473 	else
474 	    extty.d_t.sg_flags |= XTABS;
475 
476 	extty.d_lb = tstty.d_lb;
477 	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
478 	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
479 
480 	edtty.d_t.sg_flags = extty.d_t.sg_flags;
481 	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
482 	    edtty.d_t.sg_flags &=
483 		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
484 	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
485 	}
486 	else {
487 	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
488 	    edtty.d_t.sg_flags |=
489 		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
490 	}
491 
492 	edtty.d_lb = tstty.d_lb;
493 	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
494 	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
495 
496 # endif /* TERMIO || POSIX */
497 
498 	{
499 	    int i;
500 
501 	    tty_getchar(&tstty, ttychars[TS_IO]);
502 	    /*
503 	     * Check if the user made any changes.
504 	     * If he did, then propagate the changes to the
505 	     * edit and execute data structures.
506 	     */
507 	    for (i = 0; i < C_NCC; i++)
508 		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
509 		    break;
510 
511 	    if (i != C_NCC || didsetty) {
512 		didsetty = 0;
513 		/*
514 		 * Propagate changes only to the unprotected chars
515 		 * that have been modified just now.
516 		 */
517 		for (i = 0; i < C_NCC; i++) {
518 		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
519 			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
520 			ttychars[ED_IO][i] = ttychars[TS_IO][i];
521 		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
522 			ttychars[ED_IO][i] = vdisable;
523 		}
524 		tty_setchar(&edtty, ttychars[ED_IO]);
525 
526 		for (i = 0; i < C_NCC; i++) {
527 		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
528 			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
529 			ttychars[EX_IO][i] = ttychars[TS_IO][i];
530 		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
531 			ttychars[EX_IO][i] = vdisable;
532 		}
533 		tty_setchar(&extty, ttychars[EX_IO]);
534 	    }
535 
536 	}
537     }
538     if (tty_setty(SHTTY, &edtty) == -1) {
539 # ifdef DEBUG_TTY
540 	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
541 # endif /* DEBUG_TTY */
542 	return(-1);
543     }
544 #endif /* WINNT_NATIVE */
545     Tty_raw_mode = 1;
546     flush();			/* flush any buffered output */
547     return (0);
548 }
549 
550 int
551 Cookedmode(void)
552 {				/* set tty in normal setup */
553 #ifdef WINNT_NATIVE
554     do_nt_cooked_mode();
555 #else
556     sigset_t set, oset;
557     int res;
558 
559 # ifdef _IBMR2
560     tty_setdisc(SHTTY, EX_IO);
561 # endif /* _IBMR2 */
562 
563     if (!Tty_raw_mode)
564 	return (0);
565 
566     /* hold this for reseting tty */
567     sigemptyset(&set);
568     sigaddset(&set, SIGINT);
569     (void)sigprocmask(SIG_BLOCK, &set, &oset);
570     cleanup_push(&oset, sigprocmask_cleanup);
571     res = tty_setty(SHTTY, &extty);
572     cleanup_until(&oset);
573     if (res == -1) {
574 # ifdef DEBUG_TTY
575 	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
576 # endif /* DEBUG_TTY */
577 	return -1;
578     }
579 #endif /* WINNT_NATIVE */
580 
581     Tty_raw_mode = 0;
582     return (0);
583 }
584 
585 void
586 ResetInLine(int macro)
587 {
588     Cursor = InputBuf;		/* reset cursor */
589     LastChar = InputBuf;
590     InputLim = &InputBuf[INBUFSIZE - 2];/*FIXBUF*/
591     Mark = InputBuf;
592     MarkIsSet = 0;
593     MetaNext = 0;
594     CurrentKeyMap = CcKeyMap;
595     AltKeyMap = 0;
596     Hist_num = 0;
597     DoingArg = 0;
598     Argument = 1;
599     LastCmd = F_UNASSIGNED;	/* previous command executed */
600     IncMatchLen = 0;
601     if (macro)
602 	MacroLvl = -1;		/* no currently active macros */
603 }
604 
605 int
606 Load_input_line(void)
607 {
608     static Char *Input_Line = NULL;
609 #ifdef SUNOS4
610     long chrs = 0;
611 #else /* !SUNOS4 */
612     /*
613      * *Everyone* else has an int, but SunOS wants long!
614      * This breaks where int != long (alpha)
615      */
616     int chrs = 0;
617 #endif /* SUNOS4 */
618 
619     if (Input_Line)
620 	xfree(Input_Line);
621     Input_Line = NULL;
622 
623     if (Tty_raw_mode)
624 	return 0;
625 
626 #if defined(FIONREAD) && !defined(OREO)
627     (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
628     if (chrs > 0) {
629         char    buf[BUFSIZE];
630 
631 	chrs = xread(SHIN, buf, min(chrs, BUFSIZE - 1));
632 	if (chrs > 0) {
633 	    buf[chrs] = '\0';
634 	    Input_Line = Strsave(str2short(buf));
635 	    PushMacro(Input_Line);
636 	}
637 #ifdef convex
638         /* need to print errno message in case file is migrated */
639         if (chrs < 0)
640             stderror(ERR_SYSTEM, progname, strerror(errno));
641 #endif
642     }
643 #endif  /* FIONREAD && !OREO */
644     return chrs > 0;
645 }
646 
647 /*
648  * Bugfix (in Swedish) by:
649  * Johan Widen
650  * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
651  * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
652  * Internet: jw@sics.se
653  *
654  * (via Hans J Albertsson (thanks))
655  */
656 void
657 QuoteModeOn(void)
658 {
659     if (MacroLvl >= 0)
660 	return;
661 
662 #ifndef WINNT_NATIVE
663     qutty = edtty;
664 
665 #if defined(TERMIO) || defined(POSIX)
666     qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
667     qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
668 
669     qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
670     qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
671 
672     qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
673     qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
674 
675     qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
676     qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
677 #else /* GSTTY */
678     qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
679     qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
680     qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
681     qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
682 
683 #endif /* TERMIO || POSIX */
684     if (tty_setty(SHTTY, &qutty) == -1) {
685 #ifdef DEBUG_TTY
686 	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
687 #endif /* DEBUG_TTY */
688 	return;
689     }
690 #endif /* !WINNT_NATIVE */
691     Tty_quote_mode = 1;
692     return;
693 }
694 
695 void
696 QuoteModeOff(void)
697 {
698     if (!Tty_quote_mode)
699 	return;
700     Tty_quote_mode = 0;
701     if (tty_setty(SHTTY, &edtty) == -1) {
702 #ifdef DEBUG_TTY
703 	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
704 #endif /* DEBUG_TTY */
705 	return;
706     }
707     return;
708 }
709