xref: /dflybsd-src/contrib/libedit/src/tty.c (revision 698e9e6cd5f042847de67460caaa3fde98cdfe99)
1*cdf8408cSAntonio Huete Jimenez /*	$NetBSD: tty.c,v 1.70 2021/07/14 07:47:23 christos Exp $	*/
232fe07f8SJohn Marino 
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino  * Copyright (c) 1992, 1993
532fe07f8SJohn Marino  *	The Regents of the University of California.  All rights reserved.
632fe07f8SJohn Marino  *
732fe07f8SJohn Marino  * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino  * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino  *
1032fe07f8SJohn Marino  * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino  * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino  * are met:
1332fe07f8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino  *    documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino  * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino  *    may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino  *    without specific prior written permission.
2132fe07f8SJohn Marino  *
2232fe07f8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino  * SUCH DAMAGE.
3332fe07f8SJohn Marino  */
3432fe07f8SJohn Marino 
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)tty.c	8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*cdf8408cSAntonio Huete Jimenez __RCSID("$NetBSD: tty.c,v 1.70 2021/07/14 07:47:23 christos Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino 
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino  * tty.c: tty interface stuff
4632fe07f8SJohn Marino  */
4732fe07f8SJohn Marino #include <assert.h>
4832fe07f8SJohn Marino #include <errno.h>
4984b940c1SJohn Marino #include <stdlib.h>	/* for abort */
5012db70c8Szrj #include <string.h>
5112db70c8Szrj #include <strings.h>	/* for ffs */
5212db70c8Szrj #include <unistd.h>	/* for isatty */
5312db70c8Szrj 
5432fe07f8SJohn Marino #include "el.h"
5512db70c8Szrj #include "fcns.h"
5612db70c8Szrj #include "parse.h"
5732fe07f8SJohn Marino 
5832fe07f8SJohn Marino typedef struct ttymodes_t {
5932fe07f8SJohn Marino 	const char *m_name;
6032fe07f8SJohn Marino 	unsigned int m_value;
6132fe07f8SJohn Marino 	int m_type;
6232fe07f8SJohn Marino }          ttymodes_t;
6332fe07f8SJohn Marino 
6432fe07f8SJohn Marino typedef struct ttymap_t {
6512db70c8Szrj 	wint_t nch, och;	/* Internal and termio rep of chars */
6632fe07f8SJohn Marino 	el_action_t bind[3];	/* emacs, vi, and vi-cmd */
6732fe07f8SJohn Marino } ttymap_t;
6832fe07f8SJohn Marino 
6932fe07f8SJohn Marino 
7012db70c8Szrj static const ttyperm_t ttyperm = {
7132fe07f8SJohn Marino 	{
7232fe07f8SJohn Marino 		{"iflag:", ICRNL, (INLCR | IGNCR)},
7332fe07f8SJohn Marino 		{"oflag:", (OPOST | ONLCR), ONLRET},
7432fe07f8SJohn Marino 		{"cflag:", 0, 0},
7532fe07f8SJohn Marino 		{"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
7632fe07f8SJohn Marino 		(NOFLSH | ECHONL | EXTPROC | FLUSHO)},
7732fe07f8SJohn Marino 		{"chars:", 0, 0},
7832fe07f8SJohn Marino 	},
7932fe07f8SJohn Marino 	{
8032fe07f8SJohn Marino 		{"iflag:", (INLCR | ICRNL), IGNCR},
8132fe07f8SJohn Marino 		{"oflag:", (OPOST | ONLCR), ONLRET},
8232fe07f8SJohn Marino 		{"cflag:", 0, 0},
8332fe07f8SJohn Marino 		{"lflag:", ISIG,
8432fe07f8SJohn Marino 		(NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
8532fe07f8SJohn Marino 		{"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
8632fe07f8SJohn Marino 			    C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
8732fe07f8SJohn Marino 		    C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
8832fe07f8SJohn Marino 	},
8932fe07f8SJohn Marino 	{
9032fe07f8SJohn Marino 		{"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
9132fe07f8SJohn Marino 		{"oflag:", 0, 0},
9232fe07f8SJohn Marino 		{"cflag:", 0, 0},
9332fe07f8SJohn Marino 		{"lflag:", 0, ISIG | IEXTEN},
9432fe07f8SJohn Marino 		{"chars:", 0, 0},
9532fe07f8SJohn Marino 	}
9632fe07f8SJohn Marino };
9732fe07f8SJohn Marino 
9812db70c8Szrj static const ttychar_t ttychar = {
9932fe07f8SJohn Marino 	{
10032fe07f8SJohn Marino 		CINTR, CQUIT, CERASE, CKILL,
10132fe07f8SJohn Marino 		CEOF, CEOL, CEOL2, CSWTCH,
10232fe07f8SJohn Marino 		CDSWTCH, CERASE2, CSTART, CSTOP,
10332fe07f8SJohn Marino 		CWERASE, CSUSP, CDSUSP, CREPRINT,
10432fe07f8SJohn Marino 		CDISCARD, CLNEXT, CSTATUS, CPAGE,
10532fe07f8SJohn Marino 		CPGOFF, CKILL2, CBRK, CMIN,
10632fe07f8SJohn Marino 		CTIME
10732fe07f8SJohn Marino 	},
10832fe07f8SJohn Marino 	{
10932fe07f8SJohn Marino 		CINTR, CQUIT, CERASE, CKILL,
11032fe07f8SJohn Marino 		_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
11132fe07f8SJohn Marino 		_POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
11232fe07f8SJohn Marino 		_POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
11332fe07f8SJohn Marino 		CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
11432fe07f8SJohn Marino 		_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
11532fe07f8SJohn Marino 		0
11632fe07f8SJohn Marino 	},
11732fe07f8SJohn Marino 	{
11832fe07f8SJohn Marino 		0, 0, 0, 0,
11932fe07f8SJohn Marino 		0, 0, 0, 0,
12032fe07f8SJohn Marino 		0, 0, 0, 0,
12132fe07f8SJohn Marino 		0, 0, 0, 0,
12232fe07f8SJohn Marino 		0, 0, 0, 0,
12332fe07f8SJohn Marino 		0, 0, 0, 0,
12432fe07f8SJohn Marino 		0
12532fe07f8SJohn Marino 	}
12632fe07f8SJohn Marino };
12732fe07f8SJohn Marino 
12812db70c8Szrj static const ttymap_t tty_map[] = {
12932fe07f8SJohn Marino #ifdef VERASE
13032fe07f8SJohn Marino 	{C_ERASE, VERASE,
13132fe07f8SJohn Marino 	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
13232fe07f8SJohn Marino #endif /* VERASE */
13332fe07f8SJohn Marino #ifdef VERASE2
13432fe07f8SJohn Marino 	{C_ERASE2, VERASE2,
13532fe07f8SJohn Marino 	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
13632fe07f8SJohn Marino #endif /* VERASE2 */
13732fe07f8SJohn Marino #ifdef VKILL
13832fe07f8SJohn Marino 	{C_KILL, VKILL,
13932fe07f8SJohn Marino 	{EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
14032fe07f8SJohn Marino #endif /* VKILL */
14132fe07f8SJohn Marino #ifdef VKILL2
14232fe07f8SJohn Marino 	{C_KILL2, VKILL2,
14332fe07f8SJohn Marino 	{EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
14432fe07f8SJohn Marino #endif /* VKILL2 */
14532fe07f8SJohn Marino #ifdef VEOF
14632fe07f8SJohn Marino 	{C_EOF, VEOF,
14732fe07f8SJohn Marino 	{EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
14832fe07f8SJohn Marino #endif /* VEOF */
14932fe07f8SJohn Marino #ifdef VWERASE
15032fe07f8SJohn Marino 	{C_WERASE, VWERASE,
15132fe07f8SJohn Marino 	{ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
15232fe07f8SJohn Marino #endif /* VWERASE */
15332fe07f8SJohn Marino #ifdef VREPRINT
15432fe07f8SJohn Marino 	{C_REPRINT, VREPRINT,
15532fe07f8SJohn Marino 	{ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
15632fe07f8SJohn Marino #endif /* VREPRINT */
15732fe07f8SJohn Marino #ifdef VLNEXT
15832fe07f8SJohn Marino 	{C_LNEXT, VLNEXT,
15932fe07f8SJohn Marino 	{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
16032fe07f8SJohn Marino #endif /* VLNEXT */
16112db70c8Szrj 	{(wint_t)-1, (wint_t)-1,
16232fe07f8SJohn Marino 	{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
16332fe07f8SJohn Marino };
16432fe07f8SJohn Marino 
16512db70c8Szrj static const ttymodes_t ttymodes[] = {
16632fe07f8SJohn Marino #ifdef	IGNBRK
16732fe07f8SJohn Marino 	{"ignbrk", IGNBRK, MD_INP},
16832fe07f8SJohn Marino #endif /* IGNBRK */
16932fe07f8SJohn Marino #ifdef	BRKINT
17032fe07f8SJohn Marino 	{"brkint", BRKINT, MD_INP},
17132fe07f8SJohn Marino #endif /* BRKINT */
17232fe07f8SJohn Marino #ifdef	IGNPAR
17332fe07f8SJohn Marino 	{"ignpar", IGNPAR, MD_INP},
17432fe07f8SJohn Marino #endif /* IGNPAR */
17532fe07f8SJohn Marino #ifdef	PARMRK
17632fe07f8SJohn Marino 	{"parmrk", PARMRK, MD_INP},
17732fe07f8SJohn Marino #endif /* PARMRK */
17832fe07f8SJohn Marino #ifdef	INPCK
17932fe07f8SJohn Marino 	{"inpck", INPCK, MD_INP},
18032fe07f8SJohn Marino #endif /* INPCK */
18132fe07f8SJohn Marino #ifdef	ISTRIP
18232fe07f8SJohn Marino 	{"istrip", ISTRIP, MD_INP},
18332fe07f8SJohn Marino #endif /* ISTRIP */
18432fe07f8SJohn Marino #ifdef	INLCR
18532fe07f8SJohn Marino 	{"inlcr", INLCR, MD_INP},
18632fe07f8SJohn Marino #endif /* INLCR */
18732fe07f8SJohn Marino #ifdef	IGNCR
18832fe07f8SJohn Marino 	{"igncr", IGNCR, MD_INP},
18932fe07f8SJohn Marino #endif /* IGNCR */
19032fe07f8SJohn Marino #ifdef	ICRNL
19132fe07f8SJohn Marino 	{"icrnl", ICRNL, MD_INP},
19232fe07f8SJohn Marino #endif /* ICRNL */
19332fe07f8SJohn Marino #ifdef	IUCLC
19432fe07f8SJohn Marino 	{"iuclc", IUCLC, MD_INP},
19532fe07f8SJohn Marino #endif /* IUCLC */
19632fe07f8SJohn Marino #ifdef	IXON
19732fe07f8SJohn Marino 	{"ixon", IXON, MD_INP},
19832fe07f8SJohn Marino #endif /* IXON */
19932fe07f8SJohn Marino #ifdef	IXANY
20032fe07f8SJohn Marino 	{"ixany", IXANY, MD_INP},
20132fe07f8SJohn Marino #endif /* IXANY */
20232fe07f8SJohn Marino #ifdef	IXOFF
20332fe07f8SJohn Marino 	{"ixoff", IXOFF, MD_INP},
20432fe07f8SJohn Marino #endif /* IXOFF */
20532fe07f8SJohn Marino #ifdef  IMAXBEL
20632fe07f8SJohn Marino 	{"imaxbel", IMAXBEL, MD_INP},
20732fe07f8SJohn Marino #endif /* IMAXBEL */
20832fe07f8SJohn Marino 
20932fe07f8SJohn Marino #ifdef	OPOST
21032fe07f8SJohn Marino 	{"opost", OPOST, MD_OUT},
21132fe07f8SJohn Marino #endif /* OPOST */
21232fe07f8SJohn Marino #ifdef	OLCUC
21332fe07f8SJohn Marino 	{"olcuc", OLCUC, MD_OUT},
21432fe07f8SJohn Marino #endif /* OLCUC */
21532fe07f8SJohn Marino #ifdef	ONLCR
21632fe07f8SJohn Marino 	{"onlcr", ONLCR, MD_OUT},
21732fe07f8SJohn Marino #endif /* ONLCR */
21832fe07f8SJohn Marino #ifdef	OCRNL
21932fe07f8SJohn Marino 	{"ocrnl", OCRNL, MD_OUT},
22032fe07f8SJohn Marino #endif /* OCRNL */
22132fe07f8SJohn Marino #ifdef	ONOCR
22232fe07f8SJohn Marino 	{"onocr", ONOCR, MD_OUT},
22332fe07f8SJohn Marino #endif /* ONOCR */
22432fe07f8SJohn Marino #ifdef ONOEOT
22532fe07f8SJohn Marino 	{"onoeot", ONOEOT, MD_OUT},
22632fe07f8SJohn Marino #endif /* ONOEOT */
22732fe07f8SJohn Marino #ifdef	ONLRET
22832fe07f8SJohn Marino 	{"onlret", ONLRET, MD_OUT},
22932fe07f8SJohn Marino #endif /* ONLRET */
23032fe07f8SJohn Marino #ifdef	OFILL
23132fe07f8SJohn Marino 	{"ofill", OFILL, MD_OUT},
23232fe07f8SJohn Marino #endif /* OFILL */
23332fe07f8SJohn Marino #ifdef	OFDEL
23432fe07f8SJohn Marino 	{"ofdel", OFDEL, MD_OUT},
23532fe07f8SJohn Marino #endif /* OFDEL */
23632fe07f8SJohn Marino #ifdef	NLDLY
23732fe07f8SJohn Marino 	{"nldly", NLDLY, MD_OUT},
23832fe07f8SJohn Marino #endif /* NLDLY */
23932fe07f8SJohn Marino #ifdef	CRDLY
24032fe07f8SJohn Marino 	{"crdly", CRDLY, MD_OUT},
24132fe07f8SJohn Marino #endif /* CRDLY */
24232fe07f8SJohn Marino #ifdef	TABDLY
24332fe07f8SJohn Marino 	{"tabdly", TABDLY, MD_OUT},
24432fe07f8SJohn Marino #endif /* TABDLY */
24532fe07f8SJohn Marino #ifdef	XTABS
24632fe07f8SJohn Marino 	{"xtabs", XTABS, MD_OUT},
24732fe07f8SJohn Marino #endif /* XTABS */
24832fe07f8SJohn Marino #ifdef	BSDLY
24932fe07f8SJohn Marino 	{"bsdly", BSDLY, MD_OUT},
25032fe07f8SJohn Marino #endif /* BSDLY */
25132fe07f8SJohn Marino #ifdef	VTDLY
25232fe07f8SJohn Marino 	{"vtdly", VTDLY, MD_OUT},
25332fe07f8SJohn Marino #endif /* VTDLY */
25432fe07f8SJohn Marino #ifdef	FFDLY
25532fe07f8SJohn Marino 	{"ffdly", FFDLY, MD_OUT},
25632fe07f8SJohn Marino #endif /* FFDLY */
25732fe07f8SJohn Marino #ifdef	PAGEOUT
25832fe07f8SJohn Marino 	{"pageout", PAGEOUT, MD_OUT},
25932fe07f8SJohn Marino #endif /* PAGEOUT */
26032fe07f8SJohn Marino #ifdef	WRAP
26132fe07f8SJohn Marino 	{"wrap", WRAP, MD_OUT},
26232fe07f8SJohn Marino #endif /* WRAP */
26332fe07f8SJohn Marino 
26432fe07f8SJohn Marino #ifdef	CIGNORE
26532fe07f8SJohn Marino 	{"cignore", CIGNORE, MD_CTL},
26632fe07f8SJohn Marino #endif /* CBAUD */
26732fe07f8SJohn Marino #ifdef	CBAUD
26832fe07f8SJohn Marino 	{"cbaud", CBAUD, MD_CTL},
26932fe07f8SJohn Marino #endif /* CBAUD */
27032fe07f8SJohn Marino #ifdef	CSTOPB
27132fe07f8SJohn Marino 	{"cstopb", CSTOPB, MD_CTL},
27232fe07f8SJohn Marino #endif /* CSTOPB */
27332fe07f8SJohn Marino #ifdef	CREAD
27432fe07f8SJohn Marino 	{"cread", CREAD, MD_CTL},
27532fe07f8SJohn Marino #endif /* CREAD */
27632fe07f8SJohn Marino #ifdef	PARENB
27732fe07f8SJohn Marino 	{"parenb", PARENB, MD_CTL},
27832fe07f8SJohn Marino #endif /* PARENB */
27932fe07f8SJohn Marino #ifdef	PARODD
28032fe07f8SJohn Marino 	{"parodd", PARODD, MD_CTL},
28132fe07f8SJohn Marino #endif /* PARODD */
28232fe07f8SJohn Marino #ifdef	HUPCL
28332fe07f8SJohn Marino 	{"hupcl", HUPCL, MD_CTL},
28432fe07f8SJohn Marino #endif /* HUPCL */
28532fe07f8SJohn Marino #ifdef	CLOCAL
28632fe07f8SJohn Marino 	{"clocal", CLOCAL, MD_CTL},
28732fe07f8SJohn Marino #endif /* CLOCAL */
28832fe07f8SJohn Marino #ifdef	LOBLK
28932fe07f8SJohn Marino 	{"loblk", LOBLK, MD_CTL},
29032fe07f8SJohn Marino #endif /* LOBLK */
29132fe07f8SJohn Marino #ifdef	CIBAUD
29232fe07f8SJohn Marino 	{"cibaud", CIBAUD, MD_CTL},
29332fe07f8SJohn Marino #endif /* CIBAUD */
29432fe07f8SJohn Marino #ifdef CRTSCTS
29532fe07f8SJohn Marino #ifdef CCTS_OFLOW
29632fe07f8SJohn Marino 	{"ccts_oflow", CCTS_OFLOW, MD_CTL},
29732fe07f8SJohn Marino #else
29832fe07f8SJohn Marino 	{"crtscts", CRTSCTS, MD_CTL},
29932fe07f8SJohn Marino #endif /* CCTS_OFLOW */
30032fe07f8SJohn Marino #endif /* CRTSCTS */
30132fe07f8SJohn Marino #ifdef CRTS_IFLOW
30232fe07f8SJohn Marino 	{"crts_iflow", CRTS_IFLOW, MD_CTL},
30332fe07f8SJohn Marino #endif /* CRTS_IFLOW */
30432fe07f8SJohn Marino #ifdef CDTRCTS
30532fe07f8SJohn Marino 	{"cdtrcts", CDTRCTS, MD_CTL},
30632fe07f8SJohn Marino #endif /* CDTRCTS */
30732fe07f8SJohn Marino #ifdef MDMBUF
30832fe07f8SJohn Marino 	{"mdmbuf", MDMBUF, MD_CTL},
30932fe07f8SJohn Marino #endif /* MDMBUF */
31032fe07f8SJohn Marino #ifdef RCV1EN
31132fe07f8SJohn Marino 	{"rcv1en", RCV1EN, MD_CTL},
31232fe07f8SJohn Marino #endif /* RCV1EN */
31332fe07f8SJohn Marino #ifdef XMT1EN
31432fe07f8SJohn Marino 	{"xmt1en", XMT1EN, MD_CTL},
31532fe07f8SJohn Marino #endif /* XMT1EN */
31632fe07f8SJohn Marino 
31732fe07f8SJohn Marino #ifdef	ISIG
31832fe07f8SJohn Marino 	{"isig", ISIG, MD_LIN},
31932fe07f8SJohn Marino #endif /* ISIG */
32032fe07f8SJohn Marino #ifdef	ICANON
32132fe07f8SJohn Marino 	{"icanon", ICANON, MD_LIN},
32232fe07f8SJohn Marino #endif /* ICANON */
32332fe07f8SJohn Marino #ifdef	XCASE
32432fe07f8SJohn Marino 	{"xcase", XCASE, MD_LIN},
32532fe07f8SJohn Marino #endif /* XCASE */
32632fe07f8SJohn Marino #ifdef	ECHO
32732fe07f8SJohn Marino 	{"echo", ECHO, MD_LIN},
32832fe07f8SJohn Marino #endif /* ECHO */
32932fe07f8SJohn Marino #ifdef	ECHOE
33032fe07f8SJohn Marino 	{"echoe", ECHOE, MD_LIN},
33132fe07f8SJohn Marino #endif /* ECHOE */
33232fe07f8SJohn Marino #ifdef	ECHOK
33332fe07f8SJohn Marino 	{"echok", ECHOK, MD_LIN},
33432fe07f8SJohn Marino #endif /* ECHOK */
33532fe07f8SJohn Marino #ifdef	ECHONL
33632fe07f8SJohn Marino 	{"echonl", ECHONL, MD_LIN},
33732fe07f8SJohn Marino #endif /* ECHONL */
33832fe07f8SJohn Marino #ifdef	NOFLSH
33932fe07f8SJohn Marino 	{"noflsh", NOFLSH, MD_LIN},
34032fe07f8SJohn Marino #endif /* NOFLSH */
34132fe07f8SJohn Marino #ifdef	TOSTOP
34232fe07f8SJohn Marino 	{"tostop", TOSTOP, MD_LIN},
34332fe07f8SJohn Marino #endif /* TOSTOP */
34432fe07f8SJohn Marino #ifdef	ECHOCTL
34532fe07f8SJohn Marino 	{"echoctl", ECHOCTL, MD_LIN},
34632fe07f8SJohn Marino #endif /* ECHOCTL */
34732fe07f8SJohn Marino #ifdef	ECHOPRT
34832fe07f8SJohn Marino 	{"echoprt", ECHOPRT, MD_LIN},
34932fe07f8SJohn Marino #endif /* ECHOPRT */
35032fe07f8SJohn Marino #ifdef	ECHOKE
35132fe07f8SJohn Marino 	{"echoke", ECHOKE, MD_LIN},
35232fe07f8SJohn Marino #endif /* ECHOKE */
35332fe07f8SJohn Marino #ifdef	DEFECHO
35432fe07f8SJohn Marino 	{"defecho", DEFECHO, MD_LIN},
35532fe07f8SJohn Marino #endif /* DEFECHO */
35632fe07f8SJohn Marino #ifdef	FLUSHO
35732fe07f8SJohn Marino 	{"flusho", FLUSHO, MD_LIN},
35832fe07f8SJohn Marino #endif /* FLUSHO */
35932fe07f8SJohn Marino #ifdef	PENDIN
36032fe07f8SJohn Marino 	{"pendin", PENDIN, MD_LIN},
36132fe07f8SJohn Marino #endif /* PENDIN */
36232fe07f8SJohn Marino #ifdef	IEXTEN
36332fe07f8SJohn Marino 	{"iexten", IEXTEN, MD_LIN},
36432fe07f8SJohn Marino #endif /* IEXTEN */
36532fe07f8SJohn Marino #ifdef	NOKERNINFO
36632fe07f8SJohn Marino 	{"nokerninfo", NOKERNINFO, MD_LIN},
36732fe07f8SJohn Marino #endif /* NOKERNINFO */
36832fe07f8SJohn Marino #ifdef	ALTWERASE
36932fe07f8SJohn Marino 	{"altwerase", ALTWERASE, MD_LIN},
37032fe07f8SJohn Marino #endif /* ALTWERASE */
37132fe07f8SJohn Marino #ifdef	EXTPROC
37232fe07f8SJohn Marino 	{"extproc", EXTPROC, MD_LIN},
37332fe07f8SJohn Marino #endif /* EXTPROC */
37432fe07f8SJohn Marino 
37532fe07f8SJohn Marino #if defined(VINTR)
37632fe07f8SJohn Marino 	{"intr", C_SH(C_INTR), MD_CHAR},
37732fe07f8SJohn Marino #endif /* VINTR */
37832fe07f8SJohn Marino #if defined(VQUIT)
37932fe07f8SJohn Marino 	{"quit", C_SH(C_QUIT), MD_CHAR},
38032fe07f8SJohn Marino #endif /* VQUIT */
38132fe07f8SJohn Marino #if defined(VERASE)
38232fe07f8SJohn Marino 	{"erase", C_SH(C_ERASE), MD_CHAR},
38332fe07f8SJohn Marino #endif /* VERASE */
38432fe07f8SJohn Marino #if defined(VKILL)
38532fe07f8SJohn Marino 	{"kill", C_SH(C_KILL), MD_CHAR},
38632fe07f8SJohn Marino #endif /* VKILL */
38732fe07f8SJohn Marino #if defined(VEOF)
38832fe07f8SJohn Marino 	{"eof", C_SH(C_EOF), MD_CHAR},
38932fe07f8SJohn Marino #endif /* VEOF */
39032fe07f8SJohn Marino #if defined(VEOL)
39132fe07f8SJohn Marino 	{"eol", C_SH(C_EOL), MD_CHAR},
39232fe07f8SJohn Marino #endif /* VEOL */
39332fe07f8SJohn Marino #if defined(VEOL2)
39432fe07f8SJohn Marino 	{"eol2", C_SH(C_EOL2), MD_CHAR},
39532fe07f8SJohn Marino #endif /* VEOL2 */
39632fe07f8SJohn Marino #if defined(VSWTCH)
39732fe07f8SJohn Marino 	{"swtch", C_SH(C_SWTCH), MD_CHAR},
39832fe07f8SJohn Marino #endif /* VSWTCH */
39932fe07f8SJohn Marino #if defined(VDSWTCH)
40032fe07f8SJohn Marino 	{"dswtch", C_SH(C_DSWTCH), MD_CHAR},
40132fe07f8SJohn Marino #endif /* VDSWTCH */
40232fe07f8SJohn Marino #if defined(VERASE2)
40332fe07f8SJohn Marino 	{"erase2", C_SH(C_ERASE2), MD_CHAR},
40432fe07f8SJohn Marino #endif /* VERASE2 */
40532fe07f8SJohn Marino #if defined(VSTART)
40632fe07f8SJohn Marino 	{"start", C_SH(C_START), MD_CHAR},
40732fe07f8SJohn Marino #endif /* VSTART */
40832fe07f8SJohn Marino #if defined(VSTOP)
40932fe07f8SJohn Marino 	{"stop", C_SH(C_STOP), MD_CHAR},
41032fe07f8SJohn Marino #endif /* VSTOP */
41132fe07f8SJohn Marino #if defined(VWERASE)
41232fe07f8SJohn Marino 	{"werase", C_SH(C_WERASE), MD_CHAR},
41332fe07f8SJohn Marino #endif /* VWERASE */
41432fe07f8SJohn Marino #if defined(VSUSP)
41532fe07f8SJohn Marino 	{"susp", C_SH(C_SUSP), MD_CHAR},
41632fe07f8SJohn Marino #endif /* VSUSP */
41732fe07f8SJohn Marino #if defined(VDSUSP)
41832fe07f8SJohn Marino 	{"dsusp", C_SH(C_DSUSP), MD_CHAR},
41932fe07f8SJohn Marino #endif /* VDSUSP */
42032fe07f8SJohn Marino #if defined(VREPRINT)
42132fe07f8SJohn Marino 	{"reprint", C_SH(C_REPRINT), MD_CHAR},
42232fe07f8SJohn Marino #endif /* VREPRINT */
42332fe07f8SJohn Marino #if defined(VDISCARD)
42432fe07f8SJohn Marino 	{"discard", C_SH(C_DISCARD), MD_CHAR},
42532fe07f8SJohn Marino #endif /* VDISCARD */
42632fe07f8SJohn Marino #if defined(VLNEXT)
42732fe07f8SJohn Marino 	{"lnext", C_SH(C_LNEXT), MD_CHAR},
42832fe07f8SJohn Marino #endif /* VLNEXT */
42932fe07f8SJohn Marino #if defined(VSTATUS)
43032fe07f8SJohn Marino 	{"status", C_SH(C_STATUS), MD_CHAR},
43132fe07f8SJohn Marino #endif /* VSTATUS */
43232fe07f8SJohn Marino #if defined(VPAGE)
43332fe07f8SJohn Marino 	{"page", C_SH(C_PAGE), MD_CHAR},
43432fe07f8SJohn Marino #endif /* VPAGE */
43532fe07f8SJohn Marino #if defined(VPGOFF)
43632fe07f8SJohn Marino 	{"pgoff", C_SH(C_PGOFF), MD_CHAR},
43732fe07f8SJohn Marino #endif /* VPGOFF */
43832fe07f8SJohn Marino #if defined(VKILL2)
43932fe07f8SJohn Marino 	{"kill2", C_SH(C_KILL2), MD_CHAR},
44032fe07f8SJohn Marino #endif /* VKILL2 */
44132fe07f8SJohn Marino #if defined(VBRK)
44232fe07f8SJohn Marino 	{"brk", C_SH(C_BRK), MD_CHAR},
44332fe07f8SJohn Marino #endif /* VBRK */
44432fe07f8SJohn Marino #if defined(VMIN)
44532fe07f8SJohn Marino 	{"min", C_SH(C_MIN), MD_CHAR},
44632fe07f8SJohn Marino #endif /* VMIN */
44732fe07f8SJohn Marino #if defined(VTIME)
44832fe07f8SJohn Marino 	{"time", C_SH(C_TIME), MD_CHAR},
44932fe07f8SJohn Marino #endif /* VTIME */
45032fe07f8SJohn Marino 	{NULL, 0, -1},
45132fe07f8SJohn Marino };
45232fe07f8SJohn Marino 
45332fe07f8SJohn Marino 
45432fe07f8SJohn Marino 
45532fe07f8SJohn Marino #define	tty__gettabs(td)	((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
45632fe07f8SJohn Marino #define	tty__geteightbit(td)	(((td)->c_cflag & CSIZE) == CS8)
45732fe07f8SJohn Marino #define	tty__cooked_mode(td)	((td)->c_lflag & ICANON)
45832fe07f8SJohn Marino 
45912db70c8Szrj static int	tty_getty(EditLine *, struct termios *);
46012db70c8Szrj static int	tty_setty(EditLine *, int, const struct termios *);
46112db70c8Szrj static int	tty__getcharindex(int);
46212db70c8Szrj static void	tty__getchar(struct termios *, unsigned char *);
46312db70c8Szrj static void	tty__setchar(struct termios *, unsigned char *);
46412db70c8Szrj static speed_t	tty__getspeed(struct termios *);
46512db70c8Szrj static int	tty_setup(EditLine *);
46612db70c8Szrj static void	tty_setup_flags(EditLine *, struct termios *, int);
46732fe07f8SJohn Marino 
46832fe07f8SJohn Marino #define	t_qu	t_ts
46932fe07f8SJohn Marino 
47032fe07f8SJohn Marino /* tty_getty():
47132fe07f8SJohn Marino  *	Wrapper for tcgetattr to handle EINTR
47232fe07f8SJohn Marino  */
47312db70c8Szrj static int
tty_getty(EditLine * el,struct termios * t)47432fe07f8SJohn Marino tty_getty(EditLine *el, struct termios *t)
47532fe07f8SJohn Marino {
47632fe07f8SJohn Marino 	int rv;
47732fe07f8SJohn Marino 	while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
47832fe07f8SJohn Marino 		continue;
47932fe07f8SJohn Marino 	return rv;
48032fe07f8SJohn Marino }
48132fe07f8SJohn Marino 
48232fe07f8SJohn Marino /* tty_setty():
48332fe07f8SJohn Marino  *	Wrapper for tcsetattr to handle EINTR
48432fe07f8SJohn Marino  */
48512db70c8Szrj static int
tty_setty(EditLine * el,int action,const struct termios * t)48632fe07f8SJohn Marino tty_setty(EditLine *el, int action, const struct termios *t)
48732fe07f8SJohn Marino {
48832fe07f8SJohn Marino 	int rv;
48932fe07f8SJohn Marino 	while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
49032fe07f8SJohn Marino 		continue;
49132fe07f8SJohn Marino 	return rv;
49232fe07f8SJohn Marino }
49332fe07f8SJohn Marino 
49432fe07f8SJohn Marino /* tty_setup():
49532fe07f8SJohn Marino  *	Get the tty parameters and initialize the editing state
49632fe07f8SJohn Marino  */
49712db70c8Szrj static int
tty_setup(EditLine * el)49832fe07f8SJohn Marino tty_setup(EditLine *el)
49932fe07f8SJohn Marino {
500ae19eda8Szrj 	int rst = (el->el_flags & NO_RESET) == 0;
50132fe07f8SJohn Marino 
50232fe07f8SJohn Marino 	if (el->el_flags & EDIT_DISABLED)
50332fe07f8SJohn Marino 		return 0;
50432fe07f8SJohn Marino 
50512db70c8Szrj 	if (el->el_tty.t_initialized)
50612db70c8Szrj 		return -1;
50712db70c8Szrj 
50832fe07f8SJohn Marino 	if (!isatty(el->el_outfd)) {
50932fe07f8SJohn Marino #ifdef DEBUG_TTY
510c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__,
511c8e4d2bfSJohn Marino 		    strerror(errno));
51232fe07f8SJohn Marino #endif /* DEBUG_TTY */
51332fe07f8SJohn Marino 		return -1;
51432fe07f8SJohn Marino 	}
515c8e4d2bfSJohn Marino 	if (tty_getty(el, &el->el_tty.t_or) == -1) {
51632fe07f8SJohn Marino #ifdef DEBUG_TTY
517c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
518c8e4d2bfSJohn Marino 		    strerror(errno));
51932fe07f8SJohn Marino #endif /* DEBUG_TTY */
52032fe07f8SJohn Marino 		return -1;
52132fe07f8SJohn Marino 	}
522c8e4d2bfSJohn Marino 	el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or;
52332fe07f8SJohn Marino 
52432fe07f8SJohn Marino 	el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
52532fe07f8SJohn Marino 	el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
52632fe07f8SJohn Marino 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
52732fe07f8SJohn Marino 
52884b940c1SJohn Marino 	tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
52932fe07f8SJohn Marino 
53032fe07f8SJohn Marino 	/*
53132fe07f8SJohn Marino          * Reset the tty chars to reasonable defaults
53232fe07f8SJohn Marino          * If they are disabled, then enable them.
53332fe07f8SJohn Marino          */
53432fe07f8SJohn Marino 	if (rst) {
53532fe07f8SJohn Marino 		if (tty__cooked_mode(&el->el_tty.t_ts)) {
53632fe07f8SJohn Marino 			tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
53732fe07f8SJohn Marino 			/*
53832fe07f8SJohn Marino 	                 * Don't affect CMIN and CTIME for the editor mode
53932fe07f8SJohn Marino 	                 */
54032fe07f8SJohn Marino 			for (rst = 0; rst < C_NCC - 2; rst++)
54132fe07f8SJohn Marino 				if (el->el_tty.t_c[TS_IO][rst] !=
54232fe07f8SJohn Marino 				      el->el_tty.t_vdisable
54332fe07f8SJohn Marino 				    && el->el_tty.t_c[ED_IO][rst] !=
54432fe07f8SJohn Marino 				      el->el_tty.t_vdisable)
54532fe07f8SJohn Marino 					el->el_tty.t_c[ED_IO][rst] =
54632fe07f8SJohn Marino 					    el->el_tty.t_c[TS_IO][rst];
54732fe07f8SJohn Marino 			for (rst = 0; rst < C_NCC; rst++)
54832fe07f8SJohn Marino 				if (el->el_tty.t_c[TS_IO][rst] !=
54932fe07f8SJohn Marino 				    el->el_tty.t_vdisable)
55032fe07f8SJohn Marino 					el->el_tty.t_c[EX_IO][rst] =
55132fe07f8SJohn Marino 					    el->el_tty.t_c[TS_IO][rst];
55232fe07f8SJohn Marino 		}
55332fe07f8SJohn Marino 		tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
55432fe07f8SJohn Marino 		if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
55532fe07f8SJohn Marino #ifdef DEBUG_TTY
556c8e4d2bfSJohn Marino 			(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
557c8e4d2bfSJohn Marino 			    __func__, strerror(errno));
55832fe07f8SJohn Marino #endif /* DEBUG_TTY */
55932fe07f8SJohn Marino 			return -1;
56032fe07f8SJohn Marino 		}
56132fe07f8SJohn Marino 	}
56232fe07f8SJohn Marino 
56384b940c1SJohn Marino 	tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
56432fe07f8SJohn Marino 
56532fe07f8SJohn Marino 	tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
56632fe07f8SJohn Marino 	tty_bind_char(el, 1);
56712db70c8Szrj 	el->el_tty.t_initialized = 1;
56832fe07f8SJohn Marino 	return 0;
56932fe07f8SJohn Marino }
57032fe07f8SJohn Marino 
57112db70c8Szrj libedit_private int
tty_init(EditLine * el)57232fe07f8SJohn Marino tty_init(EditLine *el)
57332fe07f8SJohn Marino {
57432fe07f8SJohn Marino 
57532fe07f8SJohn Marino 	el->el_tty.t_mode = EX_IO;
57632fe07f8SJohn Marino 	el->el_tty.t_vdisable = _POSIX_VDISABLE;
57712db70c8Szrj 	el->el_tty.t_initialized = 0;
57832fe07f8SJohn Marino 	(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
57932fe07f8SJohn Marino 	(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
58032fe07f8SJohn Marino 	return tty_setup(el);
58132fe07f8SJohn Marino }
58232fe07f8SJohn Marino 
58332fe07f8SJohn Marino 
58432fe07f8SJohn Marino /* tty_end():
58532fe07f8SJohn Marino  *	Restore the tty to its original settings
58632fe07f8SJohn Marino  */
58712db70c8Szrj libedit_private void
58832fe07f8SJohn Marino /*ARGSUSED*/
tty_end(EditLine * el,int how)589ae19eda8Szrj tty_end(EditLine *el, int how)
59032fe07f8SJohn Marino {
59112db70c8Szrj 	if (el->el_flags & EDIT_DISABLED)
59212db70c8Szrj 		return;
59312db70c8Szrj 
59412db70c8Szrj 	if (!el->el_tty.t_initialized)
59512db70c8Szrj 		return;
59612db70c8Szrj 
597ae19eda8Szrj 	if (tty_setty(el, how, &el->el_tty.t_or) == -1)
598ae19eda8Szrj 	{
599c8e4d2bfSJohn Marino #ifdef DEBUG_TTY
600c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile,
601c8e4d2bfSJohn Marino 		    "%s: tty_setty: %s\n", __func__, strerror(errno));
602c8e4d2bfSJohn Marino #endif /* DEBUG_TTY */
603c8e4d2bfSJohn Marino 	}
60432fe07f8SJohn Marino }
60532fe07f8SJohn Marino 
60632fe07f8SJohn Marino 
60732fe07f8SJohn Marino /* tty__getspeed():
60832fe07f8SJohn Marino  *	Get the tty speed
60932fe07f8SJohn Marino  */
61012db70c8Szrj static speed_t
tty__getspeed(struct termios * td)61132fe07f8SJohn Marino tty__getspeed(struct termios *td)
61232fe07f8SJohn Marino {
61332fe07f8SJohn Marino 	speed_t spd;
61432fe07f8SJohn Marino 
61532fe07f8SJohn Marino 	if ((spd = cfgetispeed(td)) == 0)
61632fe07f8SJohn Marino 		spd = cfgetospeed(td);
61732fe07f8SJohn Marino 	return spd;
61832fe07f8SJohn Marino }
61932fe07f8SJohn Marino 
62032fe07f8SJohn Marino /* tty__getspeed():
62132fe07f8SJohn Marino  *	Return the index of the asked char in the c_cc array
62232fe07f8SJohn Marino  */
62312db70c8Szrj static int
tty__getcharindex(int i)62432fe07f8SJohn Marino tty__getcharindex(int i)
62532fe07f8SJohn Marino {
62632fe07f8SJohn Marino 	switch (i) {
62732fe07f8SJohn Marino #ifdef VINTR
62832fe07f8SJohn Marino 	case C_INTR:
62932fe07f8SJohn Marino 		return VINTR;
63032fe07f8SJohn Marino #endif /* VINTR */
63132fe07f8SJohn Marino #ifdef VQUIT
63232fe07f8SJohn Marino 	case C_QUIT:
63332fe07f8SJohn Marino 		return VQUIT;
63432fe07f8SJohn Marino #endif /* VQUIT */
63532fe07f8SJohn Marino #ifdef VERASE
63632fe07f8SJohn Marino 	case C_ERASE:
63732fe07f8SJohn Marino 		return VERASE;
63832fe07f8SJohn Marino #endif /* VERASE */
63932fe07f8SJohn Marino #ifdef VKILL
64032fe07f8SJohn Marino 	case C_KILL:
64132fe07f8SJohn Marino 		return VKILL;
64232fe07f8SJohn Marino #endif /* VKILL */
64332fe07f8SJohn Marino #ifdef VEOF
64432fe07f8SJohn Marino 	case C_EOF:
64532fe07f8SJohn Marino 		return VEOF;
64632fe07f8SJohn Marino #endif /* VEOF */
64732fe07f8SJohn Marino #ifdef VEOL
64832fe07f8SJohn Marino 	case C_EOL:
64932fe07f8SJohn Marino 		return VEOL;
65032fe07f8SJohn Marino #endif /* VEOL */
65132fe07f8SJohn Marino #ifdef VEOL2
65232fe07f8SJohn Marino 	case C_EOL2:
65332fe07f8SJohn Marino 		return VEOL2;
65432fe07f8SJohn Marino #endif /* VEOL2 */
65532fe07f8SJohn Marino #ifdef VSWTCH
65632fe07f8SJohn Marino 	case C_SWTCH:
65732fe07f8SJohn Marino 		return VSWTCH;
65832fe07f8SJohn Marino #endif /* VSWTCH */
65932fe07f8SJohn Marino #ifdef VDSWTCH
66032fe07f8SJohn Marino 	case C_DSWTCH:
66132fe07f8SJohn Marino 		return VDSWTCH;
66232fe07f8SJohn Marino #endif /* VDSWTCH */
66332fe07f8SJohn Marino #ifdef VERASE2
66432fe07f8SJohn Marino 	case C_ERASE2:
66532fe07f8SJohn Marino 		return VERASE2;
66632fe07f8SJohn Marino #endif /* VERASE2 */
66732fe07f8SJohn Marino #ifdef VSTART
66832fe07f8SJohn Marino 	case C_START:
66932fe07f8SJohn Marino 		return VSTART;
67032fe07f8SJohn Marino #endif /* VSTART */
67132fe07f8SJohn Marino #ifdef VSTOP
67232fe07f8SJohn Marino 	case C_STOP:
67332fe07f8SJohn Marino 		return VSTOP;
67432fe07f8SJohn Marino #endif /* VSTOP */
67532fe07f8SJohn Marino #ifdef VWERASE
67632fe07f8SJohn Marino 	case C_WERASE:
67732fe07f8SJohn Marino 		return VWERASE;
67832fe07f8SJohn Marino #endif /* VWERASE */
67932fe07f8SJohn Marino #ifdef VSUSP
68032fe07f8SJohn Marino 	case C_SUSP:
68132fe07f8SJohn Marino 		return VSUSP;
68232fe07f8SJohn Marino #endif /* VSUSP */
68332fe07f8SJohn Marino #ifdef VDSUSP
68432fe07f8SJohn Marino 	case C_DSUSP:
68532fe07f8SJohn Marino 		return VDSUSP;
68632fe07f8SJohn Marino #endif /* VDSUSP */
68732fe07f8SJohn Marino #ifdef VREPRINT
68832fe07f8SJohn Marino 	case C_REPRINT:
68932fe07f8SJohn Marino 		return VREPRINT;
69032fe07f8SJohn Marino #endif /* VREPRINT */
69132fe07f8SJohn Marino #ifdef VDISCARD
69232fe07f8SJohn Marino 	case C_DISCARD:
69332fe07f8SJohn Marino 		return VDISCARD;
69432fe07f8SJohn Marino #endif /* VDISCARD */
69532fe07f8SJohn Marino #ifdef VLNEXT
69632fe07f8SJohn Marino 	case C_LNEXT:
69732fe07f8SJohn Marino 		return VLNEXT;
69832fe07f8SJohn Marino #endif /* VLNEXT */
69932fe07f8SJohn Marino #ifdef VSTATUS
70032fe07f8SJohn Marino 	case C_STATUS:
70132fe07f8SJohn Marino 		return VSTATUS;
70232fe07f8SJohn Marino #endif /* VSTATUS */
70332fe07f8SJohn Marino #ifdef VPAGE
70432fe07f8SJohn Marino 	case C_PAGE:
70532fe07f8SJohn Marino 		return VPAGE;
70632fe07f8SJohn Marino #endif /* VPAGE */
70732fe07f8SJohn Marino #ifdef VPGOFF
70832fe07f8SJohn Marino 	case C_PGOFF:
70932fe07f8SJohn Marino 		return VPGOFF;
71032fe07f8SJohn Marino #endif /* VPGOFF */
71132fe07f8SJohn Marino #ifdef VKILL2
71232fe07f8SJohn Marino 	case C_KILL2:
71332fe07f8SJohn Marino 		return VKILL2;
71432fe07f8SJohn Marino #endif /* KILL2 */
71532fe07f8SJohn Marino #ifdef VMIN
71632fe07f8SJohn Marino 	case C_MIN:
71732fe07f8SJohn Marino 		return VMIN;
71832fe07f8SJohn Marino #endif /* VMIN */
71932fe07f8SJohn Marino #ifdef VTIME
72032fe07f8SJohn Marino 	case C_TIME:
72132fe07f8SJohn Marino 		return VTIME;
72232fe07f8SJohn Marino #endif /* VTIME */
72332fe07f8SJohn Marino 	default:
72432fe07f8SJohn Marino 		return -1;
72532fe07f8SJohn Marino 	}
72632fe07f8SJohn Marino }
72732fe07f8SJohn Marino 
72832fe07f8SJohn Marino /* tty__getchar():
72932fe07f8SJohn Marino  *	Get the tty characters
73032fe07f8SJohn Marino  */
73112db70c8Szrj static void
tty__getchar(struct termios * td,unsigned char * s)73232fe07f8SJohn Marino tty__getchar(struct termios *td, unsigned char *s)
73332fe07f8SJohn Marino {
73432fe07f8SJohn Marino 
73532fe07f8SJohn Marino #ifdef VINTR
73632fe07f8SJohn Marino 	s[C_INTR] = td->c_cc[VINTR];
73732fe07f8SJohn Marino #endif /* VINTR */
73832fe07f8SJohn Marino #ifdef VQUIT
73932fe07f8SJohn Marino 	s[C_QUIT] = td->c_cc[VQUIT];
74032fe07f8SJohn Marino #endif /* VQUIT */
74132fe07f8SJohn Marino #ifdef VERASE
74232fe07f8SJohn Marino 	s[C_ERASE] = td->c_cc[VERASE];
74332fe07f8SJohn Marino #endif /* VERASE */
74432fe07f8SJohn Marino #ifdef VKILL
74532fe07f8SJohn Marino 	s[C_KILL] = td->c_cc[VKILL];
74632fe07f8SJohn Marino #endif /* VKILL */
74732fe07f8SJohn Marino #ifdef VEOF
74832fe07f8SJohn Marino 	s[C_EOF] = td->c_cc[VEOF];
74932fe07f8SJohn Marino #endif /* VEOF */
75032fe07f8SJohn Marino #ifdef VEOL
75132fe07f8SJohn Marino 	s[C_EOL] = td->c_cc[VEOL];
75232fe07f8SJohn Marino #endif /* VEOL */
75332fe07f8SJohn Marino #ifdef VEOL2
75432fe07f8SJohn Marino 	s[C_EOL2] = td->c_cc[VEOL2];
75532fe07f8SJohn Marino #endif /* VEOL2 */
75632fe07f8SJohn Marino #ifdef VSWTCH
75732fe07f8SJohn Marino 	s[C_SWTCH] = td->c_cc[VSWTCH];
75832fe07f8SJohn Marino #endif /* VSWTCH */
75932fe07f8SJohn Marino #ifdef VDSWTCH
76032fe07f8SJohn Marino 	s[C_DSWTCH] = td->c_cc[VDSWTCH];
76132fe07f8SJohn Marino #endif /* VDSWTCH */
76232fe07f8SJohn Marino #ifdef VERASE2
76332fe07f8SJohn Marino 	s[C_ERASE2] = td->c_cc[VERASE2];
76432fe07f8SJohn Marino #endif /* VERASE2 */
76532fe07f8SJohn Marino #ifdef VSTART
76632fe07f8SJohn Marino 	s[C_START] = td->c_cc[VSTART];
76732fe07f8SJohn Marino #endif /* VSTART */
76832fe07f8SJohn Marino #ifdef VSTOP
76932fe07f8SJohn Marino 	s[C_STOP] = td->c_cc[VSTOP];
77032fe07f8SJohn Marino #endif /* VSTOP */
77132fe07f8SJohn Marino #ifdef VWERASE
77232fe07f8SJohn Marino 	s[C_WERASE] = td->c_cc[VWERASE];
77332fe07f8SJohn Marino #endif /* VWERASE */
77432fe07f8SJohn Marino #ifdef VSUSP
77532fe07f8SJohn Marino 	s[C_SUSP] = td->c_cc[VSUSP];
77632fe07f8SJohn Marino #endif /* VSUSP */
77732fe07f8SJohn Marino #ifdef VDSUSP
77832fe07f8SJohn Marino 	s[C_DSUSP] = td->c_cc[VDSUSP];
77932fe07f8SJohn Marino #endif /* VDSUSP */
78032fe07f8SJohn Marino #ifdef VREPRINT
78132fe07f8SJohn Marino 	s[C_REPRINT] = td->c_cc[VREPRINT];
78232fe07f8SJohn Marino #endif /* VREPRINT */
78332fe07f8SJohn Marino #ifdef VDISCARD
78432fe07f8SJohn Marino 	s[C_DISCARD] = td->c_cc[VDISCARD];
78532fe07f8SJohn Marino #endif /* VDISCARD */
78632fe07f8SJohn Marino #ifdef VLNEXT
78732fe07f8SJohn Marino 	s[C_LNEXT] = td->c_cc[VLNEXT];
78832fe07f8SJohn Marino #endif /* VLNEXT */
78932fe07f8SJohn Marino #ifdef VSTATUS
79032fe07f8SJohn Marino 	s[C_STATUS] = td->c_cc[VSTATUS];
79132fe07f8SJohn Marino #endif /* VSTATUS */
79232fe07f8SJohn Marino #ifdef VPAGE
79332fe07f8SJohn Marino 	s[C_PAGE] = td->c_cc[VPAGE];
79432fe07f8SJohn Marino #endif /* VPAGE */
79532fe07f8SJohn Marino #ifdef VPGOFF
79632fe07f8SJohn Marino 	s[C_PGOFF] = td->c_cc[VPGOFF];
79732fe07f8SJohn Marino #endif /* VPGOFF */
79832fe07f8SJohn Marino #ifdef VKILL2
79932fe07f8SJohn Marino 	s[C_KILL2] = td->c_cc[VKILL2];
80032fe07f8SJohn Marino #endif /* KILL2 */
80132fe07f8SJohn Marino #ifdef VMIN
80232fe07f8SJohn Marino 	s[C_MIN] = td->c_cc[VMIN];
80332fe07f8SJohn Marino #endif /* VMIN */
80432fe07f8SJohn Marino #ifdef VTIME
80532fe07f8SJohn Marino 	s[C_TIME] = td->c_cc[VTIME];
80632fe07f8SJohn Marino #endif /* VTIME */
80732fe07f8SJohn Marino }				/* tty__getchar */
80832fe07f8SJohn Marino 
80932fe07f8SJohn Marino 
81032fe07f8SJohn Marino /* tty__setchar():
81132fe07f8SJohn Marino  *	Set the tty characters
81232fe07f8SJohn Marino  */
81312db70c8Szrj static void
tty__setchar(struct termios * td,unsigned char * s)81432fe07f8SJohn Marino tty__setchar(struct termios *td, unsigned char *s)
81532fe07f8SJohn Marino {
81632fe07f8SJohn Marino 
81732fe07f8SJohn Marino #ifdef VINTR
81832fe07f8SJohn Marino 	td->c_cc[VINTR] = s[C_INTR];
81932fe07f8SJohn Marino #endif /* VINTR */
82032fe07f8SJohn Marino #ifdef VQUIT
82132fe07f8SJohn Marino 	td->c_cc[VQUIT] = s[C_QUIT];
82232fe07f8SJohn Marino #endif /* VQUIT */
82332fe07f8SJohn Marino #ifdef VERASE
82432fe07f8SJohn Marino 	td->c_cc[VERASE] = s[C_ERASE];
82532fe07f8SJohn Marino #endif /* VERASE */
82632fe07f8SJohn Marino #ifdef VKILL
82732fe07f8SJohn Marino 	td->c_cc[VKILL] = s[C_KILL];
82832fe07f8SJohn Marino #endif /* VKILL */
82932fe07f8SJohn Marino #ifdef VEOF
83032fe07f8SJohn Marino 	td->c_cc[VEOF] = s[C_EOF];
83132fe07f8SJohn Marino #endif /* VEOF */
83232fe07f8SJohn Marino #ifdef VEOL
83332fe07f8SJohn Marino 	td->c_cc[VEOL] = s[C_EOL];
83432fe07f8SJohn Marino #endif /* VEOL */
83532fe07f8SJohn Marino #ifdef VEOL2
83632fe07f8SJohn Marino 	td->c_cc[VEOL2] = s[C_EOL2];
83732fe07f8SJohn Marino #endif /* VEOL2 */
83832fe07f8SJohn Marino #ifdef VSWTCH
83932fe07f8SJohn Marino 	td->c_cc[VSWTCH] = s[C_SWTCH];
84032fe07f8SJohn Marino #endif /* VSWTCH */
84132fe07f8SJohn Marino #ifdef VDSWTCH
84232fe07f8SJohn Marino 	td->c_cc[VDSWTCH] = s[C_DSWTCH];
84332fe07f8SJohn Marino #endif /* VDSWTCH */
84432fe07f8SJohn Marino #ifdef VERASE2
84532fe07f8SJohn Marino 	td->c_cc[VERASE2] = s[C_ERASE2];
84632fe07f8SJohn Marino #endif /* VERASE2 */
84732fe07f8SJohn Marino #ifdef VSTART
84832fe07f8SJohn Marino 	td->c_cc[VSTART] = s[C_START];
84932fe07f8SJohn Marino #endif /* VSTART */
85032fe07f8SJohn Marino #ifdef VSTOP
85132fe07f8SJohn Marino 	td->c_cc[VSTOP] = s[C_STOP];
85232fe07f8SJohn Marino #endif /* VSTOP */
85332fe07f8SJohn Marino #ifdef VWERASE
85432fe07f8SJohn Marino 	td->c_cc[VWERASE] = s[C_WERASE];
85532fe07f8SJohn Marino #endif /* VWERASE */
85632fe07f8SJohn Marino #ifdef VSUSP
85732fe07f8SJohn Marino 	td->c_cc[VSUSP] = s[C_SUSP];
85832fe07f8SJohn Marino #endif /* VSUSP */
85932fe07f8SJohn Marino #ifdef VDSUSP
86032fe07f8SJohn Marino 	td->c_cc[VDSUSP] = s[C_DSUSP];
86132fe07f8SJohn Marino #endif /* VDSUSP */
86232fe07f8SJohn Marino #ifdef VREPRINT
86332fe07f8SJohn Marino 	td->c_cc[VREPRINT] = s[C_REPRINT];
86432fe07f8SJohn Marino #endif /* VREPRINT */
86532fe07f8SJohn Marino #ifdef VDISCARD
86632fe07f8SJohn Marino 	td->c_cc[VDISCARD] = s[C_DISCARD];
86732fe07f8SJohn Marino #endif /* VDISCARD */
86832fe07f8SJohn Marino #ifdef VLNEXT
86932fe07f8SJohn Marino 	td->c_cc[VLNEXT] = s[C_LNEXT];
87032fe07f8SJohn Marino #endif /* VLNEXT */
87132fe07f8SJohn Marino #ifdef VSTATUS
87232fe07f8SJohn Marino 	td->c_cc[VSTATUS] = s[C_STATUS];
87332fe07f8SJohn Marino #endif /* VSTATUS */
87432fe07f8SJohn Marino #ifdef VPAGE
87532fe07f8SJohn Marino 	td->c_cc[VPAGE] = s[C_PAGE];
87632fe07f8SJohn Marino #endif /* VPAGE */
87732fe07f8SJohn Marino #ifdef VPGOFF
87832fe07f8SJohn Marino 	td->c_cc[VPGOFF] = s[C_PGOFF];
87932fe07f8SJohn Marino #endif /* VPGOFF */
88032fe07f8SJohn Marino #ifdef VKILL2
88132fe07f8SJohn Marino 	td->c_cc[VKILL2] = s[C_KILL2];
88232fe07f8SJohn Marino #endif /* VKILL2 */
88332fe07f8SJohn Marino #ifdef VMIN
88432fe07f8SJohn Marino 	td->c_cc[VMIN] = s[C_MIN];
88532fe07f8SJohn Marino #endif /* VMIN */
88632fe07f8SJohn Marino #ifdef VTIME
88732fe07f8SJohn Marino 	td->c_cc[VTIME] = s[C_TIME];
88832fe07f8SJohn Marino #endif /* VTIME */
88932fe07f8SJohn Marino }				/* tty__setchar */
89032fe07f8SJohn Marino 
89132fe07f8SJohn Marino 
89232fe07f8SJohn Marino /* tty_bind_char():
89332fe07f8SJohn Marino  *	Rebind the editline functions
89432fe07f8SJohn Marino  */
89512db70c8Szrj libedit_private void
tty_bind_char(EditLine * el,int force)89632fe07f8SJohn Marino tty_bind_char(EditLine *el, int force)
89732fe07f8SJohn Marino {
89832fe07f8SJohn Marino 
89932fe07f8SJohn Marino 	unsigned char *t_n = el->el_tty.t_c[ED_IO];
90032fe07f8SJohn Marino 	unsigned char *t_o = el->el_tty.t_ed.c_cc;
90112db70c8Szrj 	wchar_t new[2], old[2];
90232fe07f8SJohn Marino 	const ttymap_t *tp;
90332fe07f8SJohn Marino 	el_action_t *map, *alt;
90432fe07f8SJohn Marino 	const el_action_t *dmap, *dalt;
90532fe07f8SJohn Marino 	new[1] = old[1] = '\0';
90632fe07f8SJohn Marino 
90732fe07f8SJohn Marino 	map = el->el_map.key;
90832fe07f8SJohn Marino 	alt = el->el_map.alt;
90932fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI) {
91032fe07f8SJohn Marino 		dmap = el->el_map.vii;
91132fe07f8SJohn Marino 		dalt = el->el_map.vic;
91232fe07f8SJohn Marino 	} else {
91332fe07f8SJohn Marino 		dmap = el->el_map.emacs;
91432fe07f8SJohn Marino 		dalt = NULL;
91532fe07f8SJohn Marino 	}
91632fe07f8SJohn Marino 
91712db70c8Szrj 	for (tp = tty_map; tp->nch != (wint_t)-1; tp++) {
91812db70c8Szrj 		new[0] = (wchar_t)t_n[tp->nch];
91912db70c8Szrj 		old[0] = (wchar_t)t_o[tp->och];
92032fe07f8SJohn Marino 		if (new[0] == old[0] && !force)
92132fe07f8SJohn Marino 			continue;
92232fe07f8SJohn Marino 		/* Put the old default binding back, and set the new binding */
92332fe07f8SJohn Marino 		keymacro_clear(el, map, old);
92412db70c8Szrj 		map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]];
92532fe07f8SJohn Marino 		keymacro_clear(el, map, new);
92632fe07f8SJohn Marino 		/* MAP_VI == 1, MAP_EMACS == 0... */
92712db70c8Szrj 		map[(unsigned char)new[0]] = tp->bind[el->el_map.type];
92832fe07f8SJohn Marino 		if (dalt) {
92932fe07f8SJohn Marino 			keymacro_clear(el, alt, old);
93012db70c8Szrj 			alt[(unsigned char)old[0]] =
93112db70c8Szrj 			    dalt[(unsigned char)old[0]];
93232fe07f8SJohn Marino 			keymacro_clear(el, alt, new);
93312db70c8Szrj 			alt[(unsigned char)new[0]] =
93412db70c8Szrj 			    tp->bind[el->el_map.type + 1];
93532fe07f8SJohn Marino 		}
93632fe07f8SJohn Marino 	}
93732fe07f8SJohn Marino }
93832fe07f8SJohn Marino 
93932fe07f8SJohn Marino 
94012db70c8Szrj static tcflag_t *
tty__get_flag(struct termios * t,int kind)94184b940c1SJohn Marino tty__get_flag(struct termios *t, int kind) {
94284b940c1SJohn Marino 	switch (kind) {
94384b940c1SJohn Marino 	case MD_INP:
94484b940c1SJohn Marino 		return &t->c_iflag;
94584b940c1SJohn Marino 	case MD_OUT:
94684b940c1SJohn Marino 		return &t->c_oflag;
94784b940c1SJohn Marino 	case MD_CTL:
94884b940c1SJohn Marino 		return &t->c_cflag;
94984b940c1SJohn Marino 	case MD_LIN:
95084b940c1SJohn Marino 		return &t->c_lflag;
95184b940c1SJohn Marino 	default:
95284b940c1SJohn Marino 		abort();
95384b940c1SJohn Marino 		/*NOTREACHED*/
95484b940c1SJohn Marino 	}
95584b940c1SJohn Marino }
95684b940c1SJohn Marino 
95784b940c1SJohn Marino 
95812db70c8Szrj static tcflag_t
tty_update_flag(EditLine * el,tcflag_t f,int mode,int kind)95984b940c1SJohn Marino tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
96084b940c1SJohn Marino {
96184b940c1SJohn Marino 	f &= ~el->el_tty.t_t[mode][kind].t_clrmask;
96284b940c1SJohn Marino 	f |= el->el_tty.t_t[mode][kind].t_setmask;
96384b940c1SJohn Marino 	return f;
96484b940c1SJohn Marino }
96584b940c1SJohn Marino 
96684b940c1SJohn Marino 
96712db70c8Szrj static void
tty_update_flags(EditLine * el,int kind)96884b940c1SJohn Marino tty_update_flags(EditLine *el, int kind)
96984b940c1SJohn Marino {
97084b940c1SJohn Marino 	tcflag_t *tt, *ed, *ex;
97184b940c1SJohn Marino 	tt = tty__get_flag(&el->el_tty.t_ts, kind);
97284b940c1SJohn Marino 	ed = tty__get_flag(&el->el_tty.t_ed, kind);
97384b940c1SJohn Marino 	ex = tty__get_flag(&el->el_tty.t_ex, kind);
97484b940c1SJohn Marino 
97584b940c1SJohn Marino 	if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) {
97684b940c1SJohn Marino 		*ed = tty_update_flag(el, *tt, ED_IO, kind);
97784b940c1SJohn Marino 		*ex = tty_update_flag(el, *tt, EX_IO, kind);
97884b940c1SJohn Marino 	}
97984b940c1SJohn Marino }
98084b940c1SJohn Marino 
98184b940c1SJohn Marino 
98212db70c8Szrj static void
tty_update_char(EditLine * el,int mode,int c)98384b940c1SJohn Marino tty_update_char(EditLine *el, int mode, int c) {
98484b940c1SJohn Marino 	if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c)))
98584b940c1SJohn Marino 	    && (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c]))
98684b940c1SJohn Marino 		el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c];
98784b940c1SJohn Marino 	if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c))
98884b940c1SJohn Marino 		el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable;
98984b940c1SJohn Marino }
99084b940c1SJohn Marino 
99184b940c1SJohn Marino 
99232fe07f8SJohn Marino /* tty_rawmode():
99332fe07f8SJohn Marino  *	Set terminal into 1 character at a time mode.
99432fe07f8SJohn Marino  */
99512db70c8Szrj libedit_private int
tty_rawmode(EditLine * el)99632fe07f8SJohn Marino tty_rawmode(EditLine *el)
99732fe07f8SJohn Marino {
99832fe07f8SJohn Marino 
99932fe07f8SJohn Marino 	if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
100032fe07f8SJohn Marino 		return 0;
100132fe07f8SJohn Marino 
100232fe07f8SJohn Marino 	if (el->el_flags & EDIT_DISABLED)
100332fe07f8SJohn Marino 		return 0;
100432fe07f8SJohn Marino 
100532fe07f8SJohn Marino 	if (tty_getty(el, &el->el_tty.t_ts) == -1) {
100632fe07f8SJohn Marino #ifdef DEBUG_TTY
1007c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
100832fe07f8SJohn Marino 		    strerror(errno));
100932fe07f8SJohn Marino #endif /* DEBUG_TTY */
101032fe07f8SJohn Marino 		return -1;
101132fe07f8SJohn Marino 	}
101232fe07f8SJohn Marino 	/*
101332fe07f8SJohn Marino          * We always keep up with the eight bit setting and the speed of the
101432fe07f8SJohn Marino          * tty. But we only believe changes that are made to cooked mode!
101532fe07f8SJohn Marino          */
101632fe07f8SJohn Marino 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
101732fe07f8SJohn Marino 	el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
101832fe07f8SJohn Marino 
101932fe07f8SJohn Marino 	if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
102032fe07f8SJohn Marino 	    tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
102132fe07f8SJohn Marino 		(void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
102232fe07f8SJohn Marino 		(void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
102332fe07f8SJohn Marino 		(void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
102432fe07f8SJohn Marino 		(void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
102532fe07f8SJohn Marino 	}
102632fe07f8SJohn Marino 	if (tty__cooked_mode(&el->el_tty.t_ts)) {
102784b940c1SJohn Marino 		int i;
102832fe07f8SJohn Marino 
102984b940c1SJohn Marino 		for (i = MD_INP; i <= MD_LIN; i++)
103084b940c1SJohn Marino 			tty_update_flags(el, i);
103132fe07f8SJohn Marino 
103232fe07f8SJohn Marino 		if (tty__gettabs(&el->el_tty.t_ex) == 0)
103332fe07f8SJohn Marino 			el->el_tty.t_tabs = 0;
103432fe07f8SJohn Marino 		else
103532fe07f8SJohn Marino 			el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
103632fe07f8SJohn Marino 
103732fe07f8SJohn Marino 		tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
103832fe07f8SJohn Marino 		/*
103932fe07f8SJohn Marino 		 * Check if the user made any changes.
104032fe07f8SJohn Marino 		 * If he did, then propagate the changes to the
104132fe07f8SJohn Marino 		 * edit and execute data structures.
104232fe07f8SJohn Marino 		 */
104332fe07f8SJohn Marino 		for (i = 0; i < C_NCC; i++)
104432fe07f8SJohn Marino 			if (el->el_tty.t_c[TS_IO][i] !=
104532fe07f8SJohn Marino 			    el->el_tty.t_c[EX_IO][i])
104632fe07f8SJohn Marino 				break;
104732fe07f8SJohn Marino 
104832fe07f8SJohn Marino 		if (i != C_NCC) {
104932fe07f8SJohn Marino 			/*
105012db70c8Szrj 			 * Propagate changes only to the unlibedit_private
105132fe07f8SJohn Marino 			 * chars that have been modified just now.
105232fe07f8SJohn Marino 			 */
105384b940c1SJohn Marino 			for (i = 0; i < C_NCC; i++)
105484b940c1SJohn Marino 				tty_update_char(el, ED_IO, i);
105584b940c1SJohn Marino 
105632fe07f8SJohn Marino 			tty_bind_char(el, 0);
105732fe07f8SJohn Marino 			tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
105832fe07f8SJohn Marino 
105984b940c1SJohn Marino 			for (i = 0; i < C_NCC; i++)
106084b940c1SJohn Marino 				tty_update_char(el, EX_IO, i);
106184b940c1SJohn Marino 
106232fe07f8SJohn Marino 			tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
106332fe07f8SJohn Marino 		}
106432fe07f8SJohn Marino 	}
106532fe07f8SJohn Marino 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
106632fe07f8SJohn Marino #ifdef DEBUG_TTY
1067c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
106832fe07f8SJohn Marino 		    strerror(errno));
106932fe07f8SJohn Marino #endif /* DEBUG_TTY */
107032fe07f8SJohn Marino 		return -1;
107132fe07f8SJohn Marino 	}
107232fe07f8SJohn Marino 	el->el_tty.t_mode = ED_IO;
107332fe07f8SJohn Marino 	return 0;
107432fe07f8SJohn Marino }
107532fe07f8SJohn Marino 
107632fe07f8SJohn Marino 
107732fe07f8SJohn Marino /* tty_cookedmode():
107832fe07f8SJohn Marino  *	Set the tty back to normal mode
107932fe07f8SJohn Marino  */
108012db70c8Szrj libedit_private int
tty_cookedmode(EditLine * el)108132fe07f8SJohn Marino tty_cookedmode(EditLine *el)
108232fe07f8SJohn Marino {				/* set tty in normal setup */
108332fe07f8SJohn Marino 
108432fe07f8SJohn Marino 	if (el->el_tty.t_mode == EX_IO)
108532fe07f8SJohn Marino 		return 0;
108632fe07f8SJohn Marino 
108732fe07f8SJohn Marino 	if (el->el_flags & EDIT_DISABLED)
108832fe07f8SJohn Marino 		return 0;
108932fe07f8SJohn Marino 
109032fe07f8SJohn Marino 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
109132fe07f8SJohn Marino #ifdef DEBUG_TTY
1092c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
109332fe07f8SJohn Marino 		    strerror(errno));
109432fe07f8SJohn Marino #endif /* DEBUG_TTY */
109532fe07f8SJohn Marino 		return -1;
109632fe07f8SJohn Marino 	}
109732fe07f8SJohn Marino 	el->el_tty.t_mode = EX_IO;
109832fe07f8SJohn Marino 	return 0;
109932fe07f8SJohn Marino }
110032fe07f8SJohn Marino 
110132fe07f8SJohn Marino 
110232fe07f8SJohn Marino /* tty_quotemode():
110332fe07f8SJohn Marino  *	Turn on quote mode
110432fe07f8SJohn Marino  */
110512db70c8Szrj libedit_private int
tty_quotemode(EditLine * el)110632fe07f8SJohn Marino tty_quotemode(EditLine *el)
110732fe07f8SJohn Marino {
110832fe07f8SJohn Marino 	if (el->el_tty.t_mode == QU_IO)
110932fe07f8SJohn Marino 		return 0;
111032fe07f8SJohn Marino 
111132fe07f8SJohn Marino 	el->el_tty.t_qu = el->el_tty.t_ed;
111232fe07f8SJohn Marino 
111384b940c1SJohn Marino 	tty_setup_flags(el, &el->el_tty.t_qu, QU_IO);
111432fe07f8SJohn Marino 
111532fe07f8SJohn Marino 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
111632fe07f8SJohn Marino #ifdef DEBUG_TTY
1117c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
111832fe07f8SJohn Marino 		    strerror(errno));
111932fe07f8SJohn Marino #endif /* DEBUG_TTY */
112032fe07f8SJohn Marino 		return -1;
112132fe07f8SJohn Marino 	}
112232fe07f8SJohn Marino 	el->el_tty.t_mode = QU_IO;
112332fe07f8SJohn Marino 	return 0;
112432fe07f8SJohn Marino }
112532fe07f8SJohn Marino 
112632fe07f8SJohn Marino 
112732fe07f8SJohn Marino /* tty_noquotemode():
112832fe07f8SJohn Marino  *	Turn off quote mode
112932fe07f8SJohn Marino  */
113012db70c8Szrj libedit_private int
tty_noquotemode(EditLine * el)113132fe07f8SJohn Marino tty_noquotemode(EditLine *el)
113232fe07f8SJohn Marino {
113332fe07f8SJohn Marino 
113432fe07f8SJohn Marino 	if (el->el_tty.t_mode != QU_IO)
113532fe07f8SJohn Marino 		return 0;
113632fe07f8SJohn Marino 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
113732fe07f8SJohn Marino #ifdef DEBUG_TTY
1138c8e4d2bfSJohn Marino 		(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
113932fe07f8SJohn Marino 		    strerror(errno));
114032fe07f8SJohn Marino #endif /* DEBUG_TTY */
114132fe07f8SJohn Marino 		return -1;
114232fe07f8SJohn Marino 	}
114332fe07f8SJohn Marino 	el->el_tty.t_mode = ED_IO;
114432fe07f8SJohn Marino 	return 0;
114532fe07f8SJohn Marino }
114632fe07f8SJohn Marino 
114732fe07f8SJohn Marino 
114832fe07f8SJohn Marino /* tty_stty():
114932fe07f8SJohn Marino  *	Stty builtin
115032fe07f8SJohn Marino  */
115112db70c8Szrj libedit_private int
115232fe07f8SJohn Marino /*ARGSUSED*/
tty_stty(EditLine * el,int argc,const wchar_t ** argv)115312db70c8Szrj tty_stty(EditLine *el, int argc __attribute__((__unused__)),
115412db70c8Szrj     const wchar_t **argv)
115532fe07f8SJohn Marino {
115632fe07f8SJohn Marino 	const ttymodes_t *m;
115732fe07f8SJohn Marino 	char x;
115832fe07f8SJohn Marino 	int aflag = 0;
115912db70c8Szrj 	const wchar_t *s, *d;
116032fe07f8SJohn Marino         char name[EL_BUFSIZ];
116132fe07f8SJohn Marino 	struct termios *tios = &el->el_tty.t_ex;
116232fe07f8SJohn Marino 	int z = EX_IO;
116332fe07f8SJohn Marino 
116432fe07f8SJohn Marino 	if (argv == NULL)
116532fe07f8SJohn Marino 		return -1;
1166*cdf8408cSAntonio Huete Jimenez 	strlcpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
116732fe07f8SJohn Marino 
116832fe07f8SJohn Marino 	while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
116932fe07f8SJohn Marino 		switch (argv[0][1]) {
117032fe07f8SJohn Marino 		case 'a':
117132fe07f8SJohn Marino 			aflag++;
117232fe07f8SJohn Marino 			argv++;
117332fe07f8SJohn Marino 			break;
117432fe07f8SJohn Marino 		case 'd':
117532fe07f8SJohn Marino 			argv++;
117632fe07f8SJohn Marino 			tios = &el->el_tty.t_ed;
117732fe07f8SJohn Marino 			z = ED_IO;
117832fe07f8SJohn Marino 			break;
117932fe07f8SJohn Marino 		case 'x':
118032fe07f8SJohn Marino 			argv++;
118132fe07f8SJohn Marino 			tios = &el->el_tty.t_ex;
118232fe07f8SJohn Marino 			z = EX_IO;
118332fe07f8SJohn Marino 			break;
118432fe07f8SJohn Marino 		case 'q':
118532fe07f8SJohn Marino 			argv++;
118632fe07f8SJohn Marino 			tios = &el->el_tty.t_ts;
118732fe07f8SJohn Marino 			z = QU_IO;
118832fe07f8SJohn Marino 			break;
118932fe07f8SJohn Marino 		default:
119032fe07f8SJohn Marino 			(void) fprintf(el->el_errfile,
119112db70c8Szrj 			    "%s: Unknown switch `%lc'.\n",
119212db70c8Szrj 			    name, (wint_t)argv[0][1]);
119332fe07f8SJohn Marino 			return -1;
119432fe07f8SJohn Marino 		}
119532fe07f8SJohn Marino 
119632fe07f8SJohn Marino 	if (!argv || !*argv) {
119732fe07f8SJohn Marino 		int i = -1;
119832fe07f8SJohn Marino 		size_t len = 0, st = 0, cu;
119932fe07f8SJohn Marino 		for (m = ttymodes; m->m_name; m++) {
120032fe07f8SJohn Marino 			if (m->m_type != i) {
120132fe07f8SJohn Marino 				(void) fprintf(el->el_outfile, "%s%s",
120232fe07f8SJohn Marino 				    i != -1 ? "\n" : "",
120332fe07f8SJohn Marino 				    el->el_tty.t_t[z][m->m_type].t_name);
120432fe07f8SJohn Marino 				i = m->m_type;
120532fe07f8SJohn Marino 				st = len =
120632fe07f8SJohn Marino 				    strlen(el->el_tty.t_t[z][m->m_type].t_name);
120732fe07f8SJohn Marino 			}
120832fe07f8SJohn Marino 			if (i != -1) {
120932fe07f8SJohn Marino 			    x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
121032fe07f8SJohn Marino 				?  '+' : '\0';
121132fe07f8SJohn Marino 
121232fe07f8SJohn Marino 			    if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
121332fe07f8SJohn Marino 				x = '-';
121432fe07f8SJohn Marino 			} else {
121532fe07f8SJohn Marino 			    x = '\0';
121632fe07f8SJohn Marino 			}
121732fe07f8SJohn Marino 
121832fe07f8SJohn Marino 			if (x != '\0' || aflag) {
121932fe07f8SJohn Marino 
122032fe07f8SJohn Marino 				cu = strlen(m->m_name) + (x != '\0') + 1;
122132fe07f8SJohn Marino 
1222c8e4d2bfSJohn Marino 				if (len + cu >=
1223c8e4d2bfSJohn Marino 				    (size_t)el->el_terminal.t_size.h) {
122432fe07f8SJohn Marino 					(void) fprintf(el->el_outfile, "\n%*s",
122532fe07f8SJohn Marino 					    (int)st, "");
122632fe07f8SJohn Marino 					len = st + cu;
122732fe07f8SJohn Marino 				} else
122832fe07f8SJohn Marino 					len += cu;
122932fe07f8SJohn Marino 
123032fe07f8SJohn Marino 				if (x != '\0')
123132fe07f8SJohn Marino 					(void) fprintf(el->el_outfile, "%c%s ",
123232fe07f8SJohn Marino 					    x, m->m_name);
123332fe07f8SJohn Marino 				else
123432fe07f8SJohn Marino 					(void) fprintf(el->el_outfile, "%s ",
123532fe07f8SJohn Marino 					    m->m_name);
123632fe07f8SJohn Marino 			}
123732fe07f8SJohn Marino 		}
123832fe07f8SJohn Marino 		(void) fprintf(el->el_outfile, "\n");
123932fe07f8SJohn Marino 		return 0;
124032fe07f8SJohn Marino 	}
124132fe07f8SJohn Marino 	while (argv && (s = *argv++)) {
124212db70c8Szrj 		const wchar_t *p;
124332fe07f8SJohn Marino 		switch (*s) {
124432fe07f8SJohn Marino 		case '+':
124532fe07f8SJohn Marino 		case '-':
124632fe07f8SJohn Marino 			x = (char)*s++;
124732fe07f8SJohn Marino 			break;
124832fe07f8SJohn Marino 		default:
124932fe07f8SJohn Marino 			x = '\0';
125032fe07f8SJohn Marino 			break;
125132fe07f8SJohn Marino 		}
125232fe07f8SJohn Marino 		d = s;
125312db70c8Szrj 		p = wcschr(s, L'=');
125432fe07f8SJohn Marino 		for (m = ttymodes; m->m_name; m++)
1255c8e4d2bfSJohn Marino 			if ((p ? strncmp(m->m_name, ct_encode_string(d,
1256c8e4d2bfSJohn Marino 			    &el->el_scratch), (size_t)(p - d)) :
1257c8e4d2bfSJohn Marino 			    strcmp(m->m_name, ct_encode_string(d,
1258c8e4d2bfSJohn Marino 			    &el->el_scratch))) == 0 &&
125932fe07f8SJohn Marino 			    (p == NULL || m->m_type == MD_CHAR))
126032fe07f8SJohn Marino 				break;
126132fe07f8SJohn Marino 
126232fe07f8SJohn Marino 		if (!m->m_name) {
126332fe07f8SJohn Marino 			(void) fprintf(el->el_errfile,
126412db70c8Szrj 			    "%s: Invalid argument `%ls'.\n", name, d);
126532fe07f8SJohn Marino 			return -1;
126632fe07f8SJohn Marino 		}
126732fe07f8SJohn Marino 		if (p) {
126832fe07f8SJohn Marino 			int c = ffs((int)m->m_value);
126932fe07f8SJohn Marino 			int v = *++p ? parse__escape(&p) :
127032fe07f8SJohn Marino 			    el->el_tty.t_vdisable;
127132fe07f8SJohn Marino 			assert(c != 0);
127232fe07f8SJohn Marino 			c--;
127332fe07f8SJohn Marino 			c = tty__getcharindex(c);
127432fe07f8SJohn Marino 			assert(c != -1);
127532fe07f8SJohn Marino 			tios->c_cc[c] = (cc_t)v;
127632fe07f8SJohn Marino 			continue;
127732fe07f8SJohn Marino 		}
127832fe07f8SJohn Marino 		switch (x) {
127932fe07f8SJohn Marino 		case '+':
128032fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
128132fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
128232fe07f8SJohn Marino 			break;
128332fe07f8SJohn Marino 		case '-':
128432fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
128532fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
128632fe07f8SJohn Marino 			break;
128732fe07f8SJohn Marino 		default:
128832fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
128932fe07f8SJohn Marino 			el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
129032fe07f8SJohn Marino 			break;
129132fe07f8SJohn Marino 		}
129232fe07f8SJohn Marino 	}
129332fe07f8SJohn Marino 
129484b940c1SJohn Marino 	tty_setup_flags(el, tios, z);
129532fe07f8SJohn Marino 	if (el->el_tty.t_mode == z) {
129632fe07f8SJohn Marino 		if (tty_setty(el, TCSADRAIN, tios) == -1) {
129732fe07f8SJohn Marino #ifdef DEBUG_TTY
1298c8e4d2bfSJohn Marino 			(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
1299c8e4d2bfSJohn Marino 			    __func__, strerror(errno));
130032fe07f8SJohn Marino #endif /* DEBUG_TTY */
130132fe07f8SJohn Marino 			return -1;
130232fe07f8SJohn Marino 		}
130332fe07f8SJohn Marino 	}
130432fe07f8SJohn Marino 
130532fe07f8SJohn Marino 	return 0;
130632fe07f8SJohn Marino }
130732fe07f8SJohn Marino 
130832fe07f8SJohn Marino 
130932fe07f8SJohn Marino #ifdef notyet
131032fe07f8SJohn Marino /* tty_printchar():
131132fe07f8SJohn Marino  *	DEbugging routine to print the tty characters
131232fe07f8SJohn Marino  */
131312db70c8Szrj static void
tty_printchar(EditLine * el,unsigned char * s)131432fe07f8SJohn Marino tty_printchar(EditLine *el, unsigned char *s)
131532fe07f8SJohn Marino {
131632fe07f8SJohn Marino 	ttyperm_t *m;
131732fe07f8SJohn Marino 	int i;
131832fe07f8SJohn Marino 
131932fe07f8SJohn Marino 	for (i = 0; i < C_NCC; i++) {
132032fe07f8SJohn Marino 		for (m = el->el_tty.t_t; m->m_name; m++)
132132fe07f8SJohn Marino 			if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
132232fe07f8SJohn Marino 				break;
132332fe07f8SJohn Marino 		if (m->m_name)
132432fe07f8SJohn Marino 			(void) fprintf(el->el_errfile, "%s ^%c ",
132532fe07f8SJohn Marino 			    m->m_name, s[i] + 'A' - 1);
132632fe07f8SJohn Marino 		if (i % 5 == 0)
132732fe07f8SJohn Marino 			(void) fprintf(el->el_errfile, "\n");
132832fe07f8SJohn Marino 	}
132932fe07f8SJohn Marino 	(void) fprintf(el->el_errfile, "\n");
133032fe07f8SJohn Marino }
133132fe07f8SJohn Marino #endif /* notyet */
133284b940c1SJohn Marino 
133384b940c1SJohn Marino 
133412db70c8Szrj static void
tty_setup_flags(EditLine * el,struct termios * tios,int mode)133584b940c1SJohn Marino tty_setup_flags(EditLine *el, struct termios *tios, int mode)
133684b940c1SJohn Marino {
133784b940c1SJohn Marino 	int kind;
133884b940c1SJohn Marino 	for (kind = MD_INP; kind <= MD_LIN; kind++) {
133984b940c1SJohn Marino 		tcflag_t *f = tty__get_flag(tios, kind);
134084b940c1SJohn Marino 		*f = tty_update_flag(el, *f, mode, kind);
134184b940c1SJohn Marino 	}
134284b940c1SJohn Marino }
1343ae19eda8Szrj 
1344ae19eda8Szrj libedit_private int
tty_get_signal_character(EditLine * el,int sig)1345ae19eda8Szrj tty_get_signal_character(EditLine *el, int sig)
1346ae19eda8Szrj {
1347ae19eda8Szrj #ifdef ECHOCTL
1348ae19eda8Szrj 	tcflag_t *ed = tty__get_flag(&el->el_tty.t_ed, MD_INP);
1349ae19eda8Szrj 	if ((*ed & ECHOCTL) == 0)
1350ae19eda8Szrj 		return -1;
1351ae19eda8Szrj #endif
1352ae19eda8Szrj 	switch (sig) {
1353*cdf8408cSAntonio Huete Jimenez #if defined(SIGINT) && defined(VINTR)
1354ae19eda8Szrj 	case SIGINT:
1355ae19eda8Szrj 		return el->el_tty.t_c[ED_IO][VINTR];
1356ae19eda8Szrj #endif
1357*cdf8408cSAntonio Huete Jimenez #if defined(SIGQUIT) && defined(VQUIT)
1358ae19eda8Szrj 	case SIGQUIT:
1359ae19eda8Szrj 		return el->el_tty.t_c[ED_IO][VQUIT];
1360ae19eda8Szrj #endif
1361*cdf8408cSAntonio Huete Jimenez #if defined(SIGINFO) && defined(VSTATUS)
1362ae19eda8Szrj 	case SIGINFO:
1363ae19eda8Szrj 		return el->el_tty.t_c[ED_IO][VSTATUS];
1364ae19eda8Szrj #endif
1365*cdf8408cSAntonio Huete Jimenez #if defined(SIGTSTP) && defined(VSUSP)
1366ae19eda8Szrj 	case SIGTSTP:
1367ae19eda8Szrj 		return el->el_tty.t_c[ED_IO][VSUSP];
1368ae19eda8Szrj #endif
1369ae19eda8Szrj 	default:
1370ae19eda8Szrj 		return -1;
1371ae19eda8Szrj 	}
1372ae19eda8Szrj }
1373