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