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