ed.init.c revision 69408
1/* $Header: /src/pub/tcsh/ed.init.c,v 3.43 2000/11/11 23:03:34 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. 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.43 2000/11/11 23:03:34 christos 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
212#ifndef WINNT_NATIVE
213    if (tty_getty(SHTTY, &extty) == -1) {
214# ifdef DEBUG_TTY
215	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
216# endif /* DEBUG_TTY */
217	return(-1);
218    }
219
220    tstty = edtty = extty;
221
222    T_Speed = tty_getspeed(&extty);
223    T_Tabs = tty_gettabs(&extty);
224    Tty_eight_bit = tty_geteightbit(&extty);
225
226# if defined(POSIX) || defined(TERMIO)
227    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
228    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
229
230    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
231    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
232
233    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
234    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
235
236    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
237    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
238
239#  if defined(IRIX3_3) && SYSVREL < 4
240    extty.d_t.c_line = NTTYDISC;
241#  endif /* IRIX3_3 && SYSVREL < 4 */
242
243# else	/* GSTTY */		/* V7, Berkeley style tty */
244
245    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
246	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
247	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
248    }
249    else {
250	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
251	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
252    }
253
254    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
255    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
256
257# endif /* GSTTY */
258    /*
259     * Reset the tty chars to reasonable defaults
260     * If they are disabled, then enable them.
261     */
262    if (rst) {
263	if (tty_cooked_mode(&tstty)) {
264	    tty_getchar(&tstty, ttychars[TS_IO]);
265	    /*
266	     * Don't affect CMIN and CTIME for the editor mode
267	     */
268	    for (rst = 0; rst < C_NCC - 2; rst++)
269		if (ttychars[TS_IO][rst] != vdisable &&
270		    ttychars[ED_IO][rst] != vdisable)
271		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
272	    for (rst = 0; rst < C_NCC; rst++)
273		if (ttychars[TS_IO][rst] != vdisable &&
274		    ttychars[EX_IO][rst] != vdisable)
275		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
276	}
277	tty_setchar(&extty, ttychars[EX_IO]);
278	if (tty_setty(SHTTY, &extty) == -1) {
279# ifdef DEBUG_TTY
280	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
281# endif /* DEBUG_TTY */
282	    return(-1);
283	}
284    }
285    else
286	tty_setchar(&extty, ttychars[EX_IO]);
287
288# ifdef SIG_WINDOW
289    (void) sigset(SIG_WINDOW, window_change);	/* for window systems */
290# endif
291#else /* WINNT_NATIVE */
292# ifdef DEBUG
293    if (rst)
294	xprintf("rst received in ed_Setup() %d\n", rst);
295# endif
296#endif /* WINNT_NATIVE */
297    havesetup = 1;
298    return(0);
299}
300
301void
302ed_Init()
303{
304    ResetInLine(1);		/* reset the input pointers */
305    GettingInput = 0;		/* just in case */
306    LastKill = KillBuf;		/* no kill buffer */
307
308#ifdef DEBUG_EDIT
309    CheckMaps();		/* do a little error checking on key maps */
310#endif
311
312    if (ed_Setup(0) == -1)
313	return;
314
315    /*
316     * if we have been called before but GotTermCaps isn't set, our TERM has
317     * changed, so get new termcaps and try again
318     */
319
320    if (!GotTermCaps)
321	GetTermCaps();		/* does the obvious, but gets term type each
322				 * time */
323
324#ifndef WINNT_NATIVE
325# if defined(TERMIO) || defined(POSIX)
326    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
327    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
328
329    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
330    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
331
332    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
333    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
334
335    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
336    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
337
338
339#  if defined(IRIX3_3) && SYSVREL < 4
340    edtty.d_t.c_line = NTTYDISC;
341#  endif /* IRIX3_3 && SYSVREL < 4 */
342
343# else /* GSTTY */
344
345    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
346	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
347	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
348    }
349    else {
350	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
351	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
352    }
353
354    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
355    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
356# endif /* POSIX || TERMIO */
357
358    tty_setchar(&edtty, ttychars[ED_IO]);
359#endif /* WINNT_NATIVE */
360}
361
362/*
363 * Check and re-init the line. set the terminal into 1 char at a time mode.
364 */
365int
366Rawmode()
367{
368    if (Tty_raw_mode)
369	return (0);
370
371#ifdef WINNT_NATIVE
372    do_nt_raw_mode();
373#else /* !WINNT_NATIVE */
374# ifdef _IBMR2
375    tty_setdisc(SHTTY, ED_IO);
376# endif /* _IBMR2 */
377
378    if (tty_getty(SHTTY, &tstty) == -1) {
379# ifdef DEBUG_TTY
380	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
381# endif /* DEBUG_TTY */
382	return(-1);
383    }
384
385    /*
386     * We always keep up with the eight bit setting and the speed of the
387     * tty. But only we only believe changes that are made to cooked mode!
388     */
389# if defined(POSIX) || defined(TERMIO)
390    Tty_eight_bit = tty_geteightbit(&tstty);
391    T_Speed = tty_getspeed(&tstty);
392
393#  ifdef POSIX
394    /*
395     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
396     * Speed was not being set up correctly under POSIX.
397     */
398    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
399	(void) cfsetispeed(&extty.d_t, T_Speed);
400	(void) cfsetospeed(&extty.d_t, T_Speed);
401	(void) cfsetispeed(&edtty.d_t, T_Speed);
402	(void) cfsetospeed(&edtty.d_t, T_Speed);
403    }
404#  endif /* POSIX */
405# else /* GSTTY */
406
407    T_Speed = tty_getspeed(&tstty);
408    Tty_eight_bit = tty_geteightbit(&tstty);
409
410    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
411	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
412	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
413    }
414
415    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
416	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
417	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
418    }
419# endif /* POSIX || TERMIO */
420
421    if (tty_cooked_mode(&tstty)) {
422	/*
423	 * re-test for some things here (like maybe the user typed
424	 * "stty -tabs"
425	 */
426	if (tty_gettabs(&tstty) == 0)
427	    T_Tabs = 0;
428	else
429	    T_Tabs = CanWeTab();
430
431# if defined(POSIX) || defined(TERMIO)
432	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
433	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
434	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
435
436	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
437	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
438	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
439
440	extty.d_t.c_lflag = tstty.d_t.c_lflag;
441	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
442	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
443
444	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
445	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
446	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
447
448	extty.d_t.c_iflag = tstty.d_t.c_iflag;
449	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
450	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
451
452	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
453	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
454	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
455
456	extty.d_t.c_oflag = tstty.d_t.c_oflag;
457	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
458	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
459
460	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
461	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
462	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
463
464# else /* GSTTY */
465
466	extty.d_t.sg_flags = tstty.d_t.sg_flags;
467
468	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
469	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
470
471	if (T_Tabs)		/* order of &= and |= is important to XTABS */
472	    extty.d_t.sg_flags &= ~XTABS;
473	else
474	    extty.d_t.sg_flags |= XTABS;
475
476	extty.d_lb = tstty.d_lb;
477	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
478	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
479
480	edtty.d_t.sg_flags = extty.d_t.sg_flags;
481	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
482	    edtty.d_t.sg_flags &=
483		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
484	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
485	}
486	else {
487	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
488	    edtty.d_t.sg_flags |=
489		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
490	}
491
492	edtty.d_lb = tstty.d_lb;
493	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
494	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
495
496# endif /* TERMIO || POSIX */
497
498	{
499	    extern int didsetty;
500	    int i;
501
502	    tty_getchar(&tstty, ttychars[TS_IO]);
503	    /*
504	     * Check if the user made any changes.
505	     * If he did, then propagate the changes to the
506	     * edit and execute data structures.
507	     */
508	    for (i = 0; i < C_NCC; i++)
509		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
510		    break;
511
512	    if (i != C_NCC || didsetty) {
513		didsetty = 0;
514		/*
515		 * Propagate changes only to the unprotected chars
516		 * that have been modified just now.
517		 */
518		for (i = 0; i < C_NCC; i++) {
519		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
520			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
521			ttychars[ED_IO][i] = ttychars[TS_IO][i];
522		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
523			ttychars[ED_IO][i] = vdisable;
524		}
525		tty_setchar(&edtty, ttychars[ED_IO]);
526
527		for (i = 0; i < C_NCC; i++) {
528		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
529			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
530			ttychars[EX_IO][i] = ttychars[TS_IO][i];
531		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
532			ttychars[EX_IO][i] = vdisable;
533		}
534		tty_setchar(&extty, ttychars[EX_IO]);
535	    }
536
537	}
538    }
539    if (tty_setty(SHTTY, &edtty) == -1) {
540# ifdef DEBUG_TTY
541	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
542# endif /* DEBUG_TTY */
543	return(-1);
544    }
545#endif /* WINNT_NATIVE */
546    Tty_raw_mode = 1;
547    flush();			/* flush any buffered output */
548    return (0);
549}
550
551int
552Cookedmode()
553{				/* set tty in normal setup */
554#ifdef WINNT_NATIVE
555    do_nt_cooked_mode();
556#else
557    signalfun_t orig_intr;
558
559# ifdef _IBMR2
560    tty_setdisc(SHTTY, EX_IO);
561# endif /* _IBMR2 */
562
563    if (!Tty_raw_mode)
564	return (0);
565
566    /* hold this for reseting tty */
567# ifdef BSDSIGS
568    orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
569# else
570#  ifdef SIG_HOLD
571    /*
572     * sigset doesn't return the previous handler if the signal is held,
573     * it will return SIG_HOLD instead. So instead of restoring the
574     * the signal we would end up installing a blocked SIGINT with a
575     * SIG_IGN signal handler. This is what happened when Cookedmode
576     * was called from sched_run, disabling interrupt for the rest
577     * of your session.
578     *
579     * This is what we do:
580     * - if the signal is blocked, keep it that way
581     * - else set it to SIG_IGN
582     *
583     * Casper Dik (casper@fwi.uva.nl)
584     */
585    orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
586    if (orig_intr != SIG_HOLD)
587	(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
588#  else /* !SIG_HOLD */
589    /*
590     * No SIG_HOLD; probably no reliable signals as well.
591     */
592    orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
593#  endif /* SIG_HOLD */
594# endif /* BSDSIGS */
595    if (tty_setty(SHTTY, &extty) == -1) {
596# ifdef DEBUG_TTY
597	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
598# endif /* DEBUG_TTY */
599	return -1;
600    }
601# ifdef BSDSIGS
602    (void) signal(SIGINT, orig_intr);	/* take these again */
603# else
604    (void) sigset(SIGINT, orig_intr);	/* take these again */
605# endif /* BSDSIGS */
606#endif /* WINNT_NATIVE */
607
608    Tty_raw_mode = 0;
609    return (0);
610}
611
612void
613ResetInLine(macro)
614    int macro;
615{
616    Cursor = InputBuf;		/* reset cursor */
617    LastChar = InputBuf;
618    InputLim = &InputBuf[INBUFSIZE - 2];
619    Mark = InputBuf;
620    MetaNext = 0;
621    CurrentKeyMap = CcKeyMap;
622    AltKeyMap = 0;
623    Hist_num = 0;
624    DoingArg = 0;
625    Argument = 1;
626#ifdef notdef
627    LastKill = KillBuf;		/* no kill buffer */
628#endif
629    LastCmd = F_UNASSIGNED;	/* previous command executed */
630    if (macro)
631	MacroLvl = -1;		/* no currently active macros */
632}
633
634static Char *Input_Line = NULL;
635int
636Load_input_line()
637{
638#ifdef SUNOS4
639    long chrs = 0;
640#else /* !SUNOS4 */
641    /*
642     * *Everyone* else has an int, but SunOS wants long!
643     * This breaks where int != long (alpha)
644     */
645    int chrs = 0;
646#endif /* SUNOS4 */
647
648    if (Input_Line)
649	xfree((ptr_t) Input_Line);
650    Input_Line = NULL;
651
652    if (Tty_raw_mode)
653	return 0;
654
655#if defined(FIONREAD) && !defined(OREO)
656    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
657    if (chrs > 0) {
658	char    buf[BUFSIZE];
659
660	chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
661	if (chrs > 0) {
662	    buf[chrs] = '\0';
663	    Input_Line = Strsave(str2short(buf));
664	    PushMacro(Input_Line);
665	}
666#ifdef convex
667        /* need to print errno message in case file is migrated */
668        if (chrs < 0)
669            stderror(ERR_SYSTEM, progname, strerror(errno));
670#endif
671    }
672#endif  /* FIONREAD && !OREO */
673    return chrs > 0;
674}
675
676/*
677 * Bugfix (in Swedish) by:
678 * Johan Widen
679 * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
680 * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
681 * Internet: jw@sics.se
682 *
683 * (via Hans J Albertsson (thanks))
684 */
685void
686QuoteModeOn()
687{
688    if (MacroLvl >= 0)
689	return;
690
691#ifndef WINNT_NATIVE
692    qutty = edtty;
693
694#if defined(TERMIO) || defined(POSIX)
695    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
696    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
697
698    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
699    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
700
701    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
702    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
703
704    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
705    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
706#else /* GSTTY */
707    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
708    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
709    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
710    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
711
712#endif /* TERMIO || POSIX */
713    if (tty_setty(SHTTY, &qutty) == -1) {
714#ifdef DEBUG_TTY
715	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
716#endif /* DEBUG_TTY */
717	return;
718    }
719#endif /* !WINNT_NATIVE */
720    Tty_quote_mode = 1;
721    return;
722}
723
724void
725QuoteModeOff()
726{
727    if (!Tty_quote_mode)
728	return;
729    Tty_quote_mode = 0;
730    if (tty_setty(SHTTY, &edtty) == -1) {
731#ifdef DEBUG_TTY
732	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
733#endif /* DEBUG_TTY */
734	return;
735    }
736    return;
737}
738