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