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