1/*
2 * ed.init.c: Editor initializations
3 */
4/*-
5 * Copyright (c) 1980, 1991 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32#include "sh.h"
33#include "ed.h"
34#include "tc.h"
35#include "ed.defns.h"
36
37/* ed.init.c -- init routines for the line editor */
38/* #define DEBUG_TTY */
39
40int     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
41int     MacroLvl = -1;		/* pointer to current macro nesting level; */
42				/* (-1 == none) */
43static int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
44static unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
45				 * pathconf(2) */
46
47int     Tty_eight_bit = -1;	/* does the tty handle eight bits */
48
49extern int GotTermCaps;
50
51static ttydata_t extty, edtty, tstty;
52#define qutty tstty
53
54#define SHTTY (insource ? OLDSTD : SHIN)
55
56#define uc unsigned char
57static unsigned char ttychars[NN_IO][C_NCC] = {
58    {
59	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
60	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
61	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
62	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
63	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
64	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
65	(uc)CTIME
66    },
67    {
68	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
69	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
70	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
71	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
72	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
73	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
74	0
75    },
76    {
77	0,		 0,		  0,		   0,
78	0,		 0,		  0,		   0,
79	0,		 0,		  0,		   0,
80	0,		 0,		  0,		   0,
81	0,		 0,		  0,		   0,
82	0,		 0,		  0,		   0,
83	0
84    }
85};
86
87#ifdef SIG_WINDOW
88void
89check_window_size(int force)
90{
91    int     lins, cols;
92
93    /* don't want to confuse things here */
94    pintr_disabled++;
95    cleanup_push(&pintr_disabled, disabled_cleanup);
96    /*
97     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
98     * partially hidden window gets a SIG_WINDOW every time the text is
99     * scrolled
100     */
101    if (GetSize(&lins, &cols) || force) {
102	if (GettingInput) {
103	    ClearLines();
104	    ClearDisp();
105	    MoveToLine(0);
106	    MoveToChar(0);
107	    ChangeSize(lins, cols);
108	    Refresh();
109	}
110	else
111	    ChangeSize(lins, cols);
112    }
113    windowchg = 0;
114    cleanup_until(&pintr_disabled);	/* can change it again */
115}
116
117void
118/*ARGSUSED*/
119window_change(int snum)
120{
121    USE(snum);
122    windowchg = 1;
123}
124
125#endif /* SIG_WINDOW */
126
127void
128ed_set_tty_eight_bit(void)
129{
130    if (tty_getty(SHTTY, &extty) == -1) {
131#ifdef DEBUG_TTY
132	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
133#endif /* DEBUG_TTY */
134	return;
135    }
136    Tty_eight_bit = tty_geteightbit(&extty);
137}
138
139
140int
141ed_Setup(int rst)
142{
143    static int havesetup = 0;
144    struct varent *imode;
145
146    if (havesetup) 	/* if we have never been called */
147	return(0);
148
149#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
150    !defined(WINNT_NATIVE)
151    {
152	long pcret;
153
154	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
155	    vdisable = (unsigned char) _POSIX_VDISABLE;
156	else
157	    vdisable = (unsigned char) pcret;
158	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
159	    for (rst = 0; rst < C_NCC; rst++) {
160		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
161		    ttychars[ED_IO][rst] = vdisable;
162		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
163		    ttychars[EX_IO][rst] = vdisable;
164	    }
165    }
166#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
167    vdisable = (unsigned char) _POSIX_VDISABLE;
168#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
169
170    if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
171	if (!Strcmp(*(imode->vec), STRinsert))
172	    inputmode = MODE_INSERT;
173	else if (!Strcmp(*(imode->vec), STRoverwrite))
174	    inputmode = MODE_REPLACE;
175    }
176    else
177	inputmode = MODE_INSERT;
178    ed_InitMaps();
179    Hist_num = 0;
180    Expand = 0;
181    SetKillRing(getn(varval(STRkillring)));
182
183#ifndef WINNT_NATIVE
184    if (tty_getty(SHTTY, &extty) == -1) {
185# ifdef DEBUG_TTY
186	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
187# endif /* DEBUG_TTY */
188	return(-1);
189    }
190
191    tstty = edtty = extty;
192
193    T_Speed = tty_getspeed(&extty);
194    T_Tabs = tty_gettabs(&extty);
195    Tty_eight_bit = tty_geteightbit(&extty);
196
197# if defined(POSIX) || defined(TERMIO)
198    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
199    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
200
201    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
202    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
203
204    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
205    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
206
207    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
208    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
209
210#  if defined(IRIX3_3) && SYSVREL < 4
211    extty.d_t.c_line = NTTYDISC;
212#  endif /* IRIX3_3 && SYSVREL < 4 */
213
214# else	/* GSTTY */		/* V7, Berkeley style tty */
215
216    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
217	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
218	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
219    }
220    else {
221	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
222	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
223    }
224
225    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
226    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
227
228# endif /* GSTTY */
229    /*
230     * Reset the tty chars to reasonable defaults
231     * If they are disabled, then enable them.
232     */
233    if (rst) {
234	if (tty_cooked_mode(&tstty)) {
235	    tty_getchar(&tstty, ttychars[TS_IO]);
236	    /*
237	     * Don't affect CMIN and CTIME for the editor mode
238	     */
239	    for (rst = 0; rst < C_NCC - 2; rst++)
240		if (ttychars[TS_IO][rst] != vdisable &&
241		    ttychars[ED_IO][rst] != vdisable)
242		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
243	    for (rst = 0; rst < C_NCC; rst++)
244		if (ttychars[TS_IO][rst] != vdisable &&
245		    ttychars[EX_IO][rst] != vdisable)
246		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
247	}
248	tty_setchar(&extty, ttychars[EX_IO]);
249	if (tty_setty(SHTTY, &extty) == -1) {
250# ifdef DEBUG_TTY
251	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
252# endif /* DEBUG_TTY */
253	    return(-1);
254	}
255    }
256    else
257	tty_setchar(&extty, ttychars[EX_IO]);
258
259# ifdef SIG_WINDOW
260    {
261	sigset_t set;
262	(void)signal(SIG_WINDOW, window_change);	/* for window systems */
263	sigemptyset(&set);
264	sigaddset(&set, SIG_WINDOW);
265	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
266    }
267# endif
268#else /* WINNT_NATIVE */
269# ifdef DEBUG
270    if (rst)
271	xprintf("rst received in ed_Setup() %d\n", rst);
272# endif
273#endif /* WINNT_NATIVE */
274    havesetup = 1;
275    return(0);
276}
277
278void
279ed_Init(void)
280{
281    ResetInLine(1);		/* reset the input pointers */
282    GettingInput = 0;		/* just in case */
283#ifdef notdef
284    /* XXX This code was here before the kill ring:
285    LastKill = KillBuf;		/ * no kill buffer * /
286       If there was any reason for that other than to make sure LastKill
287       was initialized, the code below should go in here instead - but
288       it doesn't seem reasonable to lose the entire kill ring (which is
289       "self-initializing") just because you set $term or whatever, so
290       presumably this whole '#ifdef notdef' should just be taken out.  */
291
292    {				/* no kill ring - why? */
293	int i;
294	for (i = 0; i < KillRingMax; i++) {
295	    xfree(KillRing[i].buf);
296	    KillRing[i].buf = NULL;
297	    KillRing[i].len = 0;
298	}
299	YankPos = KillPos = 0;
300	KillRingLen = 0;
301    }
302#endif
303
304#ifdef DEBUG_EDIT
305    CheckMaps();		/* do a little error checking on key maps */
306#endif
307
308    if (ed_Setup(0) == -1)
309	return;
310
311    /*
312     * if we have been called before but GotTermCaps isn't set, our TERM has
313     * changed, so get new termcaps and try again
314     */
315
316    if (!GotTermCaps)
317	GetTermCaps();		/* does the obvious, but gets term type each
318				 * time */
319
320#ifndef WINNT_NATIVE
321# if defined(TERMIO) || defined(POSIX)
322    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
323    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
324
325    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
326    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
327
328    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
329    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
330
331    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
332    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
333
334
335#  if defined(IRIX3_3) && SYSVREL < 4
336    edtty.d_t.c_line = NTTYDISC;
337#  endif /* IRIX3_3 && SYSVREL < 4 */
338
339# else /* GSTTY */
340
341    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
342	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
343	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
344    }
345    else {
346	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
347	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
348    }
349
350    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
351    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
352# endif /* POSIX || TERMIO */
353
354    tty_setchar(&edtty, ttychars[ED_IO]);
355#endif /* WINNT_NATIVE */
356}
357
358/*
359 * Check and re-init the line. set the terminal into 1 char at a time mode.
360 */
361int
362Rawmode(void)
363{
364    if (Tty_raw_mode)
365	return (0);
366
367#ifdef WINNT_NATIVE
368    do_nt_raw_mode();
369#else /* !WINNT_NATIVE */
370# ifdef _IBMR2
371    tty_setdisc(SHTTY, ED_IO);
372# endif /* _IBMR2 */
373
374    if (tty_getty(SHTTY, &tstty) == -1) {
375# ifdef DEBUG_TTY
376	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
377# endif /* DEBUG_TTY */
378	return(-1);
379    }
380
381    /*
382     * We always keep up with the eight bit setting and the speed of the
383     * tty. But only we only believe changes that are made to cooked mode!
384     */
385# if defined(POSIX) || defined(TERMIO)
386    Tty_eight_bit = tty_geteightbit(&tstty);
387    T_Speed = tty_getspeed(&tstty);
388
389#  ifdef POSIX
390    /*
391     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
392     * Speed was not being set up correctly under POSIX.
393     */
394    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
395	(void) cfsetispeed(&extty.d_t, T_Speed);
396	(void) cfsetospeed(&extty.d_t, T_Speed);
397	(void) cfsetispeed(&edtty.d_t, T_Speed);
398	(void) cfsetospeed(&edtty.d_t, T_Speed);
399    }
400#  endif /* POSIX */
401# else /* GSTTY */
402
403    T_Speed = tty_getspeed(&tstty);
404    Tty_eight_bit = tty_geteightbit(&tstty);
405
406    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
407	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
408	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
409    }
410
411    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
412	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
413	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
414    }
415# endif /* POSIX || TERMIO */
416
417    if (tty_cooked_mode(&tstty)) {
418	/*
419	 * re-test for some things here (like maybe the user typed
420	 * "stty -tabs"
421	 */
422	if (tty_gettabs(&tstty) == 0)
423	    T_Tabs = 0;
424	else
425	    T_Tabs = CanWeTab();
426
427# if defined(POSIX) || defined(TERMIO)
428	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
429	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
430	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
431
432	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
433	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
434	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
435
436	extty.d_t.c_lflag = tstty.d_t.c_lflag;
437	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
438	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
439
440	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
441	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
442	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
443
444	extty.d_t.c_iflag = tstty.d_t.c_iflag;
445	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
446	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
447
448	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
449	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
450	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
451
452	extty.d_t.c_oflag = tstty.d_t.c_oflag;
453	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
454	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
455
456	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
457	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
458	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
459
460# else /* GSTTY */
461
462	extty.d_t.sg_flags = tstty.d_t.sg_flags;
463
464	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
465	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
466
467	if (T_Tabs)		/* order of &= and |= is important to XTABS */
468	    extty.d_t.sg_flags &= ~XTABS;
469	else
470	    extty.d_t.sg_flags |= XTABS;
471
472	extty.d_lb = tstty.d_lb;
473	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
474	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
475
476	edtty.d_t.sg_flags = extty.d_t.sg_flags;
477	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
478	    edtty.d_t.sg_flags &=
479		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
480	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
481	}
482	else {
483	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
484	    edtty.d_t.sg_flags |=
485		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
486	}
487
488	edtty.d_lb = tstty.d_lb;
489	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
490	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
491
492# endif /* TERMIO || POSIX */
493
494	{
495	    int i;
496
497	    tty_getchar(&tstty, ttychars[TS_IO]);
498	    /*
499	     * Check if the user made any changes.
500	     * If he did, then propagate the changes to the
501	     * edit and execute data structures.
502	     */
503	    for (i = 0; i < C_NCC; i++)
504		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
505		    break;
506
507	    if (i != C_NCC || didsetty) {
508		didsetty = 0;
509		/*
510		 * Propagate changes only to the unprotected chars
511		 * that have been modified just now.
512		 */
513		for (i = 0; i < C_NCC; i++) {
514		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
515			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
516			ttychars[ED_IO][i] = ttychars[TS_IO][i];
517		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
518			ttychars[ED_IO][i] = vdisable;
519		}
520		tty_setchar(&edtty, ttychars[ED_IO]);
521
522		for (i = 0; i < C_NCC; i++) {
523		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
524			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
525			ttychars[EX_IO][i] = ttychars[TS_IO][i];
526		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
527			ttychars[EX_IO][i] = vdisable;
528		}
529		tty_setchar(&extty, ttychars[EX_IO]);
530	    }
531
532	}
533    }
534    if (tty_setty(SHTTY, &edtty) == -1) {
535# ifdef DEBUG_TTY
536	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
537# endif /* DEBUG_TTY */
538	return(-1);
539    }
540#endif /* WINNT_NATIVE */
541    Tty_raw_mode = 1;
542    flush();			/* flush any buffered output */
543    return (0);
544}
545
546int
547Cookedmode(void)
548{				/* set tty in normal setup */
549#ifdef WINNT_NATIVE
550    do_nt_cooked_mode();
551#else
552    sigset_t set, oset;
553    int res;
554
555# ifdef _IBMR2
556    tty_setdisc(SHTTY, EX_IO);
557# endif /* _IBMR2 */
558
559    if (!Tty_raw_mode)
560	return (0);
561
562    /* hold this for reseting tty */
563    sigemptyset(&set);
564    sigaddset(&set, SIGINT);
565    (void)sigprocmask(SIG_BLOCK, &set, &oset);
566    cleanup_push(&oset, sigprocmask_cleanup);
567    res = tty_setty(SHTTY, &extty);
568    cleanup_until(&oset);
569    if (res == -1) {
570# ifdef DEBUG_TTY
571	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
572# endif /* DEBUG_TTY */
573	return -1;
574    }
575#endif /* WINNT_NATIVE */
576
577    Tty_raw_mode = 0;
578    return (0);
579}
580
581void
582ResetInLine(int macro)
583{
584    Cursor = InputBuf;		/* reset cursor */
585    LastChar = InputBuf;
586    InputLim = &InputBuf[INBUFSIZE - 2];/*FIXBUF*/
587    Mark = InputBuf;
588    MarkIsSet = 0;
589    MetaNext = 0;
590    CurrentKeyMap = CcKeyMap;
591    AltKeyMap = 0;
592    Hist_num = 0;
593    DoingArg = 0;
594    Argument = 1;
595    LastCmd = F_UNASSIGNED;	/* previous command executed */
596    IncMatchLen = 0;
597    if (macro)
598	MacroLvl = -1;		/* no currently active macros */
599}
600
601int
602Load_input_line(void)
603{
604    static Char *Input_Line = NULL;
605#ifdef SUNOS4
606    long chrs = 0;
607#else /* !SUNOS4 */
608    /*
609     * *Everyone* else has an int, but SunOS wants long!
610     * This breaks where int != long (alpha)
611     */
612    int chrs = 0;
613#endif /* SUNOS4 */
614
615    if (Input_Line)
616	xfree(Input_Line);
617    Input_Line = NULL;
618
619    if (Tty_raw_mode)
620	return 0;
621
622#if defined(FIONREAD) && !defined(OREO)
623    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
624    if (chrs > 0) {
625        char    buf[BUFSIZE];
626
627	chrs = xread(SHIN, buf, min(chrs, BUFSIZE - 1));
628	if (chrs > 0) {
629	    buf[chrs] = '\0';
630	    Input_Line = Strsave(str2short(buf));
631	    PushMacro(Input_Line);
632	}
633#ifdef convex
634        /* need to print errno message in case file is migrated */
635        if (chrs < 0)
636            stderror(ERR_SYSTEM, progname, strerror(errno));
637#endif
638    }
639#endif  /* FIONREAD && !OREO */
640    return chrs > 0;
641}
642
643/*
644 * Bugfix (in Swedish) by:
645 * Johan Widen
646 * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
647 * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
648 * Internet: jw@sics.se
649 *
650 * (via Hans J Albertsson (thanks))
651 */
652void
653QuoteModeOn(void)
654{
655    if (MacroLvl >= 0)
656	return;
657
658#ifndef WINNT_NATIVE
659    qutty = edtty;
660
661#if defined(TERMIO) || defined(POSIX)
662    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
663    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
664
665    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
666    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
667
668    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
669    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
670
671    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
672    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
673#else /* GSTTY */
674    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
675    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
676    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
677    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
678
679#endif /* TERMIO || POSIX */
680    if (tty_setty(SHTTY, &qutty) == -1) {
681#ifdef DEBUG_TTY
682	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
683#endif /* DEBUG_TTY */
684	return;
685    }
686#endif /* !WINNT_NATIVE */
687    Tty_quote_mode = 1;
688    return;
689}
690
691void
692QuoteModeOff(void)
693{
694    if (!Tty_quote_mode)
695	return;
696    Tty_quote_mode = 0;
697    if (tty_setty(SHTTY, &edtty) == -1) {
698#ifdef DEBUG_TTY
699	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
700#endif /* DEBUG_TTY */
701	return;
702    }
703    return;
704}
705