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