ed.init.c revision 316958
1/* $Header: /p/tcsh/cvsroot/tcsh/ed.init.c,v 3.60 2006/08/24 20:56:31 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("$tcsh: ed.init.c,v 3.60 2006/08/24 20:56:31 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(int force)
94{
95    int     lins, cols;
96
97    /* don't want to confuse things here */
98    pintr_disabled++;
99    cleanup_push(&pintr_disabled, disabled_cleanup);
100    /*
101     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
102     * partially hidden window gets a SIG_WINDOW every time the text is
103     * scrolled
104     */
105    if (GetSize(&lins, &cols) || force) {
106	if (GettingInput) {
107	    ClearLines();
108	    ClearDisp();
109	    MoveToLine(0);
110	    MoveToChar(0);
111	    ChangeSize(lins, cols);
112	    Refresh();
113	}
114	else
115	    ChangeSize(lins, cols);
116    }
117    windowchg = 0;
118    cleanup_until(&pintr_disabled);	/* can change it again */
119}
120
121void
122/*ARGSUSED*/
123window_change(int snum)
124{
125    USE(snum);
126    windowchg = 1;
127}
128
129#endif /* SIG_WINDOW */
130
131void
132ed_set_tty_eight_bit(void)
133{
134    if (tty_getty(SHTTY, &extty) == -1) {
135#ifdef DEBUG_TTY
136	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
137#endif /* DEBUG_TTY */
138	return;
139    }
140    Tty_eight_bit = tty_geteightbit(&extty);
141}
142
143
144int
145ed_Setup(int rst)
146{
147    static int havesetup = 0;
148    struct varent *imode;
149
150    if (havesetup) 	/* if we have never been called */
151	return(0);
152
153#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
154    !defined(WINNT_NATIVE)
155    {
156	long pcret;
157
158	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
159	    vdisable = (unsigned char) _POSIX_VDISABLE;
160	else
161	    vdisable = (unsigned char) pcret;
162	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
163	    for (rst = 0; rst < C_NCC; rst++) {
164		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
165		    ttychars[ED_IO][rst] = vdisable;
166		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
167		    ttychars[EX_IO][rst] = vdisable;
168	    }
169    }
170#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
171    vdisable = (unsigned char) _POSIX_VDISABLE;
172#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
173
174    if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
175	if (!Strcmp(*(imode->vec), STRinsert))
176	    inputmode = MODE_INSERT;
177	else if (!Strcmp(*(imode->vec), STRoverwrite))
178	    inputmode = MODE_REPLACE;
179    }
180    else
181	inputmode = MODE_INSERT;
182    ed_InitMaps();
183    Hist_num = 0;
184    Expand = 0;
185    SetKillRing(getn(varval(STRkillring)));
186
187#ifndef WINNT_NATIVE
188    if (tty_getty(SHTTY, &extty) == -1) {
189# ifdef DEBUG_TTY
190	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
191# endif /* DEBUG_TTY */
192	return(-1);
193    }
194
195    tstty = edtty = extty;
196
197    T_Speed = tty_getspeed(&extty);
198    T_Tabs = tty_gettabs(&extty);
199    Tty_eight_bit = tty_geteightbit(&extty);
200
201# if defined(POSIX) || defined(TERMIO)
202    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
203    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
204
205    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
206    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
207
208    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
209    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
210
211    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
212    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
213
214#  if defined(IRIX3_3) && SYSVREL < 4
215    extty.d_t.c_line = NTTYDISC;
216#  endif /* IRIX3_3 && SYSVREL < 4 */
217
218# else	/* GSTTY */		/* V7, Berkeley style tty */
219
220    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
221	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
222	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
223    }
224    else {
225	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
226	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
227    }
228
229    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
230    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
231
232# endif /* GSTTY */
233    /*
234     * Reset the tty chars to reasonable defaults
235     * If they are disabled, then enable them.
236     */
237    if (rst) {
238	if (tty_cooked_mode(&tstty)) {
239	    tty_getchar(&tstty, ttychars[TS_IO]);
240	    /*
241	     * Don't affect CMIN and CTIME for the editor mode
242	     */
243	    for (rst = 0; rst < C_NCC - 2; rst++)
244		if (ttychars[TS_IO][rst] != vdisable &&
245		    ttychars[ED_IO][rst] != vdisable)
246		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
247	    for (rst = 0; rst < C_NCC; rst++)
248		if (ttychars[TS_IO][rst] != vdisable &&
249		    ttychars[EX_IO][rst] != vdisable)
250		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
251	}
252	tty_setchar(&extty, ttychars[EX_IO]);
253	if (tty_setty(SHTTY, &extty) == -1) {
254# ifdef DEBUG_TTY
255	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
256# endif /* DEBUG_TTY */
257	    return(-1);
258	}
259    }
260    else
261	tty_setchar(&extty, ttychars[EX_IO]);
262
263# ifdef SIG_WINDOW
264    {
265	sigset_t set;
266	(void)signal(SIG_WINDOW, window_change);	/* for window systems */
267	sigemptyset(&set);
268	sigaddset(&set, SIG_WINDOW);
269	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
270    }
271# endif
272#else /* WINNT_NATIVE */
273# ifdef DEBUG
274    if (rst)
275	xprintf("rst received in ed_Setup() %d\n", rst);
276# endif
277#endif /* WINNT_NATIVE */
278    havesetup = 1;
279    return(0);
280}
281
282void
283ed_Init(void)
284{
285    ResetInLine(1);		/* reset the input pointers */
286    GettingInput = 0;		/* just in case */
287#ifdef notdef
288    /* XXX This code was here before the kill ring:
289    LastKill = KillBuf;		/ * no kill buffer * /
290       If there was any reason for that other than to make sure LastKill
291       was initialized, the code below should go in here instead - but
292       it doesn't seem reasonable to lose the entire kill ring (which is
293       "self-initializing") just because you set $term or whatever, so
294       presumably this whole '#ifdef notdef' should just be taken out.  */
295
296    {				/* no kill ring - why? */
297	int i;
298	for (i = 0; i < KillRingMax; i++) {
299	    xfree(KillRing[i].buf);
300	    KillRing[i].buf = NULL;
301	    KillRing[i].len = 0;
302	}
303	YankPos = KillPos = 0;
304	KillRingLen = 0;
305    }
306#endif
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(void)
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	    int i;
500
501	    tty_getchar(&tstty, ttychars[TS_IO]);
502	    /*
503	     * Check if the user made any changes.
504	     * If he did, then propagate the changes to the
505	     * edit and execute data structures.
506	     */
507	    for (i = 0; i < C_NCC; i++)
508		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
509		    break;
510
511	    if (i != C_NCC || didsetty) {
512		didsetty = 0;
513		/*
514		 * Propagate changes only to the unprotected chars
515		 * that have been modified just now.
516		 */
517		for (i = 0; i < C_NCC; i++) {
518		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
519			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
520			ttychars[ED_IO][i] = ttychars[TS_IO][i];
521		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
522			ttychars[ED_IO][i] = vdisable;
523		}
524		tty_setchar(&edtty, ttychars[ED_IO]);
525
526		for (i = 0; i < C_NCC; i++) {
527		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
528			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
529			ttychars[EX_IO][i] = ttychars[TS_IO][i];
530		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
531			ttychars[EX_IO][i] = vdisable;
532		}
533		tty_setchar(&extty, ttychars[EX_IO]);
534	    }
535
536	}
537    }
538    if (tty_setty(SHTTY, &edtty) == -1) {
539# ifdef DEBUG_TTY
540	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
541# endif /* DEBUG_TTY */
542	return(-1);
543    }
544#endif /* WINNT_NATIVE */
545    Tty_raw_mode = 1;
546    flush();			/* flush any buffered output */
547    return (0);
548}
549
550int
551Cookedmode(void)
552{				/* set tty in normal setup */
553#ifdef WINNT_NATIVE
554    do_nt_cooked_mode();
555#else
556    sigset_t set, oset;
557    int res;
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    sigemptyset(&set);
568    sigaddset(&set, SIGINT);
569    (void)sigprocmask(SIG_BLOCK, &set, &oset);
570    cleanup_push(&oset, sigprocmask_cleanup);
571    res = tty_setty(SHTTY, &extty);
572    cleanup_until(&oset);
573    if (res == -1) {
574# ifdef DEBUG_TTY
575	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
576# endif /* DEBUG_TTY */
577	return -1;
578    }
579#endif /* WINNT_NATIVE */
580
581    Tty_raw_mode = 0;
582    return (0);
583}
584
585void
586ResetInLine(int macro)
587{
588    Cursor = InputBuf;		/* reset cursor */
589    LastChar = InputBuf;
590    InputLim = &InputBuf[INBUFSIZE - 2];/*FIXBUF*/
591    Mark = InputBuf;
592    MarkIsSet = 0;
593    MetaNext = 0;
594    CurrentKeyMap = CcKeyMap;
595    AltKeyMap = 0;
596    Hist_num = 0;
597    DoingArg = 0;
598    Argument = 1;
599    LastCmd = F_UNASSIGNED;	/* previous command executed */
600    IncMatchLen = 0;
601    if (macro)
602	MacroLvl = -1;		/* no currently active macros */
603}
604
605int
606Load_input_line(void)
607{
608    static Char *Input_Line = NULL;
609#ifdef SUNOS4
610    long chrs = 0;
611#else /* !SUNOS4 */
612    /*
613     * *Everyone* else has an int, but SunOS wants long!
614     * This breaks where int != long (alpha)
615     */
616    int chrs = 0;
617#endif /* SUNOS4 */
618
619    if (Input_Line)
620	xfree(Input_Line);
621    Input_Line = NULL;
622
623    if (Tty_raw_mode)
624	return 0;
625
626#if defined(FIONREAD) && !defined(OREO)
627    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
628    if (chrs > 0) {
629        char    buf[BUFSIZE];
630
631	chrs = xread(SHIN, buf, min(chrs, BUFSIZE - 1));
632	if (chrs > 0) {
633	    buf[chrs] = '\0';
634	    Input_Line = Strsave(str2short(buf));
635	    PushMacro(Input_Line);
636	}
637#ifdef convex
638        /* need to print errno message in case file is migrated */
639        if (chrs < 0)
640            stderror(ERR_SYSTEM, progname, strerror(errno));
641#endif
642    }
643#endif  /* FIONREAD && !OREO */
644    return chrs > 0;
645}
646
647/*
648 * Bugfix (in Swedish) by:
649 * Johan Widen
650 * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
651 * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
652 * Internet: jw@sics.se
653 *
654 * (via Hans J Albertsson (thanks))
655 */
656void
657QuoteModeOn(void)
658{
659    if (MacroLvl >= 0)
660	return;
661
662#ifndef WINNT_NATIVE
663    qutty = edtty;
664
665#if defined(TERMIO) || defined(POSIX)
666    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
667    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
668
669    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
670    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
671
672    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
673    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
674
675    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
676    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
677#else /* GSTTY */
678    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
679    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
680    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
681    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
682
683#endif /* TERMIO || POSIX */
684    if (tty_setty(SHTTY, &qutty) == -1) {
685#ifdef DEBUG_TTY
686	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
687#endif /* DEBUG_TTY */
688	return;
689    }
690#endif /* !WINNT_NATIVE */
691    Tty_quote_mode = 1;
692    return;
693}
694
695void
696QuoteModeOff(void)
697{
698    if (!Tty_quote_mode)
699	return;
700    Tty_quote_mode = 0;
701    if (tty_setty(SHTTY, &edtty) == -1) {
702#ifdef DEBUG_TTY
703	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
704#endif /* DEBUG_TTY */
705	return;
706    }
707    return;
708}
709