ed.init.c revision 100616
1100616Smp/* $Header: /src/pub/tcsh/ed.init.c,v 3.48 2002/07/06 22:28:13 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
35100616SmpRCSID("$Id: ed.init.c,v 3.48 2002/07/06 22:28:13 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
5359243Sobrienextern bool GotTermCaps;
5459243Sobrien
5559243Sobrienstatic ttydata_t extty, edtty, tstty;
5659243Sobrien#define qutty tstty
5759243Sobrien
5859243Sobrienextern int insource;
5959243Sobrien#define SHTTY (insource ? OLDSTD : SHIN)
6059243Sobrien
6159243Sobrien#define uc unsigned char
6259243Sobrienstatic unsigned char ttychars[NN_IO][C_NCC] = {
6359243Sobrien    {
6459243Sobrien	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
6559243Sobrien	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
6659243Sobrien	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
6759243Sobrien	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
6859243Sobrien	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
6959243Sobrien	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
7059243Sobrien	(uc)CTIME
7159243Sobrien    },
7259243Sobrien    {
7359243Sobrien	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
7459243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7559243Sobrien	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
7659243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7759243Sobrien	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7859243Sobrien	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
7959243Sobrien	0
8059243Sobrien    },
8159243Sobrien    {
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,		 0,		  0,		   0,
8859243Sobrien	0
8959243Sobrien    }
9059243Sobrien};
9159243Sobrien
9259243Sobrien#ifdef SIG_WINDOW
9359243Sobrienvoid
9459243Sobriencheck_window_size(force)
9559243Sobrien    int     force;
9659243Sobrien{
9759243Sobrien#ifdef BSDSIGS
9859243Sobrien    sigmask_t omask;
9959243Sobrien#endif /* BSDSIGS */
10059243Sobrien    int     lins, cols;
10159243Sobrien
10259243Sobrien    /* don't want to confuse things here */
10359243Sobrien#ifdef BSDSIGS
10459243Sobrien    omask = sigblock(sigmask(SIG_WINDOW)) & ~sigmask(SIG_WINDOW);
10559243Sobrien#else /* BSDSIGS */
10659243Sobrien    (void) sighold(SIG_WINDOW);
10759243Sobrien#endif /* BSDSIGS */
10859243Sobrien    /*
10959243Sobrien     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
11059243Sobrien     * partially hidden window gets a SIG_WINDOW every time the text is
11159243Sobrien     * scrolled
11259243Sobrien     */
11359243Sobrien    if (GetSize(&lins, &cols) || force) {
11459243Sobrien	if (GettingInput) {
11559243Sobrien	    ClearLines();
11659243Sobrien	    ClearDisp();
11759243Sobrien	    MoveToLine(0);
11859243Sobrien	    MoveToChar(0);
11959243Sobrien	    ChangeSize(lins, cols);
12059243Sobrien	    Refresh();
12159243Sobrien	}
12259243Sobrien	else
12359243Sobrien	    ChangeSize(lins, cols);
12459243Sobrien    }
12559243Sobrien#ifdef BSDSIGS
12659243Sobrien    (void) sigsetmask(omask);	/* can change it again */
12759243Sobrien#else				/* BSDSIGS */
12859243Sobrien    (void) sigrelse(SIG_WINDOW);
12959243Sobrien#endif /* BSDSIGS */
13059243Sobrien}
13159243Sobrien
13259243Sobriensigret_t
13359243Sobrien/*ARGSUSED*/
13459243Sobrienwindow_change(snum)
13559243Sobrienint snum;
13659243Sobrien{
13759415Sobrien    USE(snum);
13859243Sobrien#ifdef UNRELSIGS
13959243Sobrien    /* If we were called as a signal handler, restore it. */
14059243Sobrien    if (snum > 0)
14159243Sobrien      sigset(snum, window_change);
14259243Sobrien#endif /* UNRELSIGS */
143100616Smp    windowchg = 1;
14459243Sobrien#ifndef SIGVOID
14559243Sobrien    return (snum);
14659243Sobrien#endif
14759243Sobrien}
14859243Sobrien
14959243Sobrien#endif /* SIG_WINDOW */
15059243Sobrien
15159243Sobrienvoid
15259243Sobriened_set_tty_eight_bit()
15359243Sobrien{
15459243Sobrien    if (tty_getty(SHTTY, &extty) == -1) {
15559243Sobrien#ifdef DEBUG_TTY
15659243Sobrien	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
15759243Sobrien#endif /* DEBUG_TTY */
15859243Sobrien	return;
15959243Sobrien    }
16059243Sobrien    Tty_eight_bit = tty_geteightbit(&extty);
16159243Sobrien}
16259243Sobrien
16359243Sobrien
16459243Sobrienint
16559243Sobriened_Setup(rst)
16659243Sobrien    int rst;
16759243Sobrien{
16859243Sobrien    static int havesetup = 0;
16959243Sobrien    struct varent *imode;
17059243Sobrien
17159243Sobrien    if (havesetup) 	/* if we have never been called */
17259243Sobrien	return(0);
17359243Sobrien
17459243Sobrien#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
17569408Sache    !defined(WINNT_NATIVE)
17659243Sobrien    {
17759243Sobrien	long pcret;
17859243Sobrien
17959243Sobrien	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
18059243Sobrien	    vdisable = (unsigned char) _POSIX_VDISABLE;
18159243Sobrien	else
18259243Sobrien	    vdisable = (unsigned char) pcret;
18359243Sobrien	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
18459243Sobrien	    for (rst = 0; rst < C_NCC; rst++) {
18559243Sobrien		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
18659243Sobrien		    ttychars[ED_IO][rst] = vdisable;
18759243Sobrien		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
18859243Sobrien		    ttychars[EX_IO][rst] = vdisable;
18959243Sobrien	    }
19059243Sobrien    }
19169408Sache#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
19259243Sobrien    vdisable = (unsigned char) _POSIX_VDISABLE;
19369408Sache#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
19459243Sobrien
195100616Smp    if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
19659243Sobrien	if (!Strcmp(*(imode->vec), STRinsert))
19759243Sobrien	    inputmode = MODE_INSERT;
19859243Sobrien	else if (!Strcmp(*(imode->vec), STRoverwrite))
19959243Sobrien	    inputmode = MODE_REPLACE;
20059243Sobrien    }
20159243Sobrien    else
20259243Sobrien	inputmode = MODE_INSERT;
20359243Sobrien    ed_InitMaps();
20459243Sobrien    Hist_num = 0;
20559243Sobrien    Expand = 0;
20683098Smp    SetKillRing(getn(varval(STRkillring)));
20759243Sobrien
20869408Sache#ifndef WINNT_NATIVE
20959243Sobrien    if (tty_getty(SHTTY, &extty) == -1) {
21059243Sobrien# ifdef DEBUG_TTY
21159243Sobrien	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
21259243Sobrien# endif /* DEBUG_TTY */
21359243Sobrien	return(-1);
21459243Sobrien    }
21559243Sobrien
21659243Sobrien    tstty = edtty = extty;
21759243Sobrien
21859243Sobrien    T_Speed = tty_getspeed(&extty);
21959243Sobrien    T_Tabs = tty_gettabs(&extty);
22059243Sobrien    Tty_eight_bit = tty_geteightbit(&extty);
22159243Sobrien
22259243Sobrien# if defined(POSIX) || defined(TERMIO)
22359243Sobrien    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
22459243Sobrien    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
22559243Sobrien
22659243Sobrien    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
22759243Sobrien    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
22859243Sobrien
22959243Sobrien    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
23059243Sobrien    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
23159243Sobrien
23259243Sobrien    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
23359243Sobrien    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
23459243Sobrien
23559243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
23659243Sobrien    extty.d_t.c_line = NTTYDISC;
23759243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
23859243Sobrien
23959243Sobrien# else	/* GSTTY */		/* V7, Berkeley style tty */
24059243Sobrien
24159243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
24259243Sobrien	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
24359243Sobrien	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
24459243Sobrien    }
24559243Sobrien    else {
24659243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
24759243Sobrien	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
24859243Sobrien    }
24959243Sobrien
25059243Sobrien    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
25159243Sobrien    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
25259243Sobrien
25359243Sobrien# endif /* GSTTY */
25459243Sobrien    /*
25559243Sobrien     * Reset the tty chars to reasonable defaults
25659243Sobrien     * If they are disabled, then enable them.
25759243Sobrien     */
25859243Sobrien    if (rst) {
25959243Sobrien	if (tty_cooked_mode(&tstty)) {
26059243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
26159243Sobrien	    /*
26259243Sobrien	     * Don't affect CMIN and CTIME for the editor mode
26359243Sobrien	     */
26459243Sobrien	    for (rst = 0; rst < C_NCC - 2; rst++)
26559243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
26659243Sobrien		    ttychars[ED_IO][rst] != vdisable)
26759243Sobrien		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
26859243Sobrien	    for (rst = 0; rst < C_NCC; rst++)
26959243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
27059243Sobrien		    ttychars[EX_IO][rst] != vdisable)
27159243Sobrien		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
27259243Sobrien	}
27359243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
27459243Sobrien	if (tty_setty(SHTTY, &extty) == -1) {
27559243Sobrien# ifdef DEBUG_TTY
27659243Sobrien	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
27759243Sobrien# endif /* DEBUG_TTY */
27859243Sobrien	    return(-1);
27959243Sobrien	}
28059243Sobrien    }
28159243Sobrien    else
28259243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
28359243Sobrien
28459243Sobrien# ifdef SIG_WINDOW
28559243Sobrien    (void) sigset(SIG_WINDOW, window_change);	/* for window systems */
28659243Sobrien# endif
28769408Sache#else /* WINNT_NATIVE */
28859243Sobrien# ifdef DEBUG
28959243Sobrien    if (rst)
29059243Sobrien	xprintf("rst received in ed_Setup() %d\n", rst);
29159243Sobrien# endif
29269408Sache#endif /* WINNT_NATIVE */
29359243Sobrien    havesetup = 1;
29459243Sobrien    return(0);
29559243Sobrien}
29659243Sobrien
29759243Sobrienvoid
29859243Sobriened_Init()
29959243Sobrien{
30059243Sobrien    ResetInLine(1);		/* reset the input pointers */
30159243Sobrien    GettingInput = 0;		/* just in case */
30283098Smp#ifdef notdef
30383098Smp    /* XXX This code was here before the kill ring:
30483098Smp    LastKill = KillBuf;		/ * no kill buffer * /
30583098Smp       If there was any reason for that other than to make sure LastKill
30683098Smp       was initialized, the code below should go in here instead - but
30783098Smp       it doesn't seem reasonable to lose the entire kill ring (which is
30883098Smp       "self-initializing") just because you set $term or whatever, so
30983098Smp       presumably this whole '#ifdef notdef' should just be taken out.  */
31059243Sobrien
31183098Smp    {				/* no kill ring - why? */
31283098Smp	int i;
31383098Smp	for (i = 0; i < KillRingMax; i++) {
31483098Smp	    if (KillRing[i].buf != NULL)
31583098Smp		xfree((ptr_t) KillRing[i].buf);
31683098Smp	    KillRing[i].buf = NULL;
31783098Smp	    KillRing[i].len = 0;
31883098Smp	}
31983098Smp	YankPos = KillPos = 0;
32083098Smp	KillRingLen = 0;
32183098Smp    }
32283098Smp#endif
32383098Smp
32459243Sobrien#ifdef DEBUG_EDIT
32559243Sobrien    CheckMaps();		/* do a little error checking on key maps */
32659243Sobrien#endif
32759243Sobrien
32859243Sobrien    if (ed_Setup(0) == -1)
32959243Sobrien	return;
33059243Sobrien
33159243Sobrien    /*
33259243Sobrien     * if we have been called before but GotTermCaps isn't set, our TERM has
33359243Sobrien     * changed, so get new termcaps and try again
33459243Sobrien     */
33559243Sobrien
33659243Sobrien    if (!GotTermCaps)
33759243Sobrien	GetTermCaps();		/* does the obvious, but gets term type each
33859243Sobrien				 * time */
33959243Sobrien
34069408Sache#ifndef WINNT_NATIVE
34159243Sobrien# if defined(TERMIO) || defined(POSIX)
34259243Sobrien    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
34359243Sobrien    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
34459243Sobrien
34559243Sobrien    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
34659243Sobrien    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
34759243Sobrien
34859243Sobrien    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
34959243Sobrien    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
35059243Sobrien
35159243Sobrien    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
35259243Sobrien    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
35359243Sobrien
35459243Sobrien
35559243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
35659243Sobrien    edtty.d_t.c_line = NTTYDISC;
35759243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
35859243Sobrien
35959243Sobrien# else /* GSTTY */
36059243Sobrien
36159243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
36259243Sobrien	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
36359243Sobrien	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
36459243Sobrien    }
36559243Sobrien    else {
36659243Sobrien	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
36759243Sobrien	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
36859243Sobrien    }
36959243Sobrien
37059243Sobrien    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
37159243Sobrien    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
37259243Sobrien# endif /* POSIX || TERMIO */
37359243Sobrien
37459243Sobrien    tty_setchar(&edtty, ttychars[ED_IO]);
37569408Sache#endif /* WINNT_NATIVE */
37659243Sobrien}
37759243Sobrien
37859243Sobrien/*
37959243Sobrien * Check and re-init the line. set the terminal into 1 char at a time mode.
38059243Sobrien */
38159243Sobrienint
38259243SobrienRawmode()
38359243Sobrien{
38459243Sobrien    if (Tty_raw_mode)
38559243Sobrien	return (0);
38659243Sobrien
38769408Sache#ifdef WINNT_NATIVE
38859243Sobrien    do_nt_raw_mode();
38969408Sache#else /* !WINNT_NATIVE */
39059243Sobrien# ifdef _IBMR2
39159243Sobrien    tty_setdisc(SHTTY, ED_IO);
39259243Sobrien# endif /* _IBMR2 */
39359243Sobrien
39459243Sobrien    if (tty_getty(SHTTY, &tstty) == -1) {
39559243Sobrien# ifdef DEBUG_TTY
39659243Sobrien	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
39759243Sobrien# endif /* DEBUG_TTY */
39859243Sobrien	return(-1);
39959243Sobrien    }
40059243Sobrien
40159243Sobrien    /*
40259243Sobrien     * We always keep up with the eight bit setting and the speed of the
40359243Sobrien     * tty. But only we only believe changes that are made to cooked mode!
40459243Sobrien     */
40559243Sobrien# if defined(POSIX) || defined(TERMIO)
40659243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
40759243Sobrien    T_Speed = tty_getspeed(&tstty);
40859243Sobrien
40959243Sobrien#  ifdef POSIX
41059243Sobrien    /*
41159243Sobrien     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
41259243Sobrien     * Speed was not being set up correctly under POSIX.
41359243Sobrien     */
41459243Sobrien    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
41559243Sobrien	(void) cfsetispeed(&extty.d_t, T_Speed);
41659243Sobrien	(void) cfsetospeed(&extty.d_t, T_Speed);
41759243Sobrien	(void) cfsetispeed(&edtty.d_t, T_Speed);
41859243Sobrien	(void) cfsetospeed(&edtty.d_t, T_Speed);
41959243Sobrien    }
42059243Sobrien#  endif /* POSIX */
42159243Sobrien# else /* GSTTY */
42259243Sobrien
42359243Sobrien    T_Speed = tty_getspeed(&tstty);
42459243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
42559243Sobrien
42659243Sobrien    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
42759243Sobrien	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
42859243Sobrien	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
42959243Sobrien    }
43059243Sobrien
43159243Sobrien    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
43259243Sobrien	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
43359243Sobrien	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
43459243Sobrien    }
43559243Sobrien# endif /* POSIX || TERMIO */
43659243Sobrien
43759243Sobrien    if (tty_cooked_mode(&tstty)) {
43859243Sobrien	/*
43959243Sobrien	 * re-test for some things here (like maybe the user typed
44059243Sobrien	 * "stty -tabs"
44159243Sobrien	 */
44259243Sobrien	if (tty_gettabs(&tstty) == 0)
44359243Sobrien	    T_Tabs = 0;
44459243Sobrien	else
44559243Sobrien	    T_Tabs = CanWeTab();
44659243Sobrien
44759243Sobrien# if defined(POSIX) || defined(TERMIO)
44859243Sobrien	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
44959243Sobrien	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
45059243Sobrien	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
45159243Sobrien
45259243Sobrien	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
45359243Sobrien	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
45459243Sobrien	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
45559243Sobrien
45659243Sobrien	extty.d_t.c_lflag = tstty.d_t.c_lflag;
45759243Sobrien	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
45859243Sobrien	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
45959243Sobrien
46059243Sobrien	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
46159243Sobrien	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
46259243Sobrien	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
46359243Sobrien
46459243Sobrien	extty.d_t.c_iflag = tstty.d_t.c_iflag;
46559243Sobrien	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
46659243Sobrien	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
46759243Sobrien
46859243Sobrien	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
46959243Sobrien	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
47059243Sobrien	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
47159243Sobrien
47259243Sobrien	extty.d_t.c_oflag = tstty.d_t.c_oflag;
47359243Sobrien	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
47459243Sobrien	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
47559243Sobrien
47659243Sobrien	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
47759243Sobrien	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
47859243Sobrien	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
47959243Sobrien
48059243Sobrien# else /* GSTTY */
48159243Sobrien
48259243Sobrien	extty.d_t.sg_flags = tstty.d_t.sg_flags;
48359243Sobrien
48459243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
48559243Sobrien	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
48659243Sobrien
48759243Sobrien	if (T_Tabs)		/* order of &= and |= is important to XTABS */
48859243Sobrien	    extty.d_t.sg_flags &= ~XTABS;
48959243Sobrien	else
49059243Sobrien	    extty.d_t.sg_flags |= XTABS;
49159243Sobrien
49259243Sobrien	extty.d_lb = tstty.d_lb;
49359243Sobrien	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
49459243Sobrien	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
49559243Sobrien
49659243Sobrien	edtty.d_t.sg_flags = extty.d_t.sg_flags;
49759243Sobrien	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
49859243Sobrien	    edtty.d_t.sg_flags &=
49959243Sobrien		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
50059243Sobrien	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
50159243Sobrien	}
50259243Sobrien	else {
50359243Sobrien	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
50459243Sobrien	    edtty.d_t.sg_flags |=
50559243Sobrien		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
50659243Sobrien	}
50759243Sobrien
50859243Sobrien	edtty.d_lb = tstty.d_lb;
50959243Sobrien	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
51059243Sobrien	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
51159243Sobrien
51259243Sobrien# endif /* TERMIO || POSIX */
51359243Sobrien
51459243Sobrien	{
51559243Sobrien	    extern int didsetty;
51659243Sobrien	    int i;
51759243Sobrien
51859243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
51959243Sobrien	    /*
52059243Sobrien	     * Check if the user made any changes.
52159243Sobrien	     * If he did, then propagate the changes to the
52259243Sobrien	     * edit and execute data structures.
52359243Sobrien	     */
52459243Sobrien	    for (i = 0; i < C_NCC; i++)
52559243Sobrien		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
52659243Sobrien		    break;
52759243Sobrien
52859243Sobrien	    if (i != C_NCC || didsetty) {
52959243Sobrien		didsetty = 0;
53059243Sobrien		/*
53159243Sobrien		 * Propagate changes only to the unprotected chars
53259243Sobrien		 * that have been modified just now.
53359243Sobrien		 */
53459243Sobrien		for (i = 0; i < C_NCC; i++) {
53559243Sobrien		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
53659243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
53759243Sobrien			ttychars[ED_IO][i] = ttychars[TS_IO][i];
53859243Sobrien		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
53959243Sobrien			ttychars[ED_IO][i] = vdisable;
54059243Sobrien		}
54159243Sobrien		tty_setchar(&edtty, ttychars[ED_IO]);
54259243Sobrien
54359243Sobrien		for (i = 0; i < C_NCC; i++) {
54459243Sobrien		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
54559243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
54659243Sobrien			ttychars[EX_IO][i] = ttychars[TS_IO][i];
54759243Sobrien		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
54859243Sobrien			ttychars[EX_IO][i] = vdisable;
54959243Sobrien		}
55059243Sobrien		tty_setchar(&extty, ttychars[EX_IO]);
55159243Sobrien	    }
55259243Sobrien
55359243Sobrien	}
55459243Sobrien    }
55559243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
55659243Sobrien# ifdef DEBUG_TTY
55759243Sobrien	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
55859243Sobrien# endif /* DEBUG_TTY */
55959243Sobrien	return(-1);
56059243Sobrien    }
56169408Sache#endif /* WINNT_NATIVE */
56259243Sobrien    Tty_raw_mode = 1;
56359243Sobrien    flush();			/* flush any buffered output */
56459243Sobrien    return (0);
56559243Sobrien}
56659243Sobrien
56759243Sobrienint
56859243SobrienCookedmode()
56959243Sobrien{				/* set tty in normal setup */
57069408Sache#ifdef WINNT_NATIVE
57159243Sobrien    do_nt_cooked_mode();
57259243Sobrien#else
57359243Sobrien    signalfun_t orig_intr;
57459243Sobrien
57559243Sobrien# ifdef _IBMR2
57659243Sobrien    tty_setdisc(SHTTY, EX_IO);
57759243Sobrien# endif /* _IBMR2 */
57859243Sobrien
57959243Sobrien    if (!Tty_raw_mode)
58059243Sobrien	return (0);
58159243Sobrien
58259243Sobrien    /* hold this for reseting tty */
58359243Sobrien# ifdef BSDSIGS
58459243Sobrien    orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
58559243Sobrien# else
58659243Sobrien#  ifdef SIG_HOLD
58759243Sobrien    /*
58859243Sobrien     * sigset doesn't return the previous handler if the signal is held,
58959243Sobrien     * it will return SIG_HOLD instead. So instead of restoring the
59059243Sobrien     * the signal we would end up installing a blocked SIGINT with a
59159243Sobrien     * SIG_IGN signal handler. This is what happened when Cookedmode
59259243Sobrien     * was called from sched_run, disabling interrupt for the rest
59359243Sobrien     * of your session.
59459243Sobrien     *
59559243Sobrien     * This is what we do:
59659243Sobrien     * - if the signal is blocked, keep it that way
59759243Sobrien     * - else set it to SIG_IGN
59859243Sobrien     *
59959243Sobrien     * Casper Dik (casper@fwi.uva.nl)
60059243Sobrien     */
60159243Sobrien    orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
60259243Sobrien    if (orig_intr != SIG_HOLD)
60359243Sobrien	(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
60459243Sobrien#  else /* !SIG_HOLD */
60559243Sobrien    /*
60659243Sobrien     * No SIG_HOLD; probably no reliable signals as well.
60759243Sobrien     */
60859243Sobrien    orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
60959243Sobrien#  endif /* SIG_HOLD */
61059243Sobrien# endif /* BSDSIGS */
61159243Sobrien    if (tty_setty(SHTTY, &extty) == -1) {
61259243Sobrien# ifdef DEBUG_TTY
61359243Sobrien	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
61459243Sobrien# endif /* DEBUG_TTY */
61559243Sobrien	return -1;
61659243Sobrien    }
61759243Sobrien# ifdef BSDSIGS
61859243Sobrien    (void) signal(SIGINT, orig_intr);	/* take these again */
61959243Sobrien# else
62059243Sobrien    (void) sigset(SIGINT, orig_intr);	/* take these again */
62159243Sobrien# endif /* BSDSIGS */
62269408Sache#endif /* WINNT_NATIVE */
62359243Sobrien
62459243Sobrien    Tty_raw_mode = 0;
62559243Sobrien    return (0);
62659243Sobrien}
62759243Sobrien
62859243Sobrienvoid
62959243SobrienResetInLine(macro)
63059243Sobrien    int macro;
63159243Sobrien{
63259243Sobrien    Cursor = InputBuf;		/* reset cursor */
63359243Sobrien    LastChar = InputBuf;
63459243Sobrien    InputLim = &InputBuf[INBUFSIZE - 2];
63559243Sobrien    Mark = InputBuf;
63659243Sobrien    MetaNext = 0;
63759243Sobrien    CurrentKeyMap = CcKeyMap;
63859243Sobrien    AltKeyMap = 0;
63959243Sobrien    Hist_num = 0;
64059243Sobrien    DoingArg = 0;
64159243Sobrien    Argument = 1;
64259243Sobrien    LastCmd = F_UNASSIGNED;	/* previous command executed */
64359243Sobrien    if (macro)
64459243Sobrien	MacroLvl = -1;		/* no currently active macros */
64559243Sobrien}
64659243Sobrien
64759243Sobrienstatic Char *Input_Line = NULL;
64859243Sobrienint
64959243SobrienLoad_input_line()
65059243Sobrien{
65159243Sobrien#ifdef SUNOS4
65259243Sobrien    long chrs = 0;
65359243Sobrien#else /* !SUNOS4 */
65459243Sobrien    /*
65559243Sobrien     * *Everyone* else has an int, but SunOS wants long!
65659243Sobrien     * This breaks where int != long (alpha)
65759243Sobrien     */
65859243Sobrien    int chrs = 0;
65959243Sobrien#endif /* SUNOS4 */
66059243Sobrien
66159243Sobrien    if (Input_Line)
66259243Sobrien	xfree((ptr_t) Input_Line);
66359243Sobrien    Input_Line = NULL;
66459243Sobrien
66559243Sobrien    if (Tty_raw_mode)
66659243Sobrien	return 0;
66759243Sobrien
66859243Sobrien#if defined(FIONREAD) && !defined(OREO)
66959243Sobrien    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
67059243Sobrien    if (chrs > 0) {
67159243Sobrien	char    buf[BUFSIZE];
67259243Sobrien
67359243Sobrien	chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
67459243Sobrien	if (chrs > 0) {
67559243Sobrien	    buf[chrs] = '\0';
67659243Sobrien	    Input_Line = Strsave(str2short(buf));
67759243Sobrien	    PushMacro(Input_Line);
67859243Sobrien	}
67959243Sobrien#ifdef convex
68059243Sobrien        /* need to print errno message in case file is migrated */
68159243Sobrien        if (chrs < 0)
68259243Sobrien            stderror(ERR_SYSTEM, progname, strerror(errno));
68359243Sobrien#endif
68459243Sobrien    }
68559243Sobrien#endif  /* FIONREAD && !OREO */
68659243Sobrien    return chrs > 0;
68759243Sobrien}
68859243Sobrien
68959243Sobrien/*
69059243Sobrien * Bugfix (in Swedish) by:
69159243Sobrien * Johan Widen
69259243Sobrien * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
69359243Sobrien * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
69459243Sobrien * Internet: jw@sics.se
69559243Sobrien *
69659243Sobrien * (via Hans J Albertsson (thanks))
69759243Sobrien */
69859243Sobrienvoid
69959243SobrienQuoteModeOn()
70059243Sobrien{
70159243Sobrien    if (MacroLvl >= 0)
70259243Sobrien	return;
70359243Sobrien
70469408Sache#ifndef WINNT_NATIVE
70559243Sobrien    qutty = edtty;
70659243Sobrien
70759243Sobrien#if defined(TERMIO) || defined(POSIX)
70859243Sobrien    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
70959243Sobrien    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
71059243Sobrien
71159243Sobrien    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
71259243Sobrien    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
71359243Sobrien
71459243Sobrien    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
71559243Sobrien    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
71659243Sobrien
71759243Sobrien    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
71859243Sobrien    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
71959243Sobrien#else /* GSTTY */
72059243Sobrien    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
72159243Sobrien    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
72259243Sobrien    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
72359243Sobrien    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
72459243Sobrien
72559243Sobrien#endif /* TERMIO || POSIX */
72659243Sobrien    if (tty_setty(SHTTY, &qutty) == -1) {
72759243Sobrien#ifdef DEBUG_TTY
72859243Sobrien	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
72959243Sobrien#endif /* DEBUG_TTY */
73059243Sobrien	return;
73159243Sobrien    }
73269408Sache#endif /* !WINNT_NATIVE */
73359243Sobrien    Tty_quote_mode = 1;
73459243Sobrien    return;
73559243Sobrien}
73659243Sobrien
73759243Sobrienvoid
73859243SobrienQuoteModeOff()
73959243Sobrien{
74059243Sobrien    if (!Tty_quote_mode)
74159243Sobrien	return;
74259243Sobrien    Tty_quote_mode = 0;
74359243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
74459243Sobrien#ifdef DEBUG_TTY
74559243Sobrien	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
74659243Sobrien#endif /* DEBUG_TTY */
74759243Sobrien	return;
74859243Sobrien    }
74959243Sobrien    return;
75059243Sobrien}
751