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