1*5b133f3fSguenther /* $OpenBSD: tty.c,v 1.28 2023/03/08 04:43:05 guenther Exp $ */
25f805b19Sokan /* $NetBSD: tty.c,v 1.34 2011/01/27 23:11:40 christos Exp $ */
3babb851aSmillert
4df930be7Sderaadt /*-
5df930be7Sderaadt * Copyright (c) 1992, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt * Christos Zoulas of Cornell University.
10df930be7Sderaadt *
11df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt * modification, are permitted provided that the following conditions
13df930be7Sderaadt * are met:
14df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt * documentation and/or other materials provided with the distribution.
196580fee3Smillert * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt * may be used to endorse or promote products derived from this software
21df930be7Sderaadt * without specific prior written permission.
22df930be7Sderaadt *
23df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt * SUCH DAMAGE.
34df930be7Sderaadt */
35df930be7Sderaadt
36d484b7d0Sotto #include "config.h"
37df930be7Sderaadt
38df930be7Sderaadt /*
39df930be7Sderaadt * tty.c: tty interface stuff
40df930be7Sderaadt */
41aed0ee81Snicm #include <assert.h>
42aed0ee81Snicm #include <errno.h>
437ccfa089Sschwarze #include <stdlib.h> /* for abort */
447ccfa089Sschwarze #include <string.h>
45aed0ee81Snicm #include <strings.h> /* for ffs */
467ccfa089Sschwarze #include <unistd.h> /* for isatty */
475564fb94Sschwarze
48df930be7Sderaadt #include "el.h"
4913e01c7aSschwarze #include "fcns.h"
505564fb94Sschwarze #include "parse.h"
51df930be7Sderaadt
52df930be7Sderaadt typedef struct ttymodes_t {
53d484b7d0Sotto const char *m_name;
54aed0ee81Snicm unsigned int m_value;
55df930be7Sderaadt int m_type;
56df930be7Sderaadt } ttymodes_t;
57df930be7Sderaadt
58df930be7Sderaadt typedef struct ttymap_t {
59b2589f0bSschwarze wint_t nch, och; /* Internal and termio rep of chars */
60df930be7Sderaadt el_action_t bind[3]; /* emacs, vi, and vi-cmd */
61df930be7Sderaadt } ttymap_t;
62df930be7Sderaadt
63df930be7Sderaadt
64ddc81437Sschwarze static const ttyperm_t ttyperm = {
65df930be7Sderaadt {
66df930be7Sderaadt {"iflag:", ICRNL, (INLCR | IGNCR)},
67df930be7Sderaadt {"oflag:", (OPOST | ONLCR), ONLRET},
68df930be7Sderaadt {"cflag:", 0, 0},
69df930be7Sderaadt {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
70df930be7Sderaadt (NOFLSH | ECHONL | EXTPROC | FLUSHO)},
71df930be7Sderaadt {"chars:", 0, 0},
72df930be7Sderaadt },
73df930be7Sderaadt {
74df930be7Sderaadt {"iflag:", (INLCR | ICRNL), IGNCR},
75df930be7Sderaadt {"oflag:", (OPOST | ONLCR), ONLRET},
76df930be7Sderaadt {"cflag:", 0, 0},
77df930be7Sderaadt {"lflag:", ISIG,
78df930be7Sderaadt (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
79df930be7Sderaadt {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
80df930be7Sderaadt C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
81df930be7Sderaadt C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
82df930be7Sderaadt },
83df930be7Sderaadt {
84d484b7d0Sotto {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
85df930be7Sderaadt {"oflag:", 0, 0},
86df930be7Sderaadt {"cflag:", 0, 0},
87df930be7Sderaadt {"lflag:", 0, ISIG | IEXTEN},
88df930be7Sderaadt {"chars:", 0, 0},
89df930be7Sderaadt }
90df930be7Sderaadt };
91df930be7Sderaadt
92ddc81437Sschwarze static const ttychar_t ttychar = {
93df930be7Sderaadt {
94df930be7Sderaadt CINTR, CQUIT, CERASE, CKILL,
95df930be7Sderaadt CEOF, CEOL, CEOL2, CSWTCH,
96df930be7Sderaadt CDSWTCH, CERASE2, CSTART, CSTOP,
97df930be7Sderaadt CWERASE, CSUSP, CDSUSP, CREPRINT,
98df930be7Sderaadt CDISCARD, CLNEXT, CSTATUS, CPAGE,
99df930be7Sderaadt CPGOFF, CKILL2, CBRK, CMIN,
100df930be7Sderaadt CTIME
101df930be7Sderaadt },
102df930be7Sderaadt {
103df930be7Sderaadt CINTR, CQUIT, CERASE, CKILL,
104df930be7Sderaadt _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
105df930be7Sderaadt _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
106df930be7Sderaadt _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
107df930be7Sderaadt CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
108df930be7Sderaadt _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
109df930be7Sderaadt 0
110df930be7Sderaadt },
111df930be7Sderaadt {
112df930be7Sderaadt 0, 0, 0, 0,
113df930be7Sderaadt 0, 0, 0, 0,
114df930be7Sderaadt 0, 0, 0, 0,
115df930be7Sderaadt 0, 0, 0, 0,
116df930be7Sderaadt 0, 0, 0, 0,
117df930be7Sderaadt 0, 0, 0, 0,
118df930be7Sderaadt 0
119df930be7Sderaadt }
120df930be7Sderaadt };
121df930be7Sderaadt
122ddc81437Sschwarze static const ttymap_t tty_map[] = {
123df930be7Sderaadt #ifdef VERASE
124df930be7Sderaadt {C_ERASE, VERASE,
125aed0ee81Snicm {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
126df930be7Sderaadt #endif /* VERASE */
127df930be7Sderaadt #ifdef VERASE2
128df930be7Sderaadt {C_ERASE2, VERASE2,
129aed0ee81Snicm {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
130df930be7Sderaadt #endif /* VERASE2 */
131df930be7Sderaadt #ifdef VKILL
132df930be7Sderaadt {C_KILL, VKILL,
133df930be7Sderaadt {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
134df930be7Sderaadt #endif /* VKILL */
135df930be7Sderaadt #ifdef VKILL2
136df930be7Sderaadt {C_KILL2, VKILL2,
137df930be7Sderaadt {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
138df930be7Sderaadt #endif /* VKILL2 */
139df930be7Sderaadt #ifdef VEOF
140df930be7Sderaadt {C_EOF, VEOF,
141df930be7Sderaadt {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
142df930be7Sderaadt #endif /* VEOF */
143df930be7Sderaadt #ifdef VWERASE
144df930be7Sderaadt {C_WERASE, VWERASE,
145df930be7Sderaadt {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
146df930be7Sderaadt #endif /* VWERASE */
147df930be7Sderaadt #ifdef VREPRINT
148df930be7Sderaadt {C_REPRINT, VREPRINT,
149df930be7Sderaadt {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
150df930be7Sderaadt #endif /* VREPRINT */
151df930be7Sderaadt #ifdef VLNEXT
152df930be7Sderaadt {C_LNEXT, VLNEXT,
153df930be7Sderaadt {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
154df930be7Sderaadt #endif /* VLNEXT */
155b2589f0bSschwarze {(wint_t)-1, (wint_t)-1,
156df930be7Sderaadt {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
157df930be7Sderaadt };
158df930be7Sderaadt
159ddc81437Sschwarze static const ttymodes_t ttymodes[] = {
160df930be7Sderaadt #ifdef IGNBRK
161d484b7d0Sotto {"ignbrk", IGNBRK, MD_INP},
162df930be7Sderaadt #endif /* IGNBRK */
163df930be7Sderaadt #ifdef BRKINT
164d484b7d0Sotto {"brkint", BRKINT, MD_INP},
165df930be7Sderaadt #endif /* BRKINT */
166df930be7Sderaadt #ifdef IGNPAR
167d484b7d0Sotto {"ignpar", IGNPAR, MD_INP},
168df930be7Sderaadt #endif /* IGNPAR */
169df930be7Sderaadt #ifdef PARMRK
170d484b7d0Sotto {"parmrk", PARMRK, MD_INP},
171df930be7Sderaadt #endif /* PARMRK */
172df930be7Sderaadt #ifdef INPCK
173d484b7d0Sotto {"inpck", INPCK, MD_INP},
174df930be7Sderaadt #endif /* INPCK */
175df930be7Sderaadt #ifdef ISTRIP
176d484b7d0Sotto {"istrip", ISTRIP, MD_INP},
177df930be7Sderaadt #endif /* ISTRIP */
178df930be7Sderaadt #ifdef INLCR
179d484b7d0Sotto {"inlcr", INLCR, MD_INP},
180df930be7Sderaadt #endif /* INLCR */
181df930be7Sderaadt #ifdef IGNCR
182d484b7d0Sotto {"igncr", IGNCR, MD_INP},
183df930be7Sderaadt #endif /* IGNCR */
184df930be7Sderaadt #ifdef ICRNL
185d484b7d0Sotto {"icrnl", ICRNL, MD_INP},
186df930be7Sderaadt #endif /* ICRNL */
187df930be7Sderaadt #ifdef IUCLC
188d484b7d0Sotto {"iuclc", IUCLC, MD_INP},
189df930be7Sderaadt #endif /* IUCLC */
190df930be7Sderaadt #ifdef IXON
191d484b7d0Sotto {"ixon", IXON, MD_INP},
192df930be7Sderaadt #endif /* IXON */
193df930be7Sderaadt #ifdef IXANY
194d484b7d0Sotto {"ixany", IXANY, MD_INP},
195df930be7Sderaadt #endif /* IXANY */
196df930be7Sderaadt #ifdef IXOFF
197d484b7d0Sotto {"ixoff", IXOFF, MD_INP},
198df930be7Sderaadt #endif /* IXOFF */
199df930be7Sderaadt #ifdef IMAXBEL
200d484b7d0Sotto {"imaxbel", IMAXBEL, MD_INP},
201df930be7Sderaadt #endif /* IMAXBEL */
202df930be7Sderaadt
203df930be7Sderaadt #ifdef OPOST
204d484b7d0Sotto {"opost", OPOST, MD_OUT},
205df930be7Sderaadt #endif /* OPOST */
206df930be7Sderaadt #ifdef OLCUC
207d484b7d0Sotto {"olcuc", OLCUC, MD_OUT},
208df930be7Sderaadt #endif /* OLCUC */
209df930be7Sderaadt #ifdef ONLCR
210d484b7d0Sotto {"onlcr", ONLCR, MD_OUT},
211df930be7Sderaadt #endif /* ONLCR */
212df930be7Sderaadt #ifdef OCRNL
213d484b7d0Sotto {"ocrnl", OCRNL, MD_OUT},
214df930be7Sderaadt #endif /* OCRNL */
215df930be7Sderaadt #ifdef ONOCR
216d484b7d0Sotto {"onocr", ONOCR, MD_OUT},
217df930be7Sderaadt #endif /* ONOCR */
218df930be7Sderaadt #ifdef ONOEOT
219d484b7d0Sotto {"onoeot", ONOEOT, MD_OUT},
220df930be7Sderaadt #endif /* ONOEOT */
221df930be7Sderaadt #ifdef ONLRET
222d484b7d0Sotto {"onlret", ONLRET, MD_OUT},
223df930be7Sderaadt #endif /* ONLRET */
224df930be7Sderaadt #ifdef OFILL
225d484b7d0Sotto {"ofill", OFILL, MD_OUT},
226df930be7Sderaadt #endif /* OFILL */
227df930be7Sderaadt #ifdef OFDEL
228d484b7d0Sotto {"ofdel", OFDEL, MD_OUT},
229df930be7Sderaadt #endif /* OFDEL */
230df930be7Sderaadt #ifdef NLDLY
231d484b7d0Sotto {"nldly", NLDLY, MD_OUT},
232df930be7Sderaadt #endif /* NLDLY */
233df930be7Sderaadt #ifdef CRDLY
234d484b7d0Sotto {"crdly", CRDLY, MD_OUT},
235df930be7Sderaadt #endif /* CRDLY */
236df930be7Sderaadt #ifdef TABDLY
237d484b7d0Sotto {"tabdly", TABDLY, MD_OUT},
238df930be7Sderaadt #endif /* TABDLY */
239df930be7Sderaadt #ifdef XTABS
240d484b7d0Sotto {"xtabs", XTABS, MD_OUT},
241df930be7Sderaadt #endif /* XTABS */
242df930be7Sderaadt #ifdef BSDLY
243d484b7d0Sotto {"bsdly", BSDLY, MD_OUT},
244df930be7Sderaadt #endif /* BSDLY */
245df930be7Sderaadt #ifdef VTDLY
246d484b7d0Sotto {"vtdly", VTDLY, MD_OUT},
247df930be7Sderaadt #endif /* VTDLY */
248df930be7Sderaadt #ifdef FFDLY
249d484b7d0Sotto {"ffdly", FFDLY, MD_OUT},
250df930be7Sderaadt #endif /* FFDLY */
251df930be7Sderaadt #ifdef PAGEOUT
252d484b7d0Sotto {"pageout", PAGEOUT, MD_OUT},
253df930be7Sderaadt #endif /* PAGEOUT */
254df930be7Sderaadt #ifdef WRAP
255d484b7d0Sotto {"wrap", WRAP, MD_OUT},
256df930be7Sderaadt #endif /* WRAP */
257df930be7Sderaadt
258df930be7Sderaadt #ifdef CIGNORE
259d484b7d0Sotto {"cignore", CIGNORE, MD_CTL},
260df930be7Sderaadt #endif /* CBAUD */
261df930be7Sderaadt #ifdef CBAUD
262d484b7d0Sotto {"cbaud", CBAUD, MD_CTL},
263df930be7Sderaadt #endif /* CBAUD */
264df930be7Sderaadt #ifdef CSTOPB
265d484b7d0Sotto {"cstopb", CSTOPB, MD_CTL},
266df930be7Sderaadt #endif /* CSTOPB */
267df930be7Sderaadt #ifdef CREAD
268d484b7d0Sotto {"cread", CREAD, MD_CTL},
269df930be7Sderaadt #endif /* CREAD */
270df930be7Sderaadt #ifdef PARENB
271d484b7d0Sotto {"parenb", PARENB, MD_CTL},
272df930be7Sderaadt #endif /* PARENB */
273df930be7Sderaadt #ifdef PARODD
274d484b7d0Sotto {"parodd", PARODD, MD_CTL},
275df930be7Sderaadt #endif /* PARODD */
276df930be7Sderaadt #ifdef HUPCL
277d484b7d0Sotto {"hupcl", HUPCL, MD_CTL},
278df930be7Sderaadt #endif /* HUPCL */
279df930be7Sderaadt #ifdef CLOCAL
280d484b7d0Sotto {"clocal", CLOCAL, MD_CTL},
281df930be7Sderaadt #endif /* CLOCAL */
282df930be7Sderaadt #ifdef LOBLK
283d484b7d0Sotto {"loblk", LOBLK, MD_CTL},
284df930be7Sderaadt #endif /* LOBLK */
285df930be7Sderaadt #ifdef CIBAUD
286d484b7d0Sotto {"cibaud", CIBAUD, MD_CTL},
287df930be7Sderaadt #endif /* CIBAUD */
288df930be7Sderaadt #ifdef CRTSCTS
289df930be7Sderaadt #ifdef CCTS_OFLOW
290d484b7d0Sotto {"ccts_oflow", CCTS_OFLOW, MD_CTL},
291df930be7Sderaadt #else
292d484b7d0Sotto {"crtscts", CRTSCTS, MD_CTL},
293df930be7Sderaadt #endif /* CCTS_OFLOW */
294df930be7Sderaadt #endif /* CRTSCTS */
295df930be7Sderaadt #ifdef CRTS_IFLOW
296d484b7d0Sotto {"crts_iflow", CRTS_IFLOW, MD_CTL},
297df930be7Sderaadt #endif /* CRTS_IFLOW */
298d484b7d0Sotto #ifdef CDTRCTS
299d484b7d0Sotto {"cdtrcts", CDTRCTS, MD_CTL},
300d484b7d0Sotto #endif /* CDTRCTS */
301df930be7Sderaadt #ifdef MDMBUF
302d484b7d0Sotto {"mdmbuf", MDMBUF, MD_CTL},
303df930be7Sderaadt #endif /* MDMBUF */
304df930be7Sderaadt #ifdef RCV1EN
305d484b7d0Sotto {"rcv1en", RCV1EN, MD_CTL},
306df930be7Sderaadt #endif /* RCV1EN */
307df930be7Sderaadt #ifdef XMT1EN
308d484b7d0Sotto {"xmt1en", XMT1EN, MD_CTL},
309df930be7Sderaadt #endif /* XMT1EN */
310df930be7Sderaadt
311df930be7Sderaadt #ifdef ISIG
312d484b7d0Sotto {"isig", ISIG, MD_LIN},
313df930be7Sderaadt #endif /* ISIG */
314df930be7Sderaadt #ifdef ICANON
315d484b7d0Sotto {"icanon", ICANON, MD_LIN},
316df930be7Sderaadt #endif /* ICANON */
317df930be7Sderaadt #ifdef XCASE
318d484b7d0Sotto {"xcase", XCASE, MD_LIN},
319df930be7Sderaadt #endif /* XCASE */
320df930be7Sderaadt #ifdef ECHO
321d484b7d0Sotto {"echo", ECHO, MD_LIN},
322df930be7Sderaadt #endif /* ECHO */
323df930be7Sderaadt #ifdef ECHOE
324d484b7d0Sotto {"echoe", ECHOE, MD_LIN},
325df930be7Sderaadt #endif /* ECHOE */
326df930be7Sderaadt #ifdef ECHOK
327d484b7d0Sotto {"echok", ECHOK, MD_LIN},
328df930be7Sderaadt #endif /* ECHOK */
329df930be7Sderaadt #ifdef ECHONL
330d484b7d0Sotto {"echonl", ECHONL, MD_LIN},
331df930be7Sderaadt #endif /* ECHONL */
332df930be7Sderaadt #ifdef NOFLSH
333d484b7d0Sotto {"noflsh", NOFLSH, MD_LIN},
334df930be7Sderaadt #endif /* NOFLSH */
335df930be7Sderaadt #ifdef TOSTOP
336d484b7d0Sotto {"tostop", TOSTOP, MD_LIN},
337df930be7Sderaadt #endif /* TOSTOP */
338df930be7Sderaadt #ifdef ECHOCTL
339d484b7d0Sotto {"echoctl", ECHOCTL, MD_LIN},
340df930be7Sderaadt #endif /* ECHOCTL */
341df930be7Sderaadt #ifdef ECHOPRT
342d484b7d0Sotto {"echoprt", ECHOPRT, MD_LIN},
343df930be7Sderaadt #endif /* ECHOPRT */
344df930be7Sderaadt #ifdef ECHOKE
345d484b7d0Sotto {"echoke", ECHOKE, MD_LIN},
346df930be7Sderaadt #endif /* ECHOKE */
347df930be7Sderaadt #ifdef DEFECHO
348d484b7d0Sotto {"defecho", DEFECHO, MD_LIN},
349df930be7Sderaadt #endif /* DEFECHO */
350df930be7Sderaadt #ifdef FLUSHO
351d484b7d0Sotto {"flusho", FLUSHO, MD_LIN},
352df930be7Sderaadt #endif /* FLUSHO */
353df930be7Sderaadt #ifdef PENDIN
354d484b7d0Sotto {"pendin", PENDIN, MD_LIN},
355df930be7Sderaadt #endif /* PENDIN */
356df930be7Sderaadt #ifdef IEXTEN
357d484b7d0Sotto {"iexten", IEXTEN, MD_LIN},
358df930be7Sderaadt #endif /* IEXTEN */
359df930be7Sderaadt #ifdef NOKERNINFO
360d484b7d0Sotto {"nokerninfo", NOKERNINFO, MD_LIN},
361df930be7Sderaadt #endif /* NOKERNINFO */
362df930be7Sderaadt #ifdef ALTWERASE
363d484b7d0Sotto {"altwerase", ALTWERASE, MD_LIN},
364df930be7Sderaadt #endif /* ALTWERASE */
365df930be7Sderaadt #ifdef EXTPROC
366d484b7d0Sotto {"extproc", EXTPROC, MD_LIN},
367df930be7Sderaadt #endif /* EXTPROC */
368df930be7Sderaadt
369df930be7Sderaadt #if defined(VINTR)
370d484b7d0Sotto {"intr", C_SH(C_INTR), MD_CHAR},
371df930be7Sderaadt #endif /* VINTR */
372df930be7Sderaadt #if defined(VQUIT)
373d484b7d0Sotto {"quit", C_SH(C_QUIT), MD_CHAR},
374df930be7Sderaadt #endif /* VQUIT */
375df930be7Sderaadt #if defined(VERASE)
376d484b7d0Sotto {"erase", C_SH(C_ERASE), MD_CHAR},
377df930be7Sderaadt #endif /* VERASE */
378df930be7Sderaadt #if defined(VKILL)
379d484b7d0Sotto {"kill", C_SH(C_KILL), MD_CHAR},
380df930be7Sderaadt #endif /* VKILL */
381df930be7Sderaadt #if defined(VEOF)
382d484b7d0Sotto {"eof", C_SH(C_EOF), MD_CHAR},
383df930be7Sderaadt #endif /* VEOF */
384df930be7Sderaadt #if defined(VEOL)
385d484b7d0Sotto {"eol", C_SH(C_EOL), MD_CHAR},
386df930be7Sderaadt #endif /* VEOL */
387df930be7Sderaadt #if defined(VEOL2)
388d484b7d0Sotto {"eol2", C_SH(C_EOL2), MD_CHAR},
389df930be7Sderaadt #endif /* VEOL2 */
390df930be7Sderaadt #if defined(VSWTCH)
391d484b7d0Sotto {"swtch", C_SH(C_SWTCH), MD_CHAR},
392df930be7Sderaadt #endif /* VSWTCH */
393df930be7Sderaadt #if defined(VDSWTCH)
394d484b7d0Sotto {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
395df930be7Sderaadt #endif /* VDSWTCH */
396df930be7Sderaadt #if defined(VERASE2)
397d484b7d0Sotto {"erase2", C_SH(C_ERASE2), MD_CHAR},
398df930be7Sderaadt #endif /* VERASE2 */
399df930be7Sderaadt #if defined(VSTART)
400d484b7d0Sotto {"start", C_SH(C_START), MD_CHAR},
401df930be7Sderaadt #endif /* VSTART */
402df930be7Sderaadt #if defined(VSTOP)
403d484b7d0Sotto {"stop", C_SH(C_STOP), MD_CHAR},
404df930be7Sderaadt #endif /* VSTOP */
405df930be7Sderaadt #if defined(VWERASE)
406d484b7d0Sotto {"werase", C_SH(C_WERASE), MD_CHAR},
407df930be7Sderaadt #endif /* VWERASE */
408df930be7Sderaadt #if defined(VSUSP)
409d484b7d0Sotto {"susp", C_SH(C_SUSP), MD_CHAR},
410df930be7Sderaadt #endif /* VSUSP */
411df930be7Sderaadt #if defined(VDSUSP)
412d484b7d0Sotto {"dsusp", C_SH(C_DSUSP), MD_CHAR},
413df930be7Sderaadt #endif /* VDSUSP */
414df930be7Sderaadt #if defined(VREPRINT)
415d484b7d0Sotto {"reprint", C_SH(C_REPRINT), MD_CHAR},
416df930be7Sderaadt #endif /* VREPRINT */
417df930be7Sderaadt #if defined(VDISCARD)
418d484b7d0Sotto {"discard", C_SH(C_DISCARD), MD_CHAR},
419df930be7Sderaadt #endif /* VDISCARD */
420df930be7Sderaadt #if defined(VLNEXT)
421d484b7d0Sotto {"lnext", C_SH(C_LNEXT), MD_CHAR},
422df930be7Sderaadt #endif /* VLNEXT */
423df930be7Sderaadt #if defined(VSTATUS)
424d484b7d0Sotto {"status", C_SH(C_STATUS), MD_CHAR},
425df930be7Sderaadt #endif /* VSTATUS */
426df930be7Sderaadt #if defined(VPAGE)
427d484b7d0Sotto {"page", C_SH(C_PAGE), MD_CHAR},
428df930be7Sderaadt #endif /* VPAGE */
429df930be7Sderaadt #if defined(VPGOFF)
430d484b7d0Sotto {"pgoff", C_SH(C_PGOFF), MD_CHAR},
431df930be7Sderaadt #endif /* VPGOFF */
432df930be7Sderaadt #if defined(VKILL2)
433d484b7d0Sotto {"kill2", C_SH(C_KILL2), MD_CHAR},
434df930be7Sderaadt #endif /* VKILL2 */
435df930be7Sderaadt #if defined(VBRK)
436d484b7d0Sotto {"brk", C_SH(C_BRK), MD_CHAR},
437df930be7Sderaadt #endif /* VBRK */
438df930be7Sderaadt #if defined(VMIN)
439d484b7d0Sotto {"min", C_SH(C_MIN), MD_CHAR},
440df930be7Sderaadt #endif /* VMIN */
441df930be7Sderaadt #if defined(VTIME)
442d484b7d0Sotto {"time", C_SH(C_TIME), MD_CHAR},
443df930be7Sderaadt #endif /* VTIME */
444df930be7Sderaadt {NULL, 0, -1},
445df930be7Sderaadt };
446df930be7Sderaadt
447df930be7Sderaadt
448df930be7Sderaadt
449df930be7Sderaadt #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
450df930be7Sderaadt #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
451df930be7Sderaadt #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
452df930be7Sderaadt
453ddc81437Sschwarze static int tty_getty(EditLine *, struct termios *);
454ddc81437Sschwarze static int tty_setty(EditLine *, int, const struct termios *);
455ddc81437Sschwarze static int tty__getcharindex(int);
456ddc81437Sschwarze static void tty__getchar(struct termios *, unsigned char *);
457ddc81437Sschwarze static void tty__setchar(struct termios *, unsigned char *);
458ddc81437Sschwarze static speed_t tty__getspeed(struct termios *);
459ddc81437Sschwarze static int tty_setup(EditLine *);
460ddc81437Sschwarze static void tty_setup_flags(EditLine *, struct termios *, int);
461df930be7Sderaadt
462df930be7Sderaadt #define t_qu t_ts
463df930be7Sderaadt
464aed0ee81Snicm /* tty_getty():
465aed0ee81Snicm * Wrapper for tcgetattr to handle EINTR
466aed0ee81Snicm */
467ddc81437Sschwarze static int
tty_getty(EditLine * el,struct termios * t)468aed0ee81Snicm tty_getty(EditLine *el, struct termios *t)
469aed0ee81Snicm {
470aed0ee81Snicm int rv;
471aed0ee81Snicm while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
472aed0ee81Snicm continue;
473aed0ee81Snicm return rv;
474aed0ee81Snicm }
475aed0ee81Snicm
476aed0ee81Snicm /* tty_setty():
477aed0ee81Snicm * Wrapper for tcsetattr to handle EINTR
478aed0ee81Snicm */
479ddc81437Sschwarze static int
tty_setty(EditLine * el,int action,const struct termios * t)480aed0ee81Snicm tty_setty(EditLine *el, int action, const struct termios *t)
481aed0ee81Snicm {
482aed0ee81Snicm int rv;
483aed0ee81Snicm while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
484aed0ee81Snicm continue;
485aed0ee81Snicm return rv;
486aed0ee81Snicm }
487df930be7Sderaadt
488df930be7Sderaadt /* tty_setup():
489df930be7Sderaadt * Get the tty parameters and initialize the editing state
490df930be7Sderaadt */
491ddc81437Sschwarze static int
tty_setup(EditLine * el)492d484b7d0Sotto tty_setup(EditLine *el)
493df930be7Sderaadt {
494df930be7Sderaadt int rst = 1;
495d484b7d0Sotto
496d484b7d0Sotto if (el->el_flags & EDIT_DISABLED)
49728d54ee8Sschwarze return 0;
498d484b7d0Sotto
499491df958Sschwarze if (el->el_tty.t_initialized)
500491df958Sschwarze return -1;
501491df958Sschwarze
5025f805b19Sokan if (!isatty(el->el_outfd)) {
5035f805b19Sokan #ifdef DEBUG_TTY
5045f805b19Sokan (void) fprintf(el->el_errfile,
5055f805b19Sokan "tty_setup: isatty: %s\n", strerror(errno));
5065f805b19Sokan #endif /* DEBUG_TTY */
50728d54ee8Sschwarze return -1;
5085f805b19Sokan }
509491df958Sschwarze if (tty_getty(el, &el->el_tty.t_or) == -1) {
510df930be7Sderaadt #ifdef DEBUG_TTY
511df930be7Sderaadt (void) fprintf(el->el_errfile,
512df930be7Sderaadt "tty_setup: tty_getty: %s\n", strerror(errno));
513df930be7Sderaadt #endif /* DEBUG_TTY */
51428d54ee8Sschwarze return -1;
515df930be7Sderaadt }
516491df958Sschwarze el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or;
517df930be7Sderaadt
518df930be7Sderaadt el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
519df930be7Sderaadt el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
520df930be7Sderaadt el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
521df930be7Sderaadt
5220d6dc0dbSyasuoka tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
523df930be7Sderaadt
524df930be7Sderaadt /*
525df930be7Sderaadt * Reset the tty chars to reasonable defaults
526df930be7Sderaadt * If they are disabled, then enable them.
527df930be7Sderaadt */
528df930be7Sderaadt if (rst) {
529df930be7Sderaadt if (tty__cooked_mode(&el->el_tty.t_ts)) {
530df930be7Sderaadt tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
531df930be7Sderaadt /*
532df930be7Sderaadt * Don't affect CMIN and CTIME for the editor mode
533df930be7Sderaadt */
534df930be7Sderaadt for (rst = 0; rst < C_NCC - 2; rst++)
535d484b7d0Sotto if (el->el_tty.t_c[TS_IO][rst] !=
536d484b7d0Sotto el->el_tty.t_vdisable
537d484b7d0Sotto && el->el_tty.t_c[ED_IO][rst] !=
538d484b7d0Sotto el->el_tty.t_vdisable)
539d484b7d0Sotto el->el_tty.t_c[ED_IO][rst] =
540d484b7d0Sotto el->el_tty.t_c[TS_IO][rst];
541df930be7Sderaadt for (rst = 0; rst < C_NCC; rst++)
542d484b7d0Sotto if (el->el_tty.t_c[TS_IO][rst] !=
543d484b7d0Sotto el->el_tty.t_vdisable)
544d484b7d0Sotto el->el_tty.t_c[EX_IO][rst] =
545d484b7d0Sotto el->el_tty.t_c[TS_IO][rst];
546df930be7Sderaadt }
547df930be7Sderaadt tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
548aed0ee81Snicm if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
549df930be7Sderaadt #ifdef DEBUG_TTY
550d484b7d0Sotto (void) fprintf(el->el_errfile,
551d484b7d0Sotto "tty_setup: tty_setty: %s\n",
552df930be7Sderaadt strerror(errno));
553df930be7Sderaadt #endif /* DEBUG_TTY */
55428d54ee8Sschwarze return -1;
555df930be7Sderaadt }
556aed0ee81Snicm }
557df930be7Sderaadt
5580d6dc0dbSyasuoka tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
559df930be7Sderaadt
560df930be7Sderaadt tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
561d484b7d0Sotto tty_bind_char(el, 1);
562491df958Sschwarze el->el_tty.t_initialized = 1;
56328d54ee8Sschwarze return 0;
564df930be7Sderaadt }
565df930be7Sderaadt
566df930be7Sderaadt protected int
tty_init(EditLine * el)567d484b7d0Sotto tty_init(EditLine *el)
568df930be7Sderaadt {
569d484b7d0Sotto
570df930be7Sderaadt el->el_tty.t_mode = EX_IO;
571df930be7Sderaadt el->el_tty.t_vdisable = _POSIX_VDISABLE;
572491df958Sschwarze el->el_tty.t_initialized = 0;
573df930be7Sderaadt (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
574df930be7Sderaadt (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
57528d54ee8Sschwarze return tty_setup(el);
576d484b7d0Sotto }
577df930be7Sderaadt
578df930be7Sderaadt
579df930be7Sderaadt /* tty_end():
580df930be7Sderaadt * Restore the tty to its original settings
581df930be7Sderaadt */
582df930be7Sderaadt protected void
tty_end(EditLine * el)583491df958Sschwarze tty_end(EditLine *el)
584df930be7Sderaadt {
585491df958Sschwarze if (el->el_flags & EDIT_DISABLED)
586491df958Sschwarze return;
587d484b7d0Sotto
588491df958Sschwarze if (!el->el_tty.t_initialized)
589491df958Sschwarze return;
590491df958Sschwarze
591491df958Sschwarze if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
592491df958Sschwarze #ifdef DEBUG_TTY
593491df958Sschwarze (void) fprintf(el->el_errfile,
594491df958Sschwarze "%s: tty_setty: %s\n", __func__, strerror(errno));
595491df958Sschwarze #endif /* DEBUG_TTY */
596491df958Sschwarze }
597df930be7Sderaadt }
598df930be7Sderaadt
599df930be7Sderaadt
600df930be7Sderaadt /* tty__getspeed():
601df930be7Sderaadt * Get the tty speed
602df930be7Sderaadt */
603ddc81437Sschwarze static speed_t
tty__getspeed(struct termios * td)604d484b7d0Sotto tty__getspeed(struct termios *td)
605df930be7Sderaadt {
606df930be7Sderaadt speed_t spd;
607df930be7Sderaadt
608df930be7Sderaadt if ((spd = cfgetispeed(td)) == 0)
609df930be7Sderaadt spd = cfgetospeed(td);
61028d54ee8Sschwarze return spd;
611d484b7d0Sotto }
612df930be7Sderaadt
6136e02e073Sotto /* tty__getspeed():
6146e02e073Sotto * Return the index of the asked char in the c_cc array
6156e02e073Sotto */
616ddc81437Sschwarze static int
tty__getcharindex(int i)6176e02e073Sotto tty__getcharindex(int i)
6186e02e073Sotto {
6196e02e073Sotto switch (i) {
6206e02e073Sotto #ifdef VINTR
6216e02e073Sotto case C_INTR:
6226e02e073Sotto return VINTR;
6236e02e073Sotto #endif /* VINTR */
6246e02e073Sotto #ifdef VQUIT
6256e02e073Sotto case C_QUIT:
6266e02e073Sotto return VQUIT;
6276e02e073Sotto #endif /* VQUIT */
6286e02e073Sotto #ifdef VERASE
6296e02e073Sotto case C_ERASE:
6306e02e073Sotto return VERASE;
6316e02e073Sotto #endif /* VERASE */
6326e02e073Sotto #ifdef VKILL
6336e02e073Sotto case C_KILL:
6346e02e073Sotto return VKILL;
6356e02e073Sotto #endif /* VKILL */
6366e02e073Sotto #ifdef VEOF
6376e02e073Sotto case C_EOF:
6386e02e073Sotto return VEOF;
6396e02e073Sotto #endif /* VEOF */
6406e02e073Sotto #ifdef VEOL
6416e02e073Sotto case C_EOL:
6426e02e073Sotto return VEOL;
6436e02e073Sotto #endif /* VEOL */
6446e02e073Sotto #ifdef VEOL2
6456e02e073Sotto case C_EOL2:
6466e02e073Sotto return VEOL2;
6476e02e073Sotto #endif /* VEOL2 */
6486e02e073Sotto #ifdef VSWTCH
6496e02e073Sotto case C_SWTCH:
6506e02e073Sotto return VSWTCH;
6516e02e073Sotto #endif /* VSWTCH */
6526e02e073Sotto #ifdef VDSWTCH
6536e02e073Sotto case C_DSWTCH:
6546e02e073Sotto return VDSWTCH;
6556e02e073Sotto #endif /* VDSWTCH */
6566e02e073Sotto #ifdef VERASE2
6576e02e073Sotto case C_ERASE2:
6586e02e073Sotto return VERASE2;
6596e02e073Sotto #endif /* VERASE2 */
6606e02e073Sotto #ifdef VSTART
6616e02e073Sotto case C_START:
6626e02e073Sotto return VSTART;
6636e02e073Sotto #endif /* VSTART */
6646e02e073Sotto #ifdef VSTOP
6656e02e073Sotto case C_STOP:
6666e02e073Sotto return VSTOP;
6676e02e073Sotto #endif /* VSTOP */
6686e02e073Sotto #ifdef VWERASE
6696e02e073Sotto case C_WERASE:
6706e02e073Sotto return VWERASE;
6716e02e073Sotto #endif /* VWERASE */
6726e02e073Sotto #ifdef VSUSP
6736e02e073Sotto case C_SUSP:
6746e02e073Sotto return VSUSP;
6756e02e073Sotto #endif /* VSUSP */
6766e02e073Sotto #ifdef VDSUSP
6776e02e073Sotto case C_DSUSP:
6786e02e073Sotto return VDSUSP;
6796e02e073Sotto #endif /* VDSUSP */
6806e02e073Sotto #ifdef VREPRINT
6816e02e073Sotto case C_REPRINT:
6826e02e073Sotto return VREPRINT;
6836e02e073Sotto #endif /* VREPRINT */
6846e02e073Sotto #ifdef VDISCARD
6856e02e073Sotto case C_DISCARD:
6866e02e073Sotto return VDISCARD;
6876e02e073Sotto #endif /* VDISCARD */
6886e02e073Sotto #ifdef VLNEXT
6896e02e073Sotto case C_LNEXT:
6906e02e073Sotto return VLNEXT;
6916e02e073Sotto #endif /* VLNEXT */
6926e02e073Sotto #ifdef VSTATUS
6936e02e073Sotto case C_STATUS:
6946e02e073Sotto return VSTATUS;
6956e02e073Sotto #endif /* VSTATUS */
6966e02e073Sotto #ifdef VPAGE
6976e02e073Sotto case C_PAGE:
6986e02e073Sotto return VPAGE;
6996e02e073Sotto #endif /* VPAGE */
7006e02e073Sotto #ifdef VPGOFF
7016e02e073Sotto case C_PGOFF:
7026e02e073Sotto return VPGOFF;
7036e02e073Sotto #endif /* VPGOFF */
7046e02e073Sotto #ifdef VKILL2
7056e02e073Sotto case C_KILL2:
7066e02e073Sotto return VKILL2;
7076e02e073Sotto #endif /* KILL2 */
7086e02e073Sotto #ifdef VMIN
7096e02e073Sotto case C_MIN:
7106e02e073Sotto return VMIN;
7116e02e073Sotto #endif /* VMIN */
7126e02e073Sotto #ifdef VTIME
7136e02e073Sotto case C_TIME:
7146e02e073Sotto return VTIME;
7156e02e073Sotto #endif /* VTIME */
7166e02e073Sotto default:
7176e02e073Sotto return -1;
7186e02e073Sotto }
7196e02e073Sotto }
720df930be7Sderaadt
721df930be7Sderaadt /* tty__getchar():
722df930be7Sderaadt * Get the tty characters
723df930be7Sderaadt */
724ddc81437Sschwarze static void
tty__getchar(struct termios * td,unsigned char * s)725d484b7d0Sotto tty__getchar(struct termios *td, unsigned char *s)
726df930be7Sderaadt {
727d484b7d0Sotto
728df930be7Sderaadt #ifdef VINTR
729df930be7Sderaadt s[C_INTR] = td->c_cc[VINTR];
730df930be7Sderaadt #endif /* VINTR */
731df930be7Sderaadt #ifdef VQUIT
732df930be7Sderaadt s[C_QUIT] = td->c_cc[VQUIT];
733df930be7Sderaadt #endif /* VQUIT */
734df930be7Sderaadt #ifdef VERASE
735df930be7Sderaadt s[C_ERASE] = td->c_cc[VERASE];
736df930be7Sderaadt #endif /* VERASE */
737df930be7Sderaadt #ifdef VKILL
738df930be7Sderaadt s[C_KILL] = td->c_cc[VKILL];
739df930be7Sderaadt #endif /* VKILL */
740df930be7Sderaadt #ifdef VEOF
741df930be7Sderaadt s[C_EOF] = td->c_cc[VEOF];
742df930be7Sderaadt #endif /* VEOF */
743df930be7Sderaadt #ifdef VEOL
744df930be7Sderaadt s[C_EOL] = td->c_cc[VEOL];
745df930be7Sderaadt #endif /* VEOL */
746df930be7Sderaadt #ifdef VEOL2
747df930be7Sderaadt s[C_EOL2] = td->c_cc[VEOL2];
748df930be7Sderaadt #endif /* VEOL2 */
749df930be7Sderaadt #ifdef VSWTCH
750df930be7Sderaadt s[C_SWTCH] = td->c_cc[VSWTCH];
751df930be7Sderaadt #endif /* VSWTCH */
752df930be7Sderaadt #ifdef VDSWTCH
753df930be7Sderaadt s[C_DSWTCH] = td->c_cc[VDSWTCH];
754df930be7Sderaadt #endif /* VDSWTCH */
755df930be7Sderaadt #ifdef VERASE2
756df930be7Sderaadt s[C_ERASE2] = td->c_cc[VERASE2];
757df930be7Sderaadt #endif /* VERASE2 */
758df930be7Sderaadt #ifdef VSTART
759df930be7Sderaadt s[C_START] = td->c_cc[VSTART];
760df930be7Sderaadt #endif /* VSTART */
761df930be7Sderaadt #ifdef VSTOP
762df930be7Sderaadt s[C_STOP] = td->c_cc[VSTOP];
763df930be7Sderaadt #endif /* VSTOP */
764df930be7Sderaadt #ifdef VWERASE
765df930be7Sderaadt s[C_WERASE] = td->c_cc[VWERASE];
766df930be7Sderaadt #endif /* VWERASE */
767df930be7Sderaadt #ifdef VSUSP
768df930be7Sderaadt s[C_SUSP] = td->c_cc[VSUSP];
769df930be7Sderaadt #endif /* VSUSP */
770df930be7Sderaadt #ifdef VDSUSP
771df930be7Sderaadt s[C_DSUSP] = td->c_cc[VDSUSP];
772df930be7Sderaadt #endif /* VDSUSP */
773df930be7Sderaadt #ifdef VREPRINT
774df930be7Sderaadt s[C_REPRINT] = td->c_cc[VREPRINT];
775df930be7Sderaadt #endif /* VREPRINT */
776df930be7Sderaadt #ifdef VDISCARD
777df930be7Sderaadt s[C_DISCARD] = td->c_cc[VDISCARD];
778df930be7Sderaadt #endif /* VDISCARD */
779df930be7Sderaadt #ifdef VLNEXT
780df930be7Sderaadt s[C_LNEXT] = td->c_cc[VLNEXT];
781df930be7Sderaadt #endif /* VLNEXT */
782df930be7Sderaadt #ifdef VSTATUS
783df930be7Sderaadt s[C_STATUS] = td->c_cc[VSTATUS];
784df930be7Sderaadt #endif /* VSTATUS */
785df930be7Sderaadt #ifdef VPAGE
786df930be7Sderaadt s[C_PAGE] = td->c_cc[VPAGE];
787df930be7Sderaadt #endif /* VPAGE */
788df930be7Sderaadt #ifdef VPGOFF
789df930be7Sderaadt s[C_PGOFF] = td->c_cc[VPGOFF];
790df930be7Sderaadt #endif /* VPGOFF */
791df930be7Sderaadt #ifdef VKILL2
792df930be7Sderaadt s[C_KILL2] = td->c_cc[VKILL2];
793df930be7Sderaadt #endif /* KILL2 */
794df930be7Sderaadt #ifdef VMIN
795df930be7Sderaadt s[C_MIN] = td->c_cc[VMIN];
796df930be7Sderaadt #endif /* VMIN */
797df930be7Sderaadt #ifdef VTIME
798df930be7Sderaadt s[C_TIME] = td->c_cc[VTIME];
799df930be7Sderaadt #endif /* VTIME */
800df930be7Sderaadt } /* tty__getchar */
801df930be7Sderaadt
802df930be7Sderaadt
803df930be7Sderaadt /* tty__setchar():
804df930be7Sderaadt * Set the tty characters
805df930be7Sderaadt */
806ddc81437Sschwarze static void
tty__setchar(struct termios * td,unsigned char * s)807d484b7d0Sotto tty__setchar(struct termios *td, unsigned char *s)
808df930be7Sderaadt {
809d484b7d0Sotto
810df930be7Sderaadt #ifdef VINTR
811df930be7Sderaadt td->c_cc[VINTR] = s[C_INTR];
812df930be7Sderaadt #endif /* VINTR */
813df930be7Sderaadt #ifdef VQUIT
814df930be7Sderaadt td->c_cc[VQUIT] = s[C_QUIT];
815df930be7Sderaadt #endif /* VQUIT */
816df930be7Sderaadt #ifdef VERASE
817df930be7Sderaadt td->c_cc[VERASE] = s[C_ERASE];
818df930be7Sderaadt #endif /* VERASE */
819df930be7Sderaadt #ifdef VKILL
820df930be7Sderaadt td->c_cc[VKILL] = s[C_KILL];
821df930be7Sderaadt #endif /* VKILL */
822df930be7Sderaadt #ifdef VEOF
823df930be7Sderaadt td->c_cc[VEOF] = s[C_EOF];
824df930be7Sderaadt #endif /* VEOF */
825df930be7Sderaadt #ifdef VEOL
826df930be7Sderaadt td->c_cc[VEOL] = s[C_EOL];
827df930be7Sderaadt #endif /* VEOL */
828df930be7Sderaadt #ifdef VEOL2
829df930be7Sderaadt td->c_cc[VEOL2] = s[C_EOL2];
830df930be7Sderaadt #endif /* VEOL2 */
831df930be7Sderaadt #ifdef VSWTCH
832df930be7Sderaadt td->c_cc[VSWTCH] = s[C_SWTCH];
833df930be7Sderaadt #endif /* VSWTCH */
834df930be7Sderaadt #ifdef VDSWTCH
835df930be7Sderaadt td->c_cc[VDSWTCH] = s[C_DSWTCH];
836df930be7Sderaadt #endif /* VDSWTCH */
837df930be7Sderaadt #ifdef VERASE2
838df930be7Sderaadt td->c_cc[VERASE2] = s[C_ERASE2];
839df930be7Sderaadt #endif /* VERASE2 */
840df930be7Sderaadt #ifdef VSTART
841df930be7Sderaadt td->c_cc[VSTART] = s[C_START];
842df930be7Sderaadt #endif /* VSTART */
843df930be7Sderaadt #ifdef VSTOP
844df930be7Sderaadt td->c_cc[VSTOP] = s[C_STOP];
845df930be7Sderaadt #endif /* VSTOP */
846df930be7Sderaadt #ifdef VWERASE
847df930be7Sderaadt td->c_cc[VWERASE] = s[C_WERASE];
848df930be7Sderaadt #endif /* VWERASE */
849df930be7Sderaadt #ifdef VSUSP
850df930be7Sderaadt td->c_cc[VSUSP] = s[C_SUSP];
851df930be7Sderaadt #endif /* VSUSP */
852df930be7Sderaadt #ifdef VDSUSP
853df930be7Sderaadt td->c_cc[VDSUSP] = s[C_DSUSP];
854df930be7Sderaadt #endif /* VDSUSP */
855df930be7Sderaadt #ifdef VREPRINT
856df930be7Sderaadt td->c_cc[VREPRINT] = s[C_REPRINT];
857df930be7Sderaadt #endif /* VREPRINT */
858df930be7Sderaadt #ifdef VDISCARD
859df930be7Sderaadt td->c_cc[VDISCARD] = s[C_DISCARD];
860df930be7Sderaadt #endif /* VDISCARD */
861df930be7Sderaadt #ifdef VLNEXT
862df930be7Sderaadt td->c_cc[VLNEXT] = s[C_LNEXT];
863df930be7Sderaadt #endif /* VLNEXT */
864df930be7Sderaadt #ifdef VSTATUS
865df930be7Sderaadt td->c_cc[VSTATUS] = s[C_STATUS];
866df930be7Sderaadt #endif /* VSTATUS */
867df930be7Sderaadt #ifdef VPAGE
868df930be7Sderaadt td->c_cc[VPAGE] = s[C_PAGE];
869df930be7Sderaadt #endif /* VPAGE */
870df930be7Sderaadt #ifdef VPGOFF
871df930be7Sderaadt td->c_cc[VPGOFF] = s[C_PGOFF];
872df930be7Sderaadt #endif /* VPGOFF */
873df930be7Sderaadt #ifdef VKILL2
874df930be7Sderaadt td->c_cc[VKILL2] = s[C_KILL2];
875df930be7Sderaadt #endif /* VKILL2 */
876df930be7Sderaadt #ifdef VMIN
877df930be7Sderaadt td->c_cc[VMIN] = s[C_MIN];
878df930be7Sderaadt #endif /* VMIN */
879df930be7Sderaadt #ifdef VTIME
880df930be7Sderaadt td->c_cc[VTIME] = s[C_TIME];
881df930be7Sderaadt #endif /* VTIME */
882df930be7Sderaadt } /* tty__setchar */
883df930be7Sderaadt
884df930be7Sderaadt
885df930be7Sderaadt /* tty_bind_char():
886df930be7Sderaadt * Rebind the editline functions
887df930be7Sderaadt */
888df930be7Sderaadt protected void
tty_bind_char(EditLine * el,int force)889d484b7d0Sotto tty_bind_char(EditLine *el, int force)
890df930be7Sderaadt {
891d484b7d0Sotto
892df930be7Sderaadt unsigned char *t_n = el->el_tty.t_c[ED_IO];
893df930be7Sderaadt unsigned char *t_o = el->el_tty.t_ed.c_cc;
894e3191321Sschwarze wchar_t new[2], old[2];
895d484b7d0Sotto const ttymap_t *tp;
896d484b7d0Sotto el_action_t *map, *alt;
897d484b7d0Sotto const el_action_t *dmap, *dalt;
898df930be7Sderaadt new[1] = old[1] = '\0';
899df930be7Sderaadt
900df930be7Sderaadt map = el->el_map.key;
901df930be7Sderaadt alt = el->el_map.alt;
902df930be7Sderaadt if (el->el_map.type == MAP_VI) {
903df930be7Sderaadt dmap = el->el_map.vii;
904df930be7Sderaadt dalt = el->el_map.vic;
905d484b7d0Sotto } else {
906df930be7Sderaadt dmap = el->el_map.emacs;
907df930be7Sderaadt dalt = NULL;
908df930be7Sderaadt }
909df930be7Sderaadt
910b2589f0bSschwarze for (tp = tty_map; tp->nch != (wint_t)-1; tp++) {
911e3191321Sschwarze new[0] = (wchar_t)t_n[tp->nch];
912e3191321Sschwarze old[0] = (wchar_t)t_o[tp->och];
913df930be7Sderaadt if (new[0] == old[0] && !force)
914df930be7Sderaadt continue;
915df930be7Sderaadt /* Put the old default binding back, and set the new binding */
91636facb13Sschwarze keymacro_clear(el, map, old);
917565aa7e8Sschwarze map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]];
91836facb13Sschwarze keymacro_clear(el, map, new);
919df930be7Sderaadt /* MAP_VI == 1, MAP_EMACS == 0... */
920565aa7e8Sschwarze map[(unsigned char)new[0]] = tp->bind[el->el_map.type];
921df930be7Sderaadt if (dalt) {
92236facb13Sschwarze keymacro_clear(el, alt, old);
923565aa7e8Sschwarze alt[(unsigned char)old[0]] =
924565aa7e8Sschwarze dalt[(unsigned char)old[0]];
92536facb13Sschwarze keymacro_clear(el, alt, new);
926565aa7e8Sschwarze alt[(unsigned char)new[0]] =
927565aa7e8Sschwarze tp->bind[el->el_map.type + 1];
928df930be7Sderaadt }
929df930be7Sderaadt }
930df930be7Sderaadt }
931df930be7Sderaadt
932d484b7d0Sotto
933ddc81437Sschwarze static tcflag_t *
tty__get_flag(struct termios * t,int kind)9340d6dc0dbSyasuoka tty__get_flag(struct termios *t, int kind) {
9350d6dc0dbSyasuoka switch (kind) {
9360d6dc0dbSyasuoka case MD_INP:
9370d6dc0dbSyasuoka return &t->c_iflag;
9380d6dc0dbSyasuoka case MD_OUT:
9390d6dc0dbSyasuoka return &t->c_oflag;
9400d6dc0dbSyasuoka case MD_CTL:
9410d6dc0dbSyasuoka return &t->c_cflag;
9420d6dc0dbSyasuoka case MD_LIN:
9430d6dc0dbSyasuoka return &t->c_lflag;
9440d6dc0dbSyasuoka default:
9450d6dc0dbSyasuoka abort();
9460d6dc0dbSyasuoka /*NOTREACHED*/
9470d6dc0dbSyasuoka }
9480d6dc0dbSyasuoka }
9490d6dc0dbSyasuoka
9500d6dc0dbSyasuoka
951ddc81437Sschwarze static tcflag_t
tty_update_flag(EditLine * el,tcflag_t f,int mode,int kind)9520d6dc0dbSyasuoka tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
9530d6dc0dbSyasuoka {
9540d6dc0dbSyasuoka f &= ~el->el_tty.t_t[mode][kind].t_clrmask;
9550d6dc0dbSyasuoka f |= el->el_tty.t_t[mode][kind].t_setmask;
9560d6dc0dbSyasuoka return f;
9570d6dc0dbSyasuoka }
9580d6dc0dbSyasuoka
9590d6dc0dbSyasuoka
960ddc81437Sschwarze static void
tty_update_flags(EditLine * el,int kind)9610d6dc0dbSyasuoka tty_update_flags(EditLine *el, int kind)
9620d6dc0dbSyasuoka {
9630d6dc0dbSyasuoka tcflag_t *tt, *ed, *ex;
9640d6dc0dbSyasuoka tt = tty__get_flag(&el->el_tty.t_ts, kind);
9650d6dc0dbSyasuoka ed = tty__get_flag(&el->el_tty.t_ed, kind);
9660d6dc0dbSyasuoka ex = tty__get_flag(&el->el_tty.t_ex, kind);
9670d6dc0dbSyasuoka
9680d6dc0dbSyasuoka if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) {
9690d6dc0dbSyasuoka *ed = tty_update_flag(el, *tt, ED_IO, kind);
9700d6dc0dbSyasuoka *ex = tty_update_flag(el, *tt, EX_IO, kind);
9710d6dc0dbSyasuoka }
9720d6dc0dbSyasuoka }
9730d6dc0dbSyasuoka
9740d6dc0dbSyasuoka
975ddc81437Sschwarze static void
tty_update_char(EditLine * el,int mode,int c)9760d6dc0dbSyasuoka tty_update_char(EditLine *el, int mode, int c) {
9770d6dc0dbSyasuoka if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c)))
9780d6dc0dbSyasuoka && (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c]))
9790d6dc0dbSyasuoka el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c];
9800d6dc0dbSyasuoka if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c))
9810d6dc0dbSyasuoka el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable;
9820d6dc0dbSyasuoka }
9830d6dc0dbSyasuoka
9840d6dc0dbSyasuoka
985df930be7Sderaadt /* tty_rawmode():
986df930be7Sderaadt * Set terminal into 1 character at a time mode.
987df930be7Sderaadt */
988df930be7Sderaadt protected int
tty_rawmode(EditLine * el)989d484b7d0Sotto tty_rawmode(EditLine *el)
990df930be7Sderaadt {
991d484b7d0Sotto
992d484b7d0Sotto if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
99328d54ee8Sschwarze return 0;
994d484b7d0Sotto
995d484b7d0Sotto if (el->el_flags & EDIT_DISABLED)
99628d54ee8Sschwarze return 0;
997df930be7Sderaadt
998df930be7Sderaadt if (tty_getty(el, &el->el_tty.t_ts) == -1) {
999df930be7Sderaadt #ifdef DEBUG_TTY
1000d484b7d0Sotto (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
1001d484b7d0Sotto strerror(errno));
1002df930be7Sderaadt #endif /* DEBUG_TTY */
100328d54ee8Sschwarze return -1;
1004df930be7Sderaadt }
1005df930be7Sderaadt /*
1006df930be7Sderaadt * We always keep up with the eight bit setting and the speed of the
1007aed0ee81Snicm * tty. But we only believe changes that are made to cooked mode!
1008df930be7Sderaadt */
1009df930be7Sderaadt el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
1010df930be7Sderaadt el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
1011df930be7Sderaadt
1012df930be7Sderaadt if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
1013df930be7Sderaadt tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
1014df930be7Sderaadt (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
1015df930be7Sderaadt (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
1016df930be7Sderaadt (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
1017df930be7Sderaadt (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
1018df930be7Sderaadt }
1019df930be7Sderaadt if (tty__cooked_mode(&el->el_tty.t_ts)) {
10200d6dc0dbSyasuoka int i;
1021df930be7Sderaadt
10220d6dc0dbSyasuoka for (i = MD_INP; i <= MD_LIN; i++)
10230d6dc0dbSyasuoka tty_update_flags(el, i);
1024df930be7Sderaadt
1025df930be7Sderaadt if (tty__gettabs(&el->el_tty.t_ex) == 0)
1026df930be7Sderaadt el->el_tty.t_tabs = 0;
1027df930be7Sderaadt else
1028df930be7Sderaadt el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
1029df930be7Sderaadt
1030df930be7Sderaadt tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
1031df930be7Sderaadt /*
1032df930be7Sderaadt * Check if the user made any changes.
1033df930be7Sderaadt * If he did, then propagate the changes to the
1034df930be7Sderaadt * edit and execute data structures.
1035df930be7Sderaadt */
1036df930be7Sderaadt for (i = 0; i < C_NCC; i++)
1037d484b7d0Sotto if (el->el_tty.t_c[TS_IO][i] !=
1038d484b7d0Sotto el->el_tty.t_c[EX_IO][i])
1039df930be7Sderaadt break;
1040df930be7Sderaadt
1041df930be7Sderaadt if (i != C_NCC) {
1042df930be7Sderaadt /*
1043d484b7d0Sotto * Propagate changes only to the unprotected
1044d484b7d0Sotto * chars that have been modified just now.
1045df930be7Sderaadt */
10460d6dc0dbSyasuoka for (i = 0; i < C_NCC; i++)
10470d6dc0dbSyasuoka tty_update_char(el, ED_IO, i);
10480d6dc0dbSyasuoka
1049df930be7Sderaadt tty_bind_char(el, 0);
1050df930be7Sderaadt tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
1051df930be7Sderaadt
10520d6dc0dbSyasuoka for (i = 0; i < C_NCC; i++)
10530d6dc0dbSyasuoka tty_update_char(el, EX_IO, i);
10540d6dc0dbSyasuoka
1055df930be7Sderaadt tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
1056df930be7Sderaadt }
1057df930be7Sderaadt }
1058aed0ee81Snicm if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
1059df930be7Sderaadt #ifdef DEBUG_TTY
1060df930be7Sderaadt (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
1061df930be7Sderaadt strerror(errno));
1062df930be7Sderaadt #endif /* DEBUG_TTY */
106328d54ee8Sschwarze return -1;
1064df930be7Sderaadt }
1065df930be7Sderaadt el->el_tty.t_mode = ED_IO;
106628d54ee8Sschwarze return 0;
1067d484b7d0Sotto }
1068df930be7Sderaadt
1069df930be7Sderaadt
1070df930be7Sderaadt /* tty_cookedmode():
1071df930be7Sderaadt * Set the tty back to normal mode
1072df930be7Sderaadt */
1073df930be7Sderaadt protected int
tty_cookedmode(EditLine * el)1074d484b7d0Sotto tty_cookedmode(EditLine *el)
1075df930be7Sderaadt { /* set tty in normal setup */
1076d484b7d0Sotto
1077df930be7Sderaadt if (el->el_tty.t_mode == EX_IO)
107828d54ee8Sschwarze return 0;
1079df930be7Sderaadt
1080d484b7d0Sotto if (el->el_flags & EDIT_DISABLED)
108128d54ee8Sschwarze return 0;
1082d484b7d0Sotto
1083aed0ee81Snicm if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
1084df930be7Sderaadt #ifdef DEBUG_TTY
1085d484b7d0Sotto (void) fprintf(el->el_errfile,
1086d484b7d0Sotto "tty_cookedmode: tty_setty: %s\n",
1087df930be7Sderaadt strerror(errno));
1088df930be7Sderaadt #endif /* DEBUG_TTY */
108928d54ee8Sschwarze return -1;
1090df930be7Sderaadt }
1091df930be7Sderaadt el->el_tty.t_mode = EX_IO;
109228d54ee8Sschwarze return 0;
1093d484b7d0Sotto }
1094df930be7Sderaadt
1095df930be7Sderaadt
1096df930be7Sderaadt /* tty_quotemode():
1097df930be7Sderaadt * Turn on quote mode
1098df930be7Sderaadt */
1099df930be7Sderaadt protected int
tty_quotemode(EditLine * el)1100d484b7d0Sotto tty_quotemode(EditLine *el)
1101df930be7Sderaadt {
1102df930be7Sderaadt if (el->el_tty.t_mode == QU_IO)
110328d54ee8Sschwarze return 0;
1104df930be7Sderaadt
1105df930be7Sderaadt el->el_tty.t_qu = el->el_tty.t_ed;
1106df930be7Sderaadt
11070d6dc0dbSyasuoka tty_setup_flags(el, &el->el_tty.t_qu, QU_IO);
1108df930be7Sderaadt
1109aed0ee81Snicm if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
1110df930be7Sderaadt #ifdef DEBUG_TTY
1111df930be7Sderaadt (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
1112df930be7Sderaadt strerror(errno));
1113df930be7Sderaadt #endif /* DEBUG_TTY */
111428d54ee8Sschwarze return -1;
1115df930be7Sderaadt }
1116df930be7Sderaadt el->el_tty.t_mode = QU_IO;
111728d54ee8Sschwarze return 0;
1118d484b7d0Sotto }
1119df930be7Sderaadt
1120df930be7Sderaadt
1121df930be7Sderaadt /* tty_noquotemode():
1122df930be7Sderaadt * Turn off quote mode
1123df930be7Sderaadt */
1124df930be7Sderaadt protected int
tty_noquotemode(EditLine * el)1125d484b7d0Sotto tty_noquotemode(EditLine *el)
1126df930be7Sderaadt {
1127d484b7d0Sotto
1128df930be7Sderaadt if (el->el_tty.t_mode != QU_IO)
112928d54ee8Sschwarze return 0;
1130aed0ee81Snicm if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
1131df930be7Sderaadt #ifdef DEBUG_TTY
1132df930be7Sderaadt (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
1133df930be7Sderaadt strerror(errno));
1134df930be7Sderaadt #endif /* DEBUG_TTY */
113528d54ee8Sschwarze return -1;
1136df930be7Sderaadt }
1137df930be7Sderaadt el->el_tty.t_mode = ED_IO;
113828d54ee8Sschwarze return 0;
1139df930be7Sderaadt }
1140df930be7Sderaadt
1141d484b7d0Sotto
1142df930be7Sderaadt /* tty_stty():
1143df930be7Sderaadt * Stty builtin
1144df930be7Sderaadt */
1145df930be7Sderaadt protected int
tty_stty(EditLine * el,int argc,const wchar_t ** argv)1146e3191321Sschwarze tty_stty(EditLine *el, int argc __attribute__((__unused__)),
1147e3191321Sschwarze const wchar_t **argv)
1148df930be7Sderaadt {
1149d484b7d0Sotto const ttymodes_t *m;
1150d484b7d0Sotto char x;
1151df930be7Sderaadt int aflag = 0;
1152e3191321Sschwarze const wchar_t *s, *d;
1153aed0ee81Snicm char name[EL_BUFSIZ];
11546e02e073Sotto struct termios *tios = &el->el_tty.t_ex;
1155df930be7Sderaadt int z = EX_IO;
1156df930be7Sderaadt
1157df930be7Sderaadt if (argv == NULL)
115828d54ee8Sschwarze return -1;
1159aed0ee81Snicm strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
1160aed0ee81Snicm name[sizeof(name) - 1] = '\0';
1161df930be7Sderaadt
1162df930be7Sderaadt while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1163df930be7Sderaadt switch (argv[0][1]) {
1164df930be7Sderaadt case 'a':
1165df930be7Sderaadt aflag++;
1166df930be7Sderaadt argv++;
1167df930be7Sderaadt break;
1168df930be7Sderaadt case 'd':
1169df930be7Sderaadt argv++;
11706e02e073Sotto tios = &el->el_tty.t_ed;
1171df930be7Sderaadt z = ED_IO;
1172df930be7Sderaadt break;
1173df930be7Sderaadt case 'x':
1174df930be7Sderaadt argv++;
11756e02e073Sotto tios = &el->el_tty.t_ex;
1176df930be7Sderaadt z = EX_IO;
1177df930be7Sderaadt break;
1178df930be7Sderaadt case 'q':
1179df930be7Sderaadt argv++;
11806e02e073Sotto tios = &el->el_tty.t_ts;
1181df930be7Sderaadt z = QU_IO;
1182df930be7Sderaadt break;
1183df930be7Sderaadt default:
1184d484b7d0Sotto (void) fprintf(el->el_errfile,
1185b2589f0bSschwarze "%s: Unknown switch `%lc'.\n",
1186df930be7Sderaadt name, argv[0][1]);
118728d54ee8Sschwarze return -1;
1188df930be7Sderaadt }
1189df930be7Sderaadt
1190df930be7Sderaadt if (!argv || !*argv) {
1191df930be7Sderaadt int i = -1;
1192aed0ee81Snicm size_t len = 0, st = 0, cu;
1193df930be7Sderaadt for (m = ttymodes; m->m_name; m++) {
1194df930be7Sderaadt if (m->m_type != i) {
1195d484b7d0Sotto (void) fprintf(el->el_outfile, "%s%s",
1196d484b7d0Sotto i != -1 ? "\n" : "",
1197df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_name);
1198df930be7Sderaadt i = m->m_type;
1199d484b7d0Sotto st = len =
1200d484b7d0Sotto strlen(el->el_tty.t_t[z][m->m_type].t_name);
1201df930be7Sderaadt }
1202aed0ee81Snicm if (i != -1) {
1203d484b7d0Sotto x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
1204d484b7d0Sotto ? '+' : '\0';
1205d484b7d0Sotto x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
1206d484b7d0Sotto ? '-' : x;
1207aed0ee81Snicm } else {
1208aed0ee81Snicm x = '\0';
1209aed0ee81Snicm }
1210df930be7Sderaadt
1211df930be7Sderaadt if (x != '\0' || aflag) {
1212df930be7Sderaadt
1213df930be7Sderaadt cu = strlen(m->m_name) + (x != '\0') + 1;
1214df930be7Sderaadt
1215fd40972aSschwarze if (len + cu >=
1216fd40972aSschwarze (size_t)el->el_terminal.t_size.h) {
1217d484b7d0Sotto (void) fprintf(el->el_outfile, "\n%*s",
1218aed0ee81Snicm (int)st, "");
1219df930be7Sderaadt len = st + cu;
1220d484b7d0Sotto } else
1221df930be7Sderaadt len += cu;
1222df930be7Sderaadt
1223df930be7Sderaadt if (x != '\0')
1224d484b7d0Sotto (void) fprintf(el->el_outfile, "%c%s ",
1225d484b7d0Sotto x, m->m_name);
1226df930be7Sderaadt else
1227d484b7d0Sotto (void) fprintf(el->el_outfile, "%s ",
1228d484b7d0Sotto m->m_name);
1229df930be7Sderaadt }
1230df930be7Sderaadt }
1231df930be7Sderaadt (void) fprintf(el->el_outfile, "\n");
123228d54ee8Sschwarze return 0;
1233df930be7Sderaadt }
1234df930be7Sderaadt while (argv && (s = *argv++)) {
1235e3191321Sschwarze const wchar_t *p;
1236df930be7Sderaadt switch (*s) {
1237df930be7Sderaadt case '+':
1238df930be7Sderaadt case '-':
1239df930be7Sderaadt x = *s++;
1240df930be7Sderaadt break;
1241df930be7Sderaadt default:
1242df930be7Sderaadt x = '\0';
1243df930be7Sderaadt break;
1244df930be7Sderaadt }
1245df930be7Sderaadt d = s;
12465c93237dSschwarze p = wcschr(s, L'=');
1247df930be7Sderaadt for (m = ttymodes; m->m_name; m++)
1248aed0ee81Snicm if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
1249aed0ee81Snicm strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
12506e02e073Sotto (p == NULL || m->m_type == MD_CHAR))
1251df930be7Sderaadt break;
1252df930be7Sderaadt
1253df930be7Sderaadt if (!m->m_name) {
1254d484b7d0Sotto (void) fprintf(el->el_errfile,
1255565aa7e8Sschwarze "%s: Invalid argument `%ls'.\n", name, d);
125628d54ee8Sschwarze return -1;
1257df930be7Sderaadt }
12586e02e073Sotto if (p) {
12596e02e073Sotto int c = ffs((int)m->m_value);
1260aed0ee81Snicm int v = *++p ? parse__escape(&p) :
12616e02e073Sotto el->el_tty.t_vdisable;
1262aed0ee81Snicm assert(c != 0);
12636e02e073Sotto c--;
12646e02e073Sotto c = tty__getcharindex(c);
1265aed0ee81Snicm assert(c != -1);
12666e02e073Sotto tios->c_cc[c] = v;
12676e02e073Sotto continue;
12686e02e073Sotto }
1269df930be7Sderaadt switch (x) {
1270df930be7Sderaadt case '+':
1271df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1272df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1273df930be7Sderaadt break;
1274df930be7Sderaadt case '-':
1275df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1276df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1277df930be7Sderaadt break;
1278df930be7Sderaadt default:
1279df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1280df930be7Sderaadt el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1281df930be7Sderaadt break;
1282df930be7Sderaadt }
1283df930be7Sderaadt }
1284aed0ee81Snicm
12850d6dc0dbSyasuoka tty_setup_flags(el, tios, z);
1286aed0ee81Snicm if (el->el_tty.t_mode == z) {
1287aed0ee81Snicm if (tty_setty(el, TCSADRAIN, tios) == -1) {
1288aed0ee81Snicm #ifdef DEBUG_TTY
1289aed0ee81Snicm (void) fprintf(el->el_errfile,
1290aed0ee81Snicm "tty_stty: tty_setty: %s\n", strerror(errno));
1291aed0ee81Snicm #endif /* DEBUG_TTY */
129228d54ee8Sschwarze return -1;
1293aed0ee81Snicm }
1294aed0ee81Snicm }
1295aed0ee81Snicm
129628d54ee8Sschwarze return 0;
1297d484b7d0Sotto }
1298df930be7Sderaadt
1299df930be7Sderaadt
1300df930be7Sderaadt #ifdef notyet
1301df930be7Sderaadt /* tty_printchar():
1302df930be7Sderaadt * DEbugging routine to print the tty characters
1303df930be7Sderaadt */
1304ddc81437Sschwarze static void
tty_printchar(EditLine * el,unsigned char * s)1305d484b7d0Sotto tty_printchar(EditLine *el, unsigned char *s)
1306df930be7Sderaadt {
1307df930be7Sderaadt ttyperm_t *m;
1308df930be7Sderaadt int i;
1309df930be7Sderaadt
1310df930be7Sderaadt for (i = 0; i < C_NCC; i++) {
1311df930be7Sderaadt for (m = el->el_tty.t_t; m->m_name; m++)
1312d484b7d0Sotto if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
1313df930be7Sderaadt break;
1314df930be7Sderaadt if (m->m_name)
1315d484b7d0Sotto (void) fprintf(el->el_errfile, "%s ^%c ",
1316d484b7d0Sotto m->m_name, s[i] + 'A' - 1);
1317df930be7Sderaadt if (i % 5 == 0)
1318df930be7Sderaadt (void) fprintf(el->el_errfile, "\n");
1319df930be7Sderaadt }
1320df930be7Sderaadt (void) fprintf(el->el_errfile, "\n");
1321df930be7Sderaadt }
1322df930be7Sderaadt #endif /* notyet */
13230d6dc0dbSyasuoka
13240d6dc0dbSyasuoka
1325ddc81437Sschwarze static void
tty_setup_flags(EditLine * el,struct termios * tios,int mode)13260d6dc0dbSyasuoka tty_setup_flags(EditLine *el, struct termios *tios, int mode)
13270d6dc0dbSyasuoka {
13280d6dc0dbSyasuoka int kind;
13290d6dc0dbSyasuoka for (kind = MD_INP; kind <= MD_LIN; kind++) {
13300d6dc0dbSyasuoka tcflag_t *f = tty__get_flag(tios, kind);
13310d6dc0dbSyasuoka *f = tty_update_flag(el, *f, mode, kind);
13320d6dc0dbSyasuoka }
13330d6dc0dbSyasuoka }
1334