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