ed.init.c revision 69408
169408Sache/* $Header: /src/pub/tcsh/ed.init.c,v 3.43 2000/11/11 23:03:34 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.
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
3969408SacheRCSID("$Id: ed.init.c,v 3.43 2000/11/11 23:03:34 christos 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;
21159243Sobrien
21269408Sache#ifndef WINNT_NATIVE
21359243Sobrien    if (tty_getty(SHTTY, &extty) == -1) {
21459243Sobrien# ifdef DEBUG_TTY
21559243Sobrien	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
21659243Sobrien# endif /* DEBUG_TTY */
21759243Sobrien	return(-1);
21859243Sobrien    }
21959243Sobrien
22059243Sobrien    tstty = edtty = extty;
22159243Sobrien
22259243Sobrien    T_Speed = tty_getspeed(&extty);
22359243Sobrien    T_Tabs = tty_gettabs(&extty);
22459243Sobrien    Tty_eight_bit = tty_geteightbit(&extty);
22559243Sobrien
22659243Sobrien# if defined(POSIX) || defined(TERMIO)
22759243Sobrien    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
22859243Sobrien    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
22959243Sobrien
23059243Sobrien    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
23159243Sobrien    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
23259243Sobrien
23359243Sobrien    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
23459243Sobrien    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
23559243Sobrien
23659243Sobrien    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
23759243Sobrien    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
23859243Sobrien
23959243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
24059243Sobrien    extty.d_t.c_line = NTTYDISC;
24159243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
24259243Sobrien
24359243Sobrien# else	/* GSTTY */		/* V7, Berkeley style tty */
24459243Sobrien
24559243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
24659243Sobrien	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
24759243Sobrien	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
24859243Sobrien    }
24959243Sobrien    else {
25059243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
25159243Sobrien	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
25259243Sobrien    }
25359243Sobrien
25459243Sobrien    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
25559243Sobrien    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
25659243Sobrien
25759243Sobrien# endif /* GSTTY */
25859243Sobrien    /*
25959243Sobrien     * Reset the tty chars to reasonable defaults
26059243Sobrien     * If they are disabled, then enable them.
26159243Sobrien     */
26259243Sobrien    if (rst) {
26359243Sobrien	if (tty_cooked_mode(&tstty)) {
26459243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
26559243Sobrien	    /*
26659243Sobrien	     * Don't affect CMIN and CTIME for the editor mode
26759243Sobrien	     */
26859243Sobrien	    for (rst = 0; rst < C_NCC - 2; rst++)
26959243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
27059243Sobrien		    ttychars[ED_IO][rst] != vdisable)
27159243Sobrien		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
27259243Sobrien	    for (rst = 0; rst < C_NCC; rst++)
27359243Sobrien		if (ttychars[TS_IO][rst] != vdisable &&
27459243Sobrien		    ttychars[EX_IO][rst] != vdisable)
27559243Sobrien		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
27659243Sobrien	}
27759243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
27859243Sobrien	if (tty_setty(SHTTY, &extty) == -1) {
27959243Sobrien# ifdef DEBUG_TTY
28059243Sobrien	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
28159243Sobrien# endif /* DEBUG_TTY */
28259243Sobrien	    return(-1);
28359243Sobrien	}
28459243Sobrien    }
28559243Sobrien    else
28659243Sobrien	tty_setchar(&extty, ttychars[EX_IO]);
28759243Sobrien
28859243Sobrien# ifdef SIG_WINDOW
28959243Sobrien    (void) sigset(SIG_WINDOW, window_change);	/* for window systems */
29059243Sobrien# endif
29169408Sache#else /* WINNT_NATIVE */
29259243Sobrien# ifdef DEBUG
29359243Sobrien    if (rst)
29459243Sobrien	xprintf("rst received in ed_Setup() %d\n", rst);
29559243Sobrien# endif
29669408Sache#endif /* WINNT_NATIVE */
29759243Sobrien    havesetup = 1;
29859243Sobrien    return(0);
29959243Sobrien}
30059243Sobrien
30159243Sobrienvoid
30259243Sobriened_Init()
30359243Sobrien{
30459243Sobrien    ResetInLine(1);		/* reset the input pointers */
30559243Sobrien    GettingInput = 0;		/* just in case */
30659243Sobrien    LastKill = KillBuf;		/* no kill buffer */
30759243Sobrien
30859243Sobrien#ifdef DEBUG_EDIT
30959243Sobrien    CheckMaps();		/* do a little error checking on key maps */
31059243Sobrien#endif
31159243Sobrien
31259243Sobrien    if (ed_Setup(0) == -1)
31359243Sobrien	return;
31459243Sobrien
31559243Sobrien    /*
31659243Sobrien     * if we have been called before but GotTermCaps isn't set, our TERM has
31759243Sobrien     * changed, so get new termcaps and try again
31859243Sobrien     */
31959243Sobrien
32059243Sobrien    if (!GotTermCaps)
32159243Sobrien	GetTermCaps();		/* does the obvious, but gets term type each
32259243Sobrien				 * time */
32359243Sobrien
32469408Sache#ifndef WINNT_NATIVE
32559243Sobrien# if defined(TERMIO) || defined(POSIX)
32659243Sobrien    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
32759243Sobrien    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
32859243Sobrien
32959243Sobrien    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
33059243Sobrien    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
33159243Sobrien
33259243Sobrien    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
33359243Sobrien    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
33459243Sobrien
33559243Sobrien    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
33659243Sobrien    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
33759243Sobrien
33859243Sobrien
33959243Sobrien#  if defined(IRIX3_3) && SYSVREL < 4
34059243Sobrien    edtty.d_t.c_line = NTTYDISC;
34159243Sobrien#  endif /* IRIX3_3 && SYSVREL < 4 */
34259243Sobrien
34359243Sobrien# else /* GSTTY */
34459243Sobrien
34559243Sobrien    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
34659243Sobrien	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
34759243Sobrien	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
34859243Sobrien    }
34959243Sobrien    else {
35059243Sobrien	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
35159243Sobrien	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
35259243Sobrien    }
35359243Sobrien
35459243Sobrien    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
35559243Sobrien    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
35659243Sobrien# endif /* POSIX || TERMIO */
35759243Sobrien
35859243Sobrien    tty_setchar(&edtty, ttychars[ED_IO]);
35969408Sache#endif /* WINNT_NATIVE */
36059243Sobrien}
36159243Sobrien
36259243Sobrien/*
36359243Sobrien * Check and re-init the line. set the terminal into 1 char at a time mode.
36459243Sobrien */
36559243Sobrienint
36659243SobrienRawmode()
36759243Sobrien{
36859243Sobrien    if (Tty_raw_mode)
36959243Sobrien	return (0);
37059243Sobrien
37169408Sache#ifdef WINNT_NATIVE
37259243Sobrien    do_nt_raw_mode();
37369408Sache#else /* !WINNT_NATIVE */
37459243Sobrien# ifdef _IBMR2
37559243Sobrien    tty_setdisc(SHTTY, ED_IO);
37659243Sobrien# endif /* _IBMR2 */
37759243Sobrien
37859243Sobrien    if (tty_getty(SHTTY, &tstty) == -1) {
37959243Sobrien# ifdef DEBUG_TTY
38059243Sobrien	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
38159243Sobrien# endif /* DEBUG_TTY */
38259243Sobrien	return(-1);
38359243Sobrien    }
38459243Sobrien
38559243Sobrien    /*
38659243Sobrien     * We always keep up with the eight bit setting and the speed of the
38759243Sobrien     * tty. But only we only believe changes that are made to cooked mode!
38859243Sobrien     */
38959243Sobrien# if defined(POSIX) || defined(TERMIO)
39059243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
39159243Sobrien    T_Speed = tty_getspeed(&tstty);
39259243Sobrien
39359243Sobrien#  ifdef POSIX
39459243Sobrien    /*
39559243Sobrien     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
39659243Sobrien     * Speed was not being set up correctly under POSIX.
39759243Sobrien     */
39859243Sobrien    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
39959243Sobrien	(void) cfsetispeed(&extty.d_t, T_Speed);
40059243Sobrien	(void) cfsetospeed(&extty.d_t, T_Speed);
40159243Sobrien	(void) cfsetispeed(&edtty.d_t, T_Speed);
40259243Sobrien	(void) cfsetospeed(&edtty.d_t, T_Speed);
40359243Sobrien    }
40459243Sobrien#  endif /* POSIX */
40559243Sobrien# else /* GSTTY */
40659243Sobrien
40759243Sobrien    T_Speed = tty_getspeed(&tstty);
40859243Sobrien    Tty_eight_bit = tty_geteightbit(&tstty);
40959243Sobrien
41059243Sobrien    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
41159243Sobrien	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
41259243Sobrien	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
41359243Sobrien    }
41459243Sobrien
41559243Sobrien    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
41659243Sobrien	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
41759243Sobrien	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
41859243Sobrien    }
41959243Sobrien# endif /* POSIX || TERMIO */
42059243Sobrien
42159243Sobrien    if (tty_cooked_mode(&tstty)) {
42259243Sobrien	/*
42359243Sobrien	 * re-test for some things here (like maybe the user typed
42459243Sobrien	 * "stty -tabs"
42559243Sobrien	 */
42659243Sobrien	if (tty_gettabs(&tstty) == 0)
42759243Sobrien	    T_Tabs = 0;
42859243Sobrien	else
42959243Sobrien	    T_Tabs = CanWeTab();
43059243Sobrien
43159243Sobrien# if defined(POSIX) || defined(TERMIO)
43259243Sobrien	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
43359243Sobrien	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
43459243Sobrien	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
43559243Sobrien
43659243Sobrien	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
43759243Sobrien	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
43859243Sobrien	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
43959243Sobrien
44059243Sobrien	extty.d_t.c_lflag = tstty.d_t.c_lflag;
44159243Sobrien	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
44259243Sobrien	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
44359243Sobrien
44459243Sobrien	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
44559243Sobrien	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
44659243Sobrien	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
44759243Sobrien
44859243Sobrien	extty.d_t.c_iflag = tstty.d_t.c_iflag;
44959243Sobrien	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
45059243Sobrien	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
45159243Sobrien
45259243Sobrien	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
45359243Sobrien	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
45459243Sobrien	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
45559243Sobrien
45659243Sobrien	extty.d_t.c_oflag = tstty.d_t.c_oflag;
45759243Sobrien	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
45859243Sobrien	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
45959243Sobrien
46059243Sobrien	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
46159243Sobrien	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
46259243Sobrien	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
46359243Sobrien
46459243Sobrien# else /* GSTTY */
46559243Sobrien
46659243Sobrien	extty.d_t.sg_flags = tstty.d_t.sg_flags;
46759243Sobrien
46859243Sobrien	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
46959243Sobrien	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
47059243Sobrien
47159243Sobrien	if (T_Tabs)		/* order of &= and |= is important to XTABS */
47259243Sobrien	    extty.d_t.sg_flags &= ~XTABS;
47359243Sobrien	else
47459243Sobrien	    extty.d_t.sg_flags |= XTABS;
47559243Sobrien
47659243Sobrien	extty.d_lb = tstty.d_lb;
47759243Sobrien	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
47859243Sobrien	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
47959243Sobrien
48059243Sobrien	edtty.d_t.sg_flags = extty.d_t.sg_flags;
48159243Sobrien	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
48259243Sobrien	    edtty.d_t.sg_flags &=
48359243Sobrien		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
48459243Sobrien	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
48559243Sobrien	}
48659243Sobrien	else {
48759243Sobrien	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
48859243Sobrien	    edtty.d_t.sg_flags |=
48959243Sobrien		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
49059243Sobrien	}
49159243Sobrien
49259243Sobrien	edtty.d_lb = tstty.d_lb;
49359243Sobrien	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
49459243Sobrien	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
49559243Sobrien
49659243Sobrien# endif /* TERMIO || POSIX */
49759243Sobrien
49859243Sobrien	{
49959243Sobrien	    extern int didsetty;
50059243Sobrien	    int i;
50159243Sobrien
50259243Sobrien	    tty_getchar(&tstty, ttychars[TS_IO]);
50359243Sobrien	    /*
50459243Sobrien	     * Check if the user made any changes.
50559243Sobrien	     * If he did, then propagate the changes to the
50659243Sobrien	     * edit and execute data structures.
50759243Sobrien	     */
50859243Sobrien	    for (i = 0; i < C_NCC; i++)
50959243Sobrien		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
51059243Sobrien		    break;
51159243Sobrien
51259243Sobrien	    if (i != C_NCC || didsetty) {
51359243Sobrien		didsetty = 0;
51459243Sobrien		/*
51559243Sobrien		 * Propagate changes only to the unprotected chars
51659243Sobrien		 * that have been modified just now.
51759243Sobrien		 */
51859243Sobrien		for (i = 0; i < C_NCC; i++) {
51959243Sobrien		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
52059243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
52159243Sobrien			ttychars[ED_IO][i] = ttychars[TS_IO][i];
52259243Sobrien		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
52359243Sobrien			ttychars[ED_IO][i] = vdisable;
52459243Sobrien		}
52559243Sobrien		tty_setchar(&edtty, ttychars[ED_IO]);
52659243Sobrien
52759243Sobrien		for (i = 0; i < C_NCC; i++) {
52859243Sobrien		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
52959243Sobrien			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
53059243Sobrien			ttychars[EX_IO][i] = ttychars[TS_IO][i];
53159243Sobrien		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
53259243Sobrien			ttychars[EX_IO][i] = vdisable;
53359243Sobrien		}
53459243Sobrien		tty_setchar(&extty, ttychars[EX_IO]);
53559243Sobrien	    }
53659243Sobrien
53759243Sobrien	}
53859243Sobrien    }
53959243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
54059243Sobrien# ifdef DEBUG_TTY
54159243Sobrien	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
54259243Sobrien# endif /* DEBUG_TTY */
54359243Sobrien	return(-1);
54459243Sobrien    }
54569408Sache#endif /* WINNT_NATIVE */
54659243Sobrien    Tty_raw_mode = 1;
54759243Sobrien    flush();			/* flush any buffered output */
54859243Sobrien    return (0);
54959243Sobrien}
55059243Sobrien
55159243Sobrienint
55259243SobrienCookedmode()
55359243Sobrien{				/* set tty in normal setup */
55469408Sache#ifdef WINNT_NATIVE
55559243Sobrien    do_nt_cooked_mode();
55659243Sobrien#else
55759243Sobrien    signalfun_t orig_intr;
55859243Sobrien
55959243Sobrien# ifdef _IBMR2
56059243Sobrien    tty_setdisc(SHTTY, EX_IO);
56159243Sobrien# endif /* _IBMR2 */
56259243Sobrien
56359243Sobrien    if (!Tty_raw_mode)
56459243Sobrien	return (0);
56559243Sobrien
56659243Sobrien    /* hold this for reseting tty */
56759243Sobrien# ifdef BSDSIGS
56859243Sobrien    orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
56959243Sobrien# else
57059243Sobrien#  ifdef SIG_HOLD
57159243Sobrien    /*
57259243Sobrien     * sigset doesn't return the previous handler if the signal is held,
57359243Sobrien     * it will return SIG_HOLD instead. So instead of restoring the
57459243Sobrien     * the signal we would end up installing a blocked SIGINT with a
57559243Sobrien     * SIG_IGN signal handler. This is what happened when Cookedmode
57659243Sobrien     * was called from sched_run, disabling interrupt for the rest
57759243Sobrien     * of your session.
57859243Sobrien     *
57959243Sobrien     * This is what we do:
58059243Sobrien     * - if the signal is blocked, keep it that way
58159243Sobrien     * - else set it to SIG_IGN
58259243Sobrien     *
58359243Sobrien     * Casper Dik (casper@fwi.uva.nl)
58459243Sobrien     */
58559243Sobrien    orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
58659243Sobrien    if (orig_intr != SIG_HOLD)
58759243Sobrien	(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
58859243Sobrien#  else /* !SIG_HOLD */
58959243Sobrien    /*
59059243Sobrien     * No SIG_HOLD; probably no reliable signals as well.
59159243Sobrien     */
59259243Sobrien    orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
59359243Sobrien#  endif /* SIG_HOLD */
59459243Sobrien# endif /* BSDSIGS */
59559243Sobrien    if (tty_setty(SHTTY, &extty) == -1) {
59659243Sobrien# ifdef DEBUG_TTY
59759243Sobrien	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
59859243Sobrien# endif /* DEBUG_TTY */
59959243Sobrien	return -1;
60059243Sobrien    }
60159243Sobrien# ifdef BSDSIGS
60259243Sobrien    (void) signal(SIGINT, orig_intr);	/* take these again */
60359243Sobrien# else
60459243Sobrien    (void) sigset(SIGINT, orig_intr);	/* take these again */
60559243Sobrien# endif /* BSDSIGS */
60669408Sache#endif /* WINNT_NATIVE */
60759243Sobrien
60859243Sobrien    Tty_raw_mode = 0;
60959243Sobrien    return (0);
61059243Sobrien}
61159243Sobrien
61259243Sobrienvoid
61359243SobrienResetInLine(macro)
61459243Sobrien    int macro;
61559243Sobrien{
61659243Sobrien    Cursor = InputBuf;		/* reset cursor */
61759243Sobrien    LastChar = InputBuf;
61859243Sobrien    InputLim = &InputBuf[INBUFSIZE - 2];
61959243Sobrien    Mark = InputBuf;
62059243Sobrien    MetaNext = 0;
62159243Sobrien    CurrentKeyMap = CcKeyMap;
62259243Sobrien    AltKeyMap = 0;
62359243Sobrien    Hist_num = 0;
62459243Sobrien    DoingArg = 0;
62559243Sobrien    Argument = 1;
62659243Sobrien#ifdef notdef
62759243Sobrien    LastKill = KillBuf;		/* no kill buffer */
62859243Sobrien#endif
62959243Sobrien    LastCmd = F_UNASSIGNED;	/* previous command executed */
63059243Sobrien    if (macro)
63159243Sobrien	MacroLvl = -1;		/* no currently active macros */
63259243Sobrien}
63359243Sobrien
63459243Sobrienstatic Char *Input_Line = NULL;
63559243Sobrienint
63659243SobrienLoad_input_line()
63759243Sobrien{
63859243Sobrien#ifdef SUNOS4
63959243Sobrien    long chrs = 0;
64059243Sobrien#else /* !SUNOS4 */
64159243Sobrien    /*
64259243Sobrien     * *Everyone* else has an int, but SunOS wants long!
64359243Sobrien     * This breaks where int != long (alpha)
64459243Sobrien     */
64559243Sobrien    int chrs = 0;
64659243Sobrien#endif /* SUNOS4 */
64759243Sobrien
64859243Sobrien    if (Input_Line)
64959243Sobrien	xfree((ptr_t) Input_Line);
65059243Sobrien    Input_Line = NULL;
65159243Sobrien
65259243Sobrien    if (Tty_raw_mode)
65359243Sobrien	return 0;
65459243Sobrien
65559243Sobrien#if defined(FIONREAD) && !defined(OREO)
65659243Sobrien    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
65759243Sobrien    if (chrs > 0) {
65859243Sobrien	char    buf[BUFSIZE];
65959243Sobrien
66059243Sobrien	chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
66159243Sobrien	if (chrs > 0) {
66259243Sobrien	    buf[chrs] = '\0';
66359243Sobrien	    Input_Line = Strsave(str2short(buf));
66459243Sobrien	    PushMacro(Input_Line);
66559243Sobrien	}
66659243Sobrien#ifdef convex
66759243Sobrien        /* need to print errno message in case file is migrated */
66859243Sobrien        if (chrs < 0)
66959243Sobrien            stderror(ERR_SYSTEM, progname, strerror(errno));
67059243Sobrien#endif
67159243Sobrien    }
67259243Sobrien#endif  /* FIONREAD && !OREO */
67359243Sobrien    return chrs > 0;
67459243Sobrien}
67559243Sobrien
67659243Sobrien/*
67759243Sobrien * Bugfix (in Swedish) by:
67859243Sobrien * Johan Widen
67959243Sobrien * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
68059243Sobrien * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
68159243Sobrien * Internet: jw@sics.se
68259243Sobrien *
68359243Sobrien * (via Hans J Albertsson (thanks))
68459243Sobrien */
68559243Sobrienvoid
68659243SobrienQuoteModeOn()
68759243Sobrien{
68859243Sobrien    if (MacroLvl >= 0)
68959243Sobrien	return;
69059243Sobrien
69169408Sache#ifndef WINNT_NATIVE
69259243Sobrien    qutty = edtty;
69359243Sobrien
69459243Sobrien#if defined(TERMIO) || defined(POSIX)
69559243Sobrien    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
69659243Sobrien    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
69759243Sobrien
69859243Sobrien    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
69959243Sobrien    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
70059243Sobrien
70159243Sobrien    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
70259243Sobrien    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
70359243Sobrien
70459243Sobrien    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
70559243Sobrien    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
70659243Sobrien#else /* GSTTY */
70759243Sobrien    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
70859243Sobrien    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
70959243Sobrien    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
71059243Sobrien    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
71159243Sobrien
71259243Sobrien#endif /* TERMIO || POSIX */
71359243Sobrien    if (tty_setty(SHTTY, &qutty) == -1) {
71459243Sobrien#ifdef DEBUG_TTY
71559243Sobrien	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
71659243Sobrien#endif /* DEBUG_TTY */
71759243Sobrien	return;
71859243Sobrien    }
71969408Sache#endif /* !WINNT_NATIVE */
72059243Sobrien    Tty_quote_mode = 1;
72159243Sobrien    return;
72259243Sobrien}
72359243Sobrien
72459243Sobrienvoid
72559243SobrienQuoteModeOff()
72659243Sobrien{
72759243Sobrien    if (!Tty_quote_mode)
72859243Sobrien	return;
72959243Sobrien    Tty_quote_mode = 0;
73059243Sobrien    if (tty_setty(SHTTY, &edtty) == -1) {
73159243Sobrien#ifdef DEBUG_TTY
73259243Sobrien	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
73359243Sobrien#endif /* DEBUG_TTY */
73459243Sobrien	return;
73559243Sobrien    }
73659243Sobrien    return;
73759243Sobrien}
738