159243Sobrien/*
259243Sobrien * ed.init.c: Editor initializations
359243Sobrien */
459243Sobrien/*-
559243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California.
659243Sobrien * All rights reserved.
759243Sobrien *
859243Sobrien * Redistribution and use in source and binary forms, with or without
959243Sobrien * modification, are permitted provided that the following conditions
1059243Sobrien * are met:
1159243Sobrien * 1. Redistributions of source code must retain the above copyright
1259243Sobrien *    notice, this list of conditions and the following disclaimer.
1359243Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1459243Sobrien *    notice, this list of conditions and the following disclaimer in the
1559243Sobrien *    documentation and/or other materials provided with the distribution.
16100616Smp * 3. Neither the name of the University nor the names of its contributors
1759243Sobrien *    may be used to endorse or promote products derived from this software
1859243Sobrien *    without specific prior written permission.
1959243Sobrien *
2059243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2159243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2259243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2359243Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2459243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2559243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2659243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
2759243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2859243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2959243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3059243Sobrien * SUCH DAMAGE.
3159243Sobrien */
3259243Sobrien#include "sh.h"
3359243Sobrien#include "ed.h"
3459243Sobrien#include "tc.h"
3559243Sobrien#include "ed.defns.h"
3659243Sobrien
3759243Sobrien/* ed.init.c -- init routines for the line editor */
3859243Sobrien/* #define DEBUG_TTY */
3959243Sobrien
4059243Sobrienint     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
4159243Sobrienint     MacroLvl = -1;		/* pointer to current macro nesting level; */
4259243Sobrien				/* (-1 == none) */
4359243Sobrienstatic int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
4459243Sobrienstatic unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
4559243Sobrien				 * pathconf(2) */
4659243Sobrien
4759243Sobrienint     Tty_eight_bit = -1;	/* does the tty handle eight bits */
4859243Sobrien
49145479Smpextern int GotTermCaps;
5059243Sobrien
5159243Sobrienstatic ttydata_t extty, edtty, tstty;
5259243Sobrien#define qutty tstty
5359243Sobrien
5459243Sobrien#define SHTTY (insource ? OLDSTD : SHIN)
5559243Sobrien
5659243Sobrien#define uc unsigned char
5759243Sobrienstatic unsigned char ttychars[NN_IO][C_NCC] = {
5859243Sobrien    {
5959243Sobrien	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
6059243Sobrien	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
6159243Sobrien	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
6259243Sobrien	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
6359243Sobrien	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
6459243Sobrien	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
6559243Sobrien	(uc)CTIME
6659243Sobrien    },
6759243Sobrien    {
6859243Sobrien	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
6959243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7059243Sobrien	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
7159243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7259243Sobrien	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7359243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
7459243Sobrien	0
7559243Sobrien    },
7659243Sobrien    {
7759243Sobrien	0,		 0,		  0,		   0,
7859243Sobrien	0,		 0,		  0,		   0,
7959243Sobrien	0,		 0,		  0,		   0,
8059243Sobrien	0,		 0,		  0,		   0,
8159243Sobrien	0,		 0,		  0,		   0,
8259243Sobrien	0,		 0,		  0,		   0,
8359243Sobrien	0
8459243Sobrien    }
8559243Sobrien};
8659243Sobrien
8759243Sobrien#ifdef SIG_WINDOW
8859243Sobrienvoid
89167465Smpcheck_window_size(int force)
9059243Sobrien{
9159243Sobrien    int     lins, cols;
9259243Sobrien
9359243Sobrien    /* don't want to confuse things here */
94167465Smp    pintr_disabled++;
95167465Smp    cleanup_push(&pintr_disabled, disabled_cleanup);
9659243Sobrien    /*
9759243Sobrien     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
9859243Sobrien     * partially hidden window gets a SIG_WINDOW every time the text is
9959243Sobrien     * scrolled
10059243Sobrien     */
10159243Sobrien    if (GetSize(&lins, &cols) || force) {
10259243Sobrien	if (GettingInput) {
10359243Sobrien	    ClearLines();
10459243Sobrien	    ClearDisp();
10559243Sobrien	    MoveToLine(0);
10659243Sobrien	    MoveToChar(0);
10759243Sobrien	    ChangeSize(lins, cols);
10859243Sobrien	    Refresh();
10959243Sobrien	}
11059243Sobrien	else
11159243Sobrien	    ChangeSize(lins, cols);
11259243Sobrien    }
113145479Smp    windowchg = 0;
114167465Smp    cleanup_until(&pintr_disabled);	/* can change it again */
11559243Sobrien}
11659243Sobrien
117167465Smpvoid
11859243Sobrien/*ARGSUSED*/
119167465Smpwindow_change(int snum)
12059243Sobrien{
12159415Sobrien    USE(snum);
122100616Smp    windowchg = 1;
12359243Sobrien}
12459243Sobrien
12559243Sobrien#endif /* SIG_WINDOW */
12659243Sobrien
12759243Sobrienvoid
128167465Smped_set_tty_eight_bit(void)
12959243Sobrien{
13059243Sobrien    if (tty_getty(SHTTY, &extty) == -1) {
13159243Sobrien#ifdef DEBUG_TTY
13259243Sobrien	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
13359243Sobrien#endif /* DEBUG_TTY */
13459243Sobrien	return;
13559243Sobrien    }
13659243Sobrien    Tty_eight_bit = tty_geteightbit(&extty);
13759243Sobrien}
13859243Sobrien
13959243Sobrien
14059243Sobrienint
141167465Smped_Setup(int rst)
14259243Sobrien{
14359243Sobrien    static int havesetup = 0;
14459243Sobrien    struct varent *imode;
14559243Sobrien
14659243Sobrien    if (havesetup) 	/* if we have never been called */
14759243Sobrien	return(0);
14859243Sobrien
14959243Sobrien#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
15069408Sache    !defined(WINNT_NATIVE)
15159243Sobrien    {
15259243Sobrien	long pcret;
15359243Sobrien
15459243Sobrien	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
15559243Sobrien	    vdisable = (unsigned char) _POSIX_VDISABLE;
15659243Sobrien	else
15759243Sobrien	    vdisable = (unsigned char) pcret;
15859243Sobrien	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
15959243Sobrien	    for (rst = 0; rst < C_NCC; rst++) {
16059243Sobrien		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
16159243Sobrien		    ttychars[ED_IO][rst] = vdisable;
16259243Sobrien		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
16359243Sobrien		    ttychars[EX_IO][rst] = vdisable;
16459243Sobrien	    }
16559243Sobrien    }
16669408Sache#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
16759243Sobrien    vdisable = (unsigned char) _POSIX_VDISABLE;
16869408Sache#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
16959243Sobrien
170100616Smp    if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
17159243Sobrien	if (!Strcmp(*(imode->vec), STRinsert))
17259243Sobrien	    inputmode = MODE_INSERT;
17359243Sobrien	else if (!Strcmp(*(imode->vec), STRoverwrite))
17459243Sobrien	    inputmode = MODE_REPLACE;
17559243Sobrien    }
17659243Sobrien    else
17759243Sobrien	inputmode = MODE_INSERT;
17859243Sobrien    ed_InitMaps();
17959243Sobrien    Hist_num = 0;
18059243Sobrien    Expand = 0;
18183098Smp    SetKillRing(getn(varval(STRkillring)));
18259243Sobrien
18369408Sache#ifndef WINNT_NATIVE
18459243Sobrien    if (tty_getty(SHTTY, &extty) == -1) {
18559243Sobrien# ifdef DEBUG_TTY
18659243Sobrien	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
18759243Sobrien# endif /* DEBUG_TTY */
18859243Sobrien	return(-1);
18959243Sobrien    }
19059243Sobrien
19159243Sobrien    tstty = edtty = extty;
19259243Sobrien
19359243Sobrien    T_Speed = tty_getspeed(&extty);
19459243Sobrien    T_Tabs = tty_gettabs(&extty);
19559243Sobrien    Tty_eight_bit = tty_geteightbit(&extty);
19659243Sobrien
19759243Sobrien# if defined(POSIX) || defined(TERMIO)
19859243Sobrien    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
19959243Sobrien    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
20059243Sobrien
20159243Sobrien    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
20259243Sobrien    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
20359243Sobrien
20459243Sobrien    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
20559243Sobrien    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
20659243Sobrien
20759243Sobrien    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
20859243Sobrien    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
20959243Sobrien
21059243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
21159243Sobrien    extty.d_t.c_line = NTTYDISC;
21259243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
21359243Sobrien
21459243Sobrien# else	/* GSTTY */		/* V7, Berkeley style tty */
21559243Sobrien
21659243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
21759243Sobrien	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
21859243Sobrien	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
21959243Sobrien    }
22059243Sobrien    else {
22159243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
22259243Sobrien	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
22359243Sobrien    }
22459243Sobrien
22559243Sobrien    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
22659243Sobrien    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
22759243Sobrien
22859243Sobrien# endif /* GSTTY */
22959243Sobrien    /*
23059243Sobrien     * Reset the tty chars to reasonable defaults
23159243Sobrien     * If they are disabled, then enable them.
23259243Sobrien     */
23359243Sobrien    if (rst) {
23459243Sobrien	if (tty_cooked_mode(&tstty)) {
23559243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
23659243Sobrien	    /*
23759243Sobrien	     * Don't affect CMIN and CTIME for the editor mode
23859243Sobrien	     */
23959243Sobrien	    for (rst = 0; rst < C_NCC - 2; rst++)
24059243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
24159243Sobrien		    ttychars[ED_IO][rst] != vdisable)
24259243Sobrien		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
24359243Sobrien	    for (rst = 0; rst < C_NCC; rst++)
24459243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
24559243Sobrien		    ttychars[EX_IO][rst] != vdisable)
24659243Sobrien		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
24759243Sobrien	}
24859243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
24959243Sobrien	if (tty_setty(SHTTY, &extty) == -1) {
25059243Sobrien# ifdef DEBUG_TTY
25159243Sobrien	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
25259243Sobrien# endif /* DEBUG_TTY */
25359243Sobrien	    return(-1);
25459243Sobrien	}
25559243Sobrien    }
25659243Sobrien    else
25759243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
25859243Sobrien
25959243Sobrien# ifdef SIG_WINDOW
260167465Smp    {
261167465Smp	sigset_t set;
262167465Smp	(void)signal(SIG_WINDOW, window_change);	/* for window systems */
263167465Smp	sigemptyset(&set);
264167465Smp	sigaddset(&set, SIG_WINDOW);
265167465Smp	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
266167465Smp    }
267167465Smp# endif
26869408Sache#else /* WINNT_NATIVE */
26959243Sobrien# ifdef DEBUG
27059243Sobrien    if (rst)
27159243Sobrien	xprintf("rst received in ed_Setup() %d\n", rst);
27259243Sobrien# endif
27369408Sache#endif /* WINNT_NATIVE */
27459243Sobrien    havesetup = 1;
27559243Sobrien    return(0);
27659243Sobrien}
27759243Sobrien
27859243Sobrienvoid
279167465Smped_Init(void)
28059243Sobrien{
28159243Sobrien    ResetInLine(1);		/* reset the input pointers */
28259243Sobrien    GettingInput = 0;		/* just in case */
28383098Smp#ifdef notdef
28483098Smp    /* XXX This code was here before the kill ring:
28583098Smp    LastKill = KillBuf;		/ * no kill buffer * /
28683098Smp       If there was any reason for that other than to make sure LastKill
28783098Smp       was initialized, the code below should go in here instead - but
28883098Smp       it doesn't seem reasonable to lose the entire kill ring (which is
28983098Smp       "self-initializing") just because you set $term or whatever, so
29083098Smp       presumably this whole '#ifdef notdef' should just be taken out.  */
29159243Sobrien
29283098Smp    {				/* no kill ring - why? */
29383098Smp	int i;
29483098Smp	for (i = 0; i < KillRingMax; i++) {
295167465Smp	    xfree(KillRing[i].buf);
29683098Smp	    KillRing[i].buf = NULL;
29783098Smp	    KillRing[i].len = 0;
29883098Smp	}
29983098Smp	YankPos = KillPos = 0;
30083098Smp	KillRingLen = 0;
30183098Smp    }
30283098Smp#endif
30383098Smp
30459243Sobrien#ifdef DEBUG_EDIT
30559243Sobrien    CheckMaps();		/* do a little error checking on key maps */
30659243Sobrien#endif
30759243Sobrien
30859243Sobrien    if (ed_Setup(0) == -1)
30959243Sobrien	return;
31059243Sobrien
31159243Sobrien    /*
31259243Sobrien     * if we have been called before but GotTermCaps isn't set, our TERM has
31359243Sobrien     * changed, so get new termcaps and try again
31459243Sobrien     */
31559243Sobrien
31659243Sobrien    if (!GotTermCaps)
31759243Sobrien	GetTermCaps();		/* does the obvious, but gets term type each
31859243Sobrien				 * time */
31959243Sobrien
32069408Sache#ifndef WINNT_NATIVE
32159243Sobrien# if defined(TERMIO) || defined(POSIX)
32259243Sobrien    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
32359243Sobrien    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
32459243Sobrien
32559243Sobrien    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
32659243Sobrien    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
32759243Sobrien
32859243Sobrien    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
32959243Sobrien    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
33059243Sobrien
33159243Sobrien    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
33259243Sobrien    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
33359243Sobrien
33459243Sobrien
33559243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
33659243Sobrien    edtty.d_t.c_line = NTTYDISC;
33759243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
33859243Sobrien
33959243Sobrien# else /* GSTTY */
34059243Sobrien
34159243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
34259243Sobrien	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
34359243Sobrien	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
34459243Sobrien    }
34559243Sobrien    else {
34659243Sobrien	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
34759243Sobrien	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
34859243Sobrien    }
34959243Sobrien
35059243Sobrien    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
35159243Sobrien    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
35259243Sobrien# endif /* POSIX || TERMIO */
35359243Sobrien
35459243Sobrien    tty_setchar(&edtty, ttychars[ED_IO]);
35569408Sache#endif /* WINNT_NATIVE */
35659243Sobrien}
35759243Sobrien
35859243Sobrien/*
35959243Sobrien * Check and re-init the line. set the terminal into 1 char at a time mode.
36059243Sobrien */
36159243Sobrienint
362167465SmpRawmode(void)
36359243Sobrien{
36459243Sobrien    if (Tty_raw_mode)
36559243Sobrien	return (0);
36659243Sobrien
36769408Sache#ifdef WINNT_NATIVE
36859243Sobrien    do_nt_raw_mode();
36969408Sache#else /* !WINNT_NATIVE */
37059243Sobrien# ifdef _IBMR2
37159243Sobrien    tty_setdisc(SHTTY, ED_IO);
37259243Sobrien# endif /* _IBMR2 */
37359243Sobrien
37459243Sobrien    if (tty_getty(SHTTY, &tstty) == -1) {
37559243Sobrien# ifdef DEBUG_TTY
37659243Sobrien	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
37759243Sobrien# endif /* DEBUG_TTY */
37859243Sobrien	return(-1);
37959243Sobrien    }
38059243Sobrien
38159243Sobrien    /*
38259243Sobrien     * We always keep up with the eight bit setting and the speed of the
38359243Sobrien     * tty. But only we only believe changes that are made to cooked mode!
38459243Sobrien     */
38559243Sobrien# if defined(POSIX) || defined(TERMIO)
38659243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
38759243Sobrien    T_Speed = tty_getspeed(&tstty);
38859243Sobrien
38959243Sobrien#  ifdef POSIX
39059243Sobrien    /*
39159243Sobrien     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
39259243Sobrien     * Speed was not being set up correctly under POSIX.
39359243Sobrien     */
39459243Sobrien    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
39559243Sobrien	(void) cfsetispeed(&extty.d_t, T_Speed);
39659243Sobrien	(void) cfsetospeed(&extty.d_t, T_Speed);
39759243Sobrien	(void) cfsetispeed(&edtty.d_t, T_Speed);
39859243Sobrien	(void) cfsetospeed(&edtty.d_t, T_Speed);
39959243Sobrien    }
40059243Sobrien#  endif /* POSIX */
40159243Sobrien# else /* GSTTY */
40259243Sobrien
40359243Sobrien    T_Speed = tty_getspeed(&tstty);
40459243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
40559243Sobrien
40659243Sobrien    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
40759243Sobrien	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
40859243Sobrien	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
40959243Sobrien    }
41059243Sobrien
41159243Sobrien    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
41259243Sobrien	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
41359243Sobrien	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
41459243Sobrien    }
41559243Sobrien# endif /* POSIX || TERMIO */
41659243Sobrien
41759243Sobrien    if (tty_cooked_mode(&tstty)) {
41859243Sobrien	/*
41959243Sobrien	 * re-test for some things here (like maybe the user typed
42059243Sobrien	 * "stty -tabs"
42159243Sobrien	 */
42259243Sobrien	if (tty_gettabs(&tstty) == 0)
42359243Sobrien	    T_Tabs = 0;
42459243Sobrien	else
42559243Sobrien	    T_Tabs = CanWeTab();
42659243Sobrien
42759243Sobrien# if defined(POSIX) || defined(TERMIO)
42859243Sobrien	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
42959243Sobrien	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
43059243Sobrien	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
43159243Sobrien
43259243Sobrien	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
43359243Sobrien	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
43459243Sobrien	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
43559243Sobrien
43659243Sobrien	extty.d_t.c_lflag = tstty.d_t.c_lflag;
43759243Sobrien	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
43859243Sobrien	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
43959243Sobrien
44059243Sobrien	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
44159243Sobrien	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
44259243Sobrien	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
44359243Sobrien
44459243Sobrien	extty.d_t.c_iflag = tstty.d_t.c_iflag;
44559243Sobrien	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
44659243Sobrien	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
44759243Sobrien
44859243Sobrien	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
44959243Sobrien	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
45059243Sobrien	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
45159243Sobrien
45259243Sobrien	extty.d_t.c_oflag = tstty.d_t.c_oflag;
45359243Sobrien	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
45459243Sobrien	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
45559243Sobrien
45659243Sobrien	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
45759243Sobrien	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
45859243Sobrien	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
45959243Sobrien
46059243Sobrien# else /* GSTTY */
46159243Sobrien
46259243Sobrien	extty.d_t.sg_flags = tstty.d_t.sg_flags;
46359243Sobrien
46459243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
46559243Sobrien	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
46659243Sobrien
46759243Sobrien	if (T_Tabs)		/* order of &= and |= is important to XTABS */
46859243Sobrien	    extty.d_t.sg_flags &= ~XTABS;
46959243Sobrien	else
47059243Sobrien	    extty.d_t.sg_flags |= XTABS;
47159243Sobrien
47259243Sobrien	extty.d_lb = tstty.d_lb;
47359243Sobrien	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
47459243Sobrien	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
47559243Sobrien
47659243Sobrien	edtty.d_t.sg_flags = extty.d_t.sg_flags;
47759243Sobrien	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
47859243Sobrien	    edtty.d_t.sg_flags &=
47959243Sobrien		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
48059243Sobrien	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
48159243Sobrien	}
48259243Sobrien	else {
48359243Sobrien	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
48459243Sobrien	    edtty.d_t.sg_flags |=
48559243Sobrien		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
48659243Sobrien	}
48759243Sobrien
48859243Sobrien	edtty.d_lb = tstty.d_lb;
48959243Sobrien	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
49059243Sobrien	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
49159243Sobrien
49259243Sobrien# endif /* TERMIO || POSIX */
49359243Sobrien
49459243Sobrien	{
49559243Sobrien	    int i;
49659243Sobrien
49759243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
49859243Sobrien	    /*
49959243Sobrien	     * Check if the user made any changes.
50059243Sobrien	     * If he did, then propagate the changes to the
50159243Sobrien	     * edit and execute data structures.
50259243Sobrien	     */
50359243Sobrien	    for (i = 0; i < C_NCC; i++)
50459243Sobrien		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
50559243Sobrien		    break;
50659243Sobrien
50759243Sobrien	    if (i != C_NCC || didsetty) {
50859243Sobrien		didsetty = 0;
50959243Sobrien		/*
51059243Sobrien		 * Propagate changes only to the unprotected chars
51159243Sobrien		 * that have been modified just now.
51259243Sobrien		 */
51359243Sobrien		for (i = 0; i < C_NCC; i++) {
51459243Sobrien		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
51559243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
51659243Sobrien			ttychars[ED_IO][i] = ttychars[TS_IO][i];
51759243Sobrien		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
51859243Sobrien			ttychars[ED_IO][i] = vdisable;
51959243Sobrien		}
52059243Sobrien		tty_setchar(&edtty, ttychars[ED_IO]);
52159243Sobrien
52259243Sobrien		for (i = 0; i < C_NCC; i++) {
52359243Sobrien		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
52459243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
52559243Sobrien			ttychars[EX_IO][i] = ttychars[TS_IO][i];
52659243Sobrien		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
52759243Sobrien			ttychars[EX_IO][i] = vdisable;
52859243Sobrien		}
52959243Sobrien		tty_setchar(&extty, ttychars[EX_IO]);
53059243Sobrien	    }
53159243Sobrien
53259243Sobrien	}
53359243Sobrien    }
53459243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
53559243Sobrien# ifdef DEBUG_TTY
53659243Sobrien	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
53759243Sobrien# endif /* DEBUG_TTY */
53859243Sobrien	return(-1);
53959243Sobrien    }
54069408Sache#endif /* WINNT_NATIVE */
54159243Sobrien    Tty_raw_mode = 1;
54259243Sobrien    flush();			/* flush any buffered output */
54359243Sobrien    return (0);
54459243Sobrien}
54559243Sobrien
54659243Sobrienint
547167465SmpCookedmode(void)
54859243Sobrien{				/* set tty in normal setup */
54969408Sache#ifdef WINNT_NATIVE
55059243Sobrien    do_nt_cooked_mode();
55159243Sobrien#else
552167465Smp    sigset_t set, oset;
553167465Smp    int res;
55459243Sobrien
55559243Sobrien# ifdef _IBMR2
55659243Sobrien    tty_setdisc(SHTTY, EX_IO);
55759243Sobrien# endif /* _IBMR2 */
55859243Sobrien
55959243Sobrien    if (!Tty_raw_mode)
56059243Sobrien	return (0);
56159243Sobrien
56259243Sobrien    /* hold this for reseting tty */
563167465Smp    sigemptyset(&set);
564167465Smp    sigaddset(&set, SIGINT);
565167465Smp    (void)sigprocmask(SIG_BLOCK, &set, &oset);
566167465Smp    cleanup_push(&oset, sigprocmask_cleanup);
567167465Smp    res = tty_setty(SHTTY, &extty);
568167465Smp    cleanup_until(&oset);
569167465Smp    if (res == -1) {
57059243Sobrien# ifdef DEBUG_TTY
57159243Sobrien	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
57259243Sobrien# endif /* DEBUG_TTY */
57359243Sobrien	return -1;
57459243Sobrien    }
57569408Sache#endif /* WINNT_NATIVE */
57659243Sobrien
57759243Sobrien    Tty_raw_mode = 0;
57859243Sobrien    return (0);
57959243Sobrien}
58059243Sobrien
58159243Sobrienvoid
582167465SmpResetInLine(int macro)
58359243Sobrien{
58459243Sobrien    Cursor = InputBuf;		/* reset cursor */
58559243Sobrien    LastChar = InputBuf;
586167465Smp    InputLim = &InputBuf[INBUFSIZE - 2];/*FIXBUF*/
58759243Sobrien    Mark = InputBuf;
588167465Smp    MarkIsSet = 0;
58959243Sobrien    MetaNext = 0;
59059243Sobrien    CurrentKeyMap = CcKeyMap;
59159243Sobrien    AltKeyMap = 0;
59259243Sobrien    Hist_num = 0;
59359243Sobrien    DoingArg = 0;
59459243Sobrien    Argument = 1;
59559243Sobrien    LastCmd = F_UNASSIGNED;	/* previous command executed */
596167465Smp    IncMatchLen = 0;
59759243Sobrien    if (macro)
59859243Sobrien	MacroLvl = -1;		/* no currently active macros */
59959243Sobrien}
60059243Sobrien
60159243Sobrienint
602167465SmpLoad_input_line(void)
60359243Sobrien{
604167465Smp    static Char *Input_Line = NULL;
60559243Sobrien#ifdef SUNOS4
60659243Sobrien    long chrs = 0;
60759243Sobrien#else /* !SUNOS4 */
60859243Sobrien    /*
60959243Sobrien     * *Everyone* else has an int, but SunOS wants long!
61059243Sobrien     * This breaks where int != long (alpha)
61159243Sobrien     */
61259243Sobrien    int chrs = 0;
61359243Sobrien#endif /* SUNOS4 */
61459243Sobrien
61559243Sobrien    if (Input_Line)
616167465Smp	xfree(Input_Line);
61759243Sobrien    Input_Line = NULL;
61859243Sobrien
61959243Sobrien    if (Tty_raw_mode)
62059243Sobrien	return 0;
62159243Sobrien
62259243Sobrien#if defined(FIONREAD) && !defined(OREO)
62359243Sobrien    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
62459243Sobrien    if (chrs > 0) {
625167465Smp        char    buf[BUFSIZE];
62659243Sobrien
627167465Smp	chrs = xread(SHIN, buf, min(chrs, BUFSIZE - 1));
62859243Sobrien	if (chrs > 0) {
62959243Sobrien	    buf[chrs] = '\0';
63059243Sobrien	    Input_Line = Strsave(str2short(buf));
63159243Sobrien	    PushMacro(Input_Line);
63259243Sobrien	}
63359243Sobrien#ifdef convex
63459243Sobrien        /* need to print errno message in case file is migrated */
63559243Sobrien        if (chrs < 0)
63659243Sobrien            stderror(ERR_SYSTEM, progname, strerror(errno));
63759243Sobrien#endif
63859243Sobrien    }
63959243Sobrien#endif  /* FIONREAD && !OREO */
64059243Sobrien    return chrs > 0;
64159243Sobrien}
64259243Sobrien
64359243Sobrien/*
64459243Sobrien * Bugfix (in Swedish) by:
64559243Sobrien * Johan Widen
64659243Sobrien * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
64759243Sobrien * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
64859243Sobrien * Internet: jw@sics.se
64959243Sobrien *
65059243Sobrien * (via Hans J Albertsson (thanks))
65159243Sobrien */
65259243Sobrienvoid
653167465SmpQuoteModeOn(void)
65459243Sobrien{
65559243Sobrien    if (MacroLvl >= 0)
65659243Sobrien	return;
65759243Sobrien
65869408Sache#ifndef WINNT_NATIVE
65959243Sobrien    qutty = edtty;
66059243Sobrien
66159243Sobrien#if defined(TERMIO) || defined(POSIX)
66259243Sobrien    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
66359243Sobrien    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
66459243Sobrien
66559243Sobrien    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
66659243Sobrien    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
66759243Sobrien
66859243Sobrien    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
66959243Sobrien    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
67059243Sobrien
67159243Sobrien    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
67259243Sobrien    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
67359243Sobrien#else /* GSTTY */
67459243Sobrien    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
67559243Sobrien    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
67659243Sobrien    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
67759243Sobrien    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
67859243Sobrien
67959243Sobrien#endif /* TERMIO || POSIX */
68059243Sobrien    if (tty_setty(SHTTY, &qutty) == -1) {
68159243Sobrien#ifdef DEBUG_TTY
68259243Sobrien	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
68359243Sobrien#endif /* DEBUG_TTY */
68459243Sobrien	return;
68559243Sobrien    }
68669408Sache#endif /* !WINNT_NATIVE */
68759243Sobrien    Tty_quote_mode = 1;
68859243Sobrien    return;
68959243Sobrien}
69059243Sobrien
69159243Sobrienvoid
692167465SmpQuoteModeOff(void)
69359243Sobrien{
69459243Sobrien    if (!Tty_quote_mode)
69559243Sobrien	return;
69659243Sobrien    Tty_quote_mode = 0;
69759243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
69859243Sobrien#ifdef DEBUG_TTY
69959243Sobrien	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
70059243Sobrien#endif /* DEBUG_TTY */
70159243Sobrien	return;
70259243Sobrien    }
70359243Sobrien    return;
70459243Sobrien}
705