ed.init.c revision 83098
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
39RCSID("$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
49int     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
50int     MacroLvl = -1;		/* pointer to current macro nesting level; */
51				/* (-1 == none) */
52static int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
53static unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
54				 * pathconf(2) */
55
56int     Tty_eight_bit = -1;	/* does the tty handle eight bits */
57
58extern bool GotTermCaps;
59
60static ttydata_t extty, edtty, tstty;
61#define qutty tstty
62
63extern int insource;
64#define SHTTY (insource ? OLDSTD : SHIN)
65
66#define uc unsigned char
67static 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
98void
99check_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
137sigret_t
138/*ARGSUSED*/
139window_change(snum)
140int 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
156void
157ed_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
169int
170ed_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
302void
303ed_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 */
386int
387Rawmode()
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
572int
573Cookedmode()
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
633void
634ResetInLine(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
652static Char *Input_Line = NULL;
653int
654Load_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 */
703void
704QuoteModeOn()
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
742void
743QuoteModeOff()
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