xref: /openbsd-src/lib/libedit/tty.c (revision 5b133f3f277e80f096764111e64f3a1284acb179)
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