ed.init.c revision 100616
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
35RCSID("$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
44int     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
45int     MacroLvl = -1;		/* pointer to current macro nesting level; */
46				/* (-1 == none) */
47static int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
48static unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
49				 * pathconf(2) */
50
51int     Tty_eight_bit = -1;	/* does the tty handle eight bits */
52
53extern bool GotTermCaps;
54
55static ttydata_t extty, edtty, tstty;
56#define qutty tstty
57
58extern int insource;
59#define SHTTY (insource ? OLDSTD : SHIN)
60
61#define uc unsigned char
62static 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
93void
94check_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
132sigret_t
133/*ARGSUSED*/
134window_change(snum)
135int 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
151void
152ed_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
164int
165ed_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
297void
298ed_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 */
381int
382Rawmode()
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
567int
568Cookedmode()
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
628void
629ResetInLine(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
647static Char *Input_Line = NULL;
648int
649Load_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 */
698void
699QuoteModeOn()
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
737void
738QuoteModeOff()
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}
751