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