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