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