tty.c revision 1.42 1 1.42 christos /* $NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $ */
2 1.2 lukem
3 1.1 cgd /*-
4 1.1 cgd * Copyright (c) 1992, 1993
5 1.1 cgd * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * This code is derived from software contributed to Berkeley by
8 1.1 cgd * Christos Zoulas of Cornell University.
9 1.1 cgd *
10 1.1 cgd * Redistribution and use in source and binary forms, with or without
11 1.1 cgd * modification, are permitted provided that the following conditions
12 1.1 cgd * are met:
13 1.1 cgd * 1. Redistributions of source code must retain the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer.
15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cgd * notice, this list of conditions and the following disclaimer in the
17 1.1 cgd * documentation and/or other materials provided with the distribution.
18 1.18 agc * 3. Neither the name of the University nor the names of its contributors
19 1.1 cgd * may be used to endorse or promote products derived from this software
20 1.1 cgd * without specific prior written permission.
21 1.1 cgd *
22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 1.1 cgd * SUCH DAMAGE.
33 1.1 cgd */
34 1.1 cgd
35 1.16 christos #include "config.h"
36 1.1 cgd #if !defined(lint) && !defined(SCCSID)
37 1.2 lukem #if 0
38 1.1 cgd static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
39 1.2 lukem #else
40 1.42 christos __RCSID("$NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $");
41 1.2 lukem #endif
42 1.1 cgd #endif /* not lint && not SCCSID */
43 1.1 cgd
44 1.11 simonb /*
45 1.1 cgd * tty.c: tty interface stuff
46 1.1 cgd */
47 1.19 christos #include <assert.h>
48 1.28 sketch #include <errno.h>
49 1.34 christos #include <unistd.h> /* for isatty */
50 1.33 christos #include <strings.h> /* for ffs */
51 1.32 christos #include "el.h"
52 1.1 cgd #include "tty.h"
53 1.1 cgd
54 1.1 cgd typedef struct ttymodes_t {
55 1.14 jdolecek const char *m_name;
56 1.23 lukem unsigned int m_value;
57 1.13 lukem int m_type;
58 1.13 lukem } ttymodes_t;
59 1.1 cgd
60 1.1 cgd typedef struct ttymap_t {
61 1.32 christos Int nch, och; /* Internal and termio rep of chars */
62 1.13 lukem el_action_t bind[3]; /* emacs, vi, and vi-cmd */
63 1.16 christos } ttymap_t;
64 1.1 cgd
65 1.1 cgd
66 1.14 jdolecek private const ttyperm_t ttyperm = {
67 1.13 lukem {
68 1.13 lukem {"iflag:", ICRNL, (INLCR | IGNCR)},
69 1.13 lukem {"oflag:", (OPOST | ONLCR), ONLRET},
70 1.13 lukem {"cflag:", 0, 0},
71 1.13 lukem {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
72 1.13 lukem (NOFLSH | ECHONL | EXTPROC | FLUSHO)},
73 1.13 lukem {"chars:", 0, 0},
74 1.13 lukem },
75 1.13 lukem {
76 1.13 lukem {"iflag:", (INLCR | ICRNL), IGNCR},
77 1.13 lukem {"oflag:", (OPOST | ONLCR), ONLRET},
78 1.13 lukem {"cflag:", 0, 0},
79 1.13 lukem {"lflag:", ISIG,
80 1.13 lukem (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
81 1.13 lukem {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
82 1.13 lukem C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
83 1.13 lukem C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
84 1.13 lukem },
85 1.13 lukem {
86 1.13 lukem {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
87 1.13 lukem {"oflag:", 0, 0},
88 1.13 lukem {"cflag:", 0, 0},
89 1.13 lukem {"lflag:", 0, ISIG | IEXTEN},
90 1.13 lukem {"chars:", 0, 0},
91 1.13 lukem }
92 1.1 cgd };
93 1.1 cgd
94 1.14 jdolecek private const ttychar_t ttychar = {
95 1.13 lukem {
96 1.13 lukem CINTR, CQUIT, CERASE, CKILL,
97 1.13 lukem CEOF, CEOL, CEOL2, CSWTCH,
98 1.13 lukem CDSWTCH, CERASE2, CSTART, CSTOP,
99 1.13 lukem CWERASE, CSUSP, CDSUSP, CREPRINT,
100 1.13 lukem CDISCARD, CLNEXT, CSTATUS, CPAGE,
101 1.13 lukem CPGOFF, CKILL2, CBRK, CMIN,
102 1.13 lukem CTIME
103 1.13 lukem },
104 1.13 lukem {
105 1.13 lukem CINTR, CQUIT, CERASE, CKILL,
106 1.13 lukem _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
107 1.13 lukem _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
108 1.13 lukem _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
109 1.13 lukem CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
110 1.13 lukem _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
111 1.13 lukem 0
112 1.13 lukem },
113 1.13 lukem {
114 1.13 lukem 0, 0, 0, 0,
115 1.13 lukem 0, 0, 0, 0,
116 1.13 lukem 0, 0, 0, 0,
117 1.13 lukem 0, 0, 0, 0,
118 1.13 lukem 0, 0, 0, 0,
119 1.13 lukem 0, 0, 0, 0,
120 1.13 lukem 0
121 1.13 lukem }
122 1.1 cgd };
123 1.1 cgd
124 1.14 jdolecek private const ttymap_t tty_map[] = {
125 1.1 cgd #ifdef VERASE
126 1.13 lukem {C_ERASE, VERASE,
127 1.21 mycroft {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
128 1.1 cgd #endif /* VERASE */
129 1.1 cgd #ifdef VERASE2
130 1.13 lukem {C_ERASE2, VERASE2,
131 1.21 mycroft {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
132 1.1 cgd #endif /* VERASE2 */
133 1.1 cgd #ifdef VKILL
134 1.13 lukem {C_KILL, VKILL,
135 1.13 lukem {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
136 1.1 cgd #endif /* VKILL */
137 1.1 cgd #ifdef VKILL2
138 1.13 lukem {C_KILL2, VKILL2,
139 1.13 lukem {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
140 1.1 cgd #endif /* VKILL2 */
141 1.1 cgd #ifdef VEOF
142 1.13 lukem {C_EOF, VEOF,
143 1.13 lukem {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
144 1.1 cgd #endif /* VEOF */
145 1.1 cgd #ifdef VWERASE
146 1.13 lukem {C_WERASE, VWERASE,
147 1.13 lukem {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
148 1.1 cgd #endif /* VWERASE */
149 1.1 cgd #ifdef VREPRINT
150 1.13 lukem {C_REPRINT, VREPRINT,
151 1.13 lukem {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
152 1.1 cgd #endif /* VREPRINT */
153 1.1 cgd #ifdef VLNEXT
154 1.13 lukem {C_LNEXT, VLNEXT,
155 1.13 lukem {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
156 1.1 cgd #endif /* VLNEXT */
157 1.41 christos {(Int)-1, (Int)-1,
158 1.13 lukem {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
159 1.13 lukem };
160 1.1 cgd
161 1.14 jdolecek private const ttymodes_t ttymodes[] = {
162 1.13 lukem #ifdef IGNBRK
163 1.13 lukem {"ignbrk", IGNBRK, MD_INP},
164 1.13 lukem #endif /* IGNBRK */
165 1.13 lukem #ifdef BRKINT
166 1.13 lukem {"brkint", BRKINT, MD_INP},
167 1.13 lukem #endif /* BRKINT */
168 1.13 lukem #ifdef IGNPAR
169 1.13 lukem {"ignpar", IGNPAR, MD_INP},
170 1.13 lukem #endif /* IGNPAR */
171 1.13 lukem #ifdef PARMRK
172 1.13 lukem {"parmrk", PARMRK, MD_INP},
173 1.13 lukem #endif /* PARMRK */
174 1.13 lukem #ifdef INPCK
175 1.13 lukem {"inpck", INPCK, MD_INP},
176 1.13 lukem #endif /* INPCK */
177 1.13 lukem #ifdef ISTRIP
178 1.13 lukem {"istrip", ISTRIP, MD_INP},
179 1.13 lukem #endif /* ISTRIP */
180 1.13 lukem #ifdef INLCR
181 1.13 lukem {"inlcr", INLCR, MD_INP},
182 1.13 lukem #endif /* INLCR */
183 1.13 lukem #ifdef IGNCR
184 1.13 lukem {"igncr", IGNCR, MD_INP},
185 1.13 lukem #endif /* IGNCR */
186 1.13 lukem #ifdef ICRNL
187 1.13 lukem {"icrnl", ICRNL, MD_INP},
188 1.13 lukem #endif /* ICRNL */
189 1.13 lukem #ifdef IUCLC
190 1.13 lukem {"iuclc", IUCLC, MD_INP},
191 1.13 lukem #endif /* IUCLC */
192 1.13 lukem #ifdef IXON
193 1.13 lukem {"ixon", IXON, MD_INP},
194 1.13 lukem #endif /* IXON */
195 1.13 lukem #ifdef IXANY
196 1.13 lukem {"ixany", IXANY, MD_INP},
197 1.13 lukem #endif /* IXANY */
198 1.13 lukem #ifdef IXOFF
199 1.13 lukem {"ixoff", IXOFF, MD_INP},
200 1.13 lukem #endif /* IXOFF */
201 1.13 lukem #ifdef IMAXBEL
202 1.13 lukem {"imaxbel", IMAXBEL, MD_INP},
203 1.13 lukem #endif /* IMAXBEL */
204 1.13 lukem
205 1.13 lukem #ifdef OPOST
206 1.13 lukem {"opost", OPOST, MD_OUT},
207 1.13 lukem #endif /* OPOST */
208 1.13 lukem #ifdef OLCUC
209 1.13 lukem {"olcuc", OLCUC, MD_OUT},
210 1.13 lukem #endif /* OLCUC */
211 1.13 lukem #ifdef ONLCR
212 1.13 lukem {"onlcr", ONLCR, MD_OUT},
213 1.13 lukem #endif /* ONLCR */
214 1.13 lukem #ifdef OCRNL
215 1.13 lukem {"ocrnl", OCRNL, MD_OUT},
216 1.13 lukem #endif /* OCRNL */
217 1.13 lukem #ifdef ONOCR
218 1.13 lukem {"onocr", ONOCR, MD_OUT},
219 1.13 lukem #endif /* ONOCR */
220 1.13 lukem #ifdef ONOEOT
221 1.13 lukem {"onoeot", ONOEOT, MD_OUT},
222 1.13 lukem #endif /* ONOEOT */
223 1.13 lukem #ifdef ONLRET
224 1.13 lukem {"onlret", ONLRET, MD_OUT},
225 1.13 lukem #endif /* ONLRET */
226 1.13 lukem #ifdef OFILL
227 1.13 lukem {"ofill", OFILL, MD_OUT},
228 1.13 lukem #endif /* OFILL */
229 1.13 lukem #ifdef OFDEL
230 1.13 lukem {"ofdel", OFDEL, MD_OUT},
231 1.13 lukem #endif /* OFDEL */
232 1.13 lukem #ifdef NLDLY
233 1.13 lukem {"nldly", NLDLY, MD_OUT},
234 1.13 lukem #endif /* NLDLY */
235 1.13 lukem #ifdef CRDLY
236 1.13 lukem {"crdly", CRDLY, MD_OUT},
237 1.13 lukem #endif /* CRDLY */
238 1.13 lukem #ifdef TABDLY
239 1.13 lukem {"tabdly", TABDLY, MD_OUT},
240 1.13 lukem #endif /* TABDLY */
241 1.13 lukem #ifdef XTABS
242 1.13 lukem {"xtabs", XTABS, MD_OUT},
243 1.13 lukem #endif /* XTABS */
244 1.13 lukem #ifdef BSDLY
245 1.13 lukem {"bsdly", BSDLY, MD_OUT},
246 1.13 lukem #endif /* BSDLY */
247 1.13 lukem #ifdef VTDLY
248 1.13 lukem {"vtdly", VTDLY, MD_OUT},
249 1.13 lukem #endif /* VTDLY */
250 1.13 lukem #ifdef FFDLY
251 1.13 lukem {"ffdly", FFDLY, MD_OUT},
252 1.13 lukem #endif /* FFDLY */
253 1.13 lukem #ifdef PAGEOUT
254 1.13 lukem {"pageout", PAGEOUT, MD_OUT},
255 1.13 lukem #endif /* PAGEOUT */
256 1.13 lukem #ifdef WRAP
257 1.13 lukem {"wrap", WRAP, MD_OUT},
258 1.13 lukem #endif /* WRAP */
259 1.13 lukem
260 1.13 lukem #ifdef CIGNORE
261 1.13 lukem {"cignore", CIGNORE, MD_CTL},
262 1.13 lukem #endif /* CBAUD */
263 1.13 lukem #ifdef CBAUD
264 1.13 lukem {"cbaud", CBAUD, MD_CTL},
265 1.13 lukem #endif /* CBAUD */
266 1.13 lukem #ifdef CSTOPB
267 1.13 lukem {"cstopb", CSTOPB, MD_CTL},
268 1.13 lukem #endif /* CSTOPB */
269 1.13 lukem #ifdef CREAD
270 1.13 lukem {"cread", CREAD, MD_CTL},
271 1.13 lukem #endif /* CREAD */
272 1.13 lukem #ifdef PARENB
273 1.13 lukem {"parenb", PARENB, MD_CTL},
274 1.13 lukem #endif /* PARENB */
275 1.13 lukem #ifdef PARODD
276 1.13 lukem {"parodd", PARODD, MD_CTL},
277 1.13 lukem #endif /* PARODD */
278 1.13 lukem #ifdef HUPCL
279 1.13 lukem {"hupcl", HUPCL, MD_CTL},
280 1.13 lukem #endif /* HUPCL */
281 1.13 lukem #ifdef CLOCAL
282 1.13 lukem {"clocal", CLOCAL, MD_CTL},
283 1.13 lukem #endif /* CLOCAL */
284 1.13 lukem #ifdef LOBLK
285 1.13 lukem {"loblk", LOBLK, MD_CTL},
286 1.13 lukem #endif /* LOBLK */
287 1.13 lukem #ifdef CIBAUD
288 1.13 lukem {"cibaud", CIBAUD, MD_CTL},
289 1.13 lukem #endif /* CIBAUD */
290 1.13 lukem #ifdef CRTSCTS
291 1.13 lukem #ifdef CCTS_OFLOW
292 1.13 lukem {"ccts_oflow", CCTS_OFLOW, MD_CTL},
293 1.13 lukem #else
294 1.13 lukem {"crtscts", CRTSCTS, MD_CTL},
295 1.13 lukem #endif /* CCTS_OFLOW */
296 1.13 lukem #endif /* CRTSCTS */
297 1.13 lukem #ifdef CRTS_IFLOW
298 1.13 lukem {"crts_iflow", CRTS_IFLOW, MD_CTL},
299 1.13 lukem #endif /* CRTS_IFLOW */
300 1.13 lukem #ifdef CDTRCTS
301 1.13 lukem {"cdtrcts", CDTRCTS, MD_CTL},
302 1.13 lukem #endif /* CDTRCTS */
303 1.13 lukem #ifdef MDMBUF
304 1.13 lukem {"mdmbuf", MDMBUF, MD_CTL},
305 1.13 lukem #endif /* MDMBUF */
306 1.13 lukem #ifdef RCV1EN
307 1.13 lukem {"rcv1en", RCV1EN, MD_CTL},
308 1.13 lukem #endif /* RCV1EN */
309 1.13 lukem #ifdef XMT1EN
310 1.13 lukem {"xmt1en", XMT1EN, MD_CTL},
311 1.13 lukem #endif /* XMT1EN */
312 1.13 lukem
313 1.13 lukem #ifdef ISIG
314 1.13 lukem {"isig", ISIG, MD_LIN},
315 1.13 lukem #endif /* ISIG */
316 1.13 lukem #ifdef ICANON
317 1.13 lukem {"icanon", ICANON, MD_LIN},
318 1.13 lukem #endif /* ICANON */
319 1.13 lukem #ifdef XCASE
320 1.13 lukem {"xcase", XCASE, MD_LIN},
321 1.13 lukem #endif /* XCASE */
322 1.13 lukem #ifdef ECHO
323 1.13 lukem {"echo", ECHO, MD_LIN},
324 1.13 lukem #endif /* ECHO */
325 1.13 lukem #ifdef ECHOE
326 1.13 lukem {"echoe", ECHOE, MD_LIN},
327 1.13 lukem #endif /* ECHOE */
328 1.13 lukem #ifdef ECHOK
329 1.13 lukem {"echok", ECHOK, MD_LIN},
330 1.13 lukem #endif /* ECHOK */
331 1.13 lukem #ifdef ECHONL
332 1.13 lukem {"echonl", ECHONL, MD_LIN},
333 1.13 lukem #endif /* ECHONL */
334 1.13 lukem #ifdef NOFLSH
335 1.13 lukem {"noflsh", NOFLSH, MD_LIN},
336 1.13 lukem #endif /* NOFLSH */
337 1.13 lukem #ifdef TOSTOP
338 1.13 lukem {"tostop", TOSTOP, MD_LIN},
339 1.13 lukem #endif /* TOSTOP */
340 1.13 lukem #ifdef ECHOCTL
341 1.13 lukem {"echoctl", ECHOCTL, MD_LIN},
342 1.13 lukem #endif /* ECHOCTL */
343 1.13 lukem #ifdef ECHOPRT
344 1.13 lukem {"echoprt", ECHOPRT, MD_LIN},
345 1.13 lukem #endif /* ECHOPRT */
346 1.13 lukem #ifdef ECHOKE
347 1.13 lukem {"echoke", ECHOKE, MD_LIN},
348 1.13 lukem #endif /* ECHOKE */
349 1.13 lukem #ifdef DEFECHO
350 1.13 lukem {"defecho", DEFECHO, MD_LIN},
351 1.13 lukem #endif /* DEFECHO */
352 1.13 lukem #ifdef FLUSHO
353 1.13 lukem {"flusho", FLUSHO, MD_LIN},
354 1.13 lukem #endif /* FLUSHO */
355 1.13 lukem #ifdef PENDIN
356 1.13 lukem {"pendin", PENDIN, MD_LIN},
357 1.13 lukem #endif /* PENDIN */
358 1.13 lukem #ifdef IEXTEN
359 1.13 lukem {"iexten", IEXTEN, MD_LIN},
360 1.13 lukem #endif /* IEXTEN */
361 1.13 lukem #ifdef NOKERNINFO
362 1.13 lukem {"nokerninfo", NOKERNINFO, MD_LIN},
363 1.13 lukem #endif /* NOKERNINFO */
364 1.13 lukem #ifdef ALTWERASE
365 1.13 lukem {"altwerase", ALTWERASE, MD_LIN},
366 1.13 lukem #endif /* ALTWERASE */
367 1.13 lukem #ifdef EXTPROC
368 1.13 lukem {"extproc", EXTPROC, MD_LIN},
369 1.13 lukem #endif /* EXTPROC */
370 1.13 lukem
371 1.13 lukem #if defined(VINTR)
372 1.13 lukem {"intr", C_SH(C_INTR), MD_CHAR},
373 1.13 lukem #endif /* VINTR */
374 1.13 lukem #if defined(VQUIT)
375 1.13 lukem {"quit", C_SH(C_QUIT), MD_CHAR},
376 1.13 lukem #endif /* VQUIT */
377 1.13 lukem #if defined(VERASE)
378 1.13 lukem {"erase", C_SH(C_ERASE), MD_CHAR},
379 1.13 lukem #endif /* VERASE */
380 1.13 lukem #if defined(VKILL)
381 1.13 lukem {"kill", C_SH(C_KILL), MD_CHAR},
382 1.13 lukem #endif /* VKILL */
383 1.13 lukem #if defined(VEOF)
384 1.13 lukem {"eof", C_SH(C_EOF), MD_CHAR},
385 1.13 lukem #endif /* VEOF */
386 1.13 lukem #if defined(VEOL)
387 1.13 lukem {"eol", C_SH(C_EOL), MD_CHAR},
388 1.13 lukem #endif /* VEOL */
389 1.13 lukem #if defined(VEOL2)
390 1.13 lukem {"eol2", C_SH(C_EOL2), MD_CHAR},
391 1.13 lukem #endif /* VEOL2 */
392 1.13 lukem #if defined(VSWTCH)
393 1.13 lukem {"swtch", C_SH(C_SWTCH), MD_CHAR},
394 1.13 lukem #endif /* VSWTCH */
395 1.13 lukem #if defined(VDSWTCH)
396 1.13 lukem {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
397 1.13 lukem #endif /* VDSWTCH */
398 1.13 lukem #if defined(VERASE2)
399 1.13 lukem {"erase2", C_SH(C_ERASE2), MD_CHAR},
400 1.13 lukem #endif /* VERASE2 */
401 1.13 lukem #if defined(VSTART)
402 1.13 lukem {"start", C_SH(C_START), MD_CHAR},
403 1.13 lukem #endif /* VSTART */
404 1.13 lukem #if defined(VSTOP)
405 1.13 lukem {"stop", C_SH(C_STOP), MD_CHAR},
406 1.13 lukem #endif /* VSTOP */
407 1.13 lukem #if defined(VWERASE)
408 1.13 lukem {"werase", C_SH(C_WERASE), MD_CHAR},
409 1.13 lukem #endif /* VWERASE */
410 1.13 lukem #if defined(VSUSP)
411 1.13 lukem {"susp", C_SH(C_SUSP), MD_CHAR},
412 1.13 lukem #endif /* VSUSP */
413 1.13 lukem #if defined(VDSUSP)
414 1.13 lukem {"dsusp", C_SH(C_DSUSP), MD_CHAR},
415 1.13 lukem #endif /* VDSUSP */
416 1.13 lukem #if defined(VREPRINT)
417 1.13 lukem {"reprint", C_SH(C_REPRINT), MD_CHAR},
418 1.13 lukem #endif /* VREPRINT */
419 1.13 lukem #if defined(VDISCARD)
420 1.13 lukem {"discard", C_SH(C_DISCARD), MD_CHAR},
421 1.13 lukem #endif /* VDISCARD */
422 1.13 lukem #if defined(VLNEXT)
423 1.13 lukem {"lnext", C_SH(C_LNEXT), MD_CHAR},
424 1.13 lukem #endif /* VLNEXT */
425 1.13 lukem #if defined(VSTATUS)
426 1.13 lukem {"status", C_SH(C_STATUS), MD_CHAR},
427 1.13 lukem #endif /* VSTATUS */
428 1.13 lukem #if defined(VPAGE)
429 1.13 lukem {"page", C_SH(C_PAGE), MD_CHAR},
430 1.13 lukem #endif /* VPAGE */
431 1.13 lukem #if defined(VPGOFF)
432 1.13 lukem {"pgoff", C_SH(C_PGOFF), MD_CHAR},
433 1.13 lukem #endif /* VPGOFF */
434 1.13 lukem #if defined(VKILL2)
435 1.13 lukem {"kill2", C_SH(C_KILL2), MD_CHAR},
436 1.13 lukem #endif /* VKILL2 */
437 1.13 lukem #if defined(VBRK)
438 1.13 lukem {"brk", C_SH(C_BRK), MD_CHAR},
439 1.13 lukem #endif /* VBRK */
440 1.13 lukem #if defined(VMIN)
441 1.13 lukem {"min", C_SH(C_MIN), MD_CHAR},
442 1.13 lukem #endif /* VMIN */
443 1.13 lukem #if defined(VTIME)
444 1.13 lukem {"time", C_SH(C_TIME), MD_CHAR},
445 1.13 lukem #endif /* VTIME */
446 1.13 lukem {NULL, 0, -1},
447 1.1 cgd };
448 1.1 cgd
449 1.1 cgd
450 1.1 cgd
451 1.13 lukem #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
452 1.13 lukem #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
453 1.13 lukem #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
454 1.13 lukem
455 1.26 christos private int tty_getty(EditLine *, struct termios *);
456 1.26 christos private int tty_setty(EditLine *, int, const struct termios *);
457 1.19 christos private int tty__getcharindex(int);
458 1.13 lukem private void tty__getchar(struct termios *, unsigned char *);
459 1.13 lukem private void tty__setchar(struct termios *, unsigned char *);
460 1.13 lukem private speed_t tty__getspeed(struct termios *);
461 1.13 lukem private int tty_setup(EditLine *);
462 1.1 cgd
463 1.13 lukem #define t_qu t_ts
464 1.1 cgd
465 1.26 christos /* tty_getty():
466 1.26 christos * Wrapper for tcgetattr to handle EINTR
467 1.26 christos */
468 1.26 christos private int
469 1.26 christos tty_getty(EditLine *el, struct termios *t)
470 1.26 christos {
471 1.26 christos int rv;
472 1.26 christos while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
473 1.26 christos continue;
474 1.26 christos return rv;
475 1.26 christos }
476 1.26 christos
477 1.26 christos /* tty_setty():
478 1.26 christos * Wrapper for tcsetattr to handle EINTR
479 1.26 christos */
480 1.26 christos private int
481 1.26 christos tty_setty(EditLine *el, int action, const struct termios *t)
482 1.26 christos {
483 1.26 christos int rv;
484 1.26 christos while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
485 1.26 christos continue;
486 1.26 christos return rv;
487 1.26 christos }
488 1.1 cgd
489 1.1 cgd /* tty_setup():
490 1.1 cgd * Get the tty parameters and initialize the editing state
491 1.1 cgd */
492 1.11 simonb private int
493 1.13 lukem tty_setup(EditLine *el)
494 1.1 cgd {
495 1.13 lukem int rst = 1;
496 1.12 sommerfe
497 1.13 lukem if (el->el_flags & EDIT_DISABLED)
498 1.38 christos return 0;
499 1.13 lukem
500 1.34 christos if (!isatty(el->el_outfd)) {
501 1.34 christos #ifdef DEBUG_TTY
502 1.42 christos (void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__,
503 1.42 christos strerror(errno));
504 1.34 christos #endif /* DEBUG_TTY */
505 1.38 christos return -1;
506 1.34 christos }
507 1.42 christos if (tty_getty(el, &el->el_tty.t_or) == -1) {
508 1.1 cgd #ifdef DEBUG_TTY
509 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
510 1.42 christos strerror(errno));
511 1.1 cgd #endif /* DEBUG_TTY */
512 1.38 christos return -1;
513 1.13 lukem }
514 1.42 christos el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or;
515 1.13 lukem
516 1.13 lukem el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
517 1.13 lukem el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
518 1.13 lukem el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
519 1.13 lukem
520 1.13 lukem el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
521 1.13 lukem el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
522 1.13 lukem
523 1.13 lukem el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
524 1.13 lukem el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
525 1.13 lukem
526 1.13 lukem el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
527 1.13 lukem el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
528 1.13 lukem
529 1.13 lukem el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
530 1.13 lukem el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
531 1.13 lukem
532 1.13 lukem /*
533 1.13 lukem * Reset the tty chars to reasonable defaults
534 1.13 lukem * If they are disabled, then enable them.
535 1.13 lukem */
536 1.13 lukem if (rst) {
537 1.13 lukem if (tty__cooked_mode(&el->el_tty.t_ts)) {
538 1.13 lukem tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
539 1.13 lukem /*
540 1.13 lukem * Don't affect CMIN and CTIME for the editor mode
541 1.13 lukem */
542 1.13 lukem for (rst = 0; rst < C_NCC - 2; rst++)
543 1.13 lukem if (el->el_tty.t_c[TS_IO][rst] !=
544 1.13 lukem el->el_tty.t_vdisable
545 1.13 lukem && el->el_tty.t_c[ED_IO][rst] !=
546 1.13 lukem el->el_tty.t_vdisable)
547 1.13 lukem el->el_tty.t_c[ED_IO][rst] =
548 1.13 lukem el->el_tty.t_c[TS_IO][rst];
549 1.13 lukem for (rst = 0; rst < C_NCC; rst++)
550 1.13 lukem if (el->el_tty.t_c[TS_IO][rst] !=
551 1.13 lukem el->el_tty.t_vdisable)
552 1.13 lukem el->el_tty.t_c[EX_IO][rst] =
553 1.13 lukem el->el_tty.t_c[TS_IO][rst];
554 1.13 lukem }
555 1.13 lukem tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
556 1.26 christos if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
557 1.1 cgd #ifdef DEBUG_TTY
558 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
559 1.42 christos __func__, strerror(errno));
560 1.1 cgd #endif /* DEBUG_TTY */
561 1.38 christos return -1;
562 1.13 lukem }
563 1.25 christos }
564 1.13 lukem
565 1.13 lukem el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
566 1.13 lukem el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
567 1.13 lukem
568 1.13 lukem el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
569 1.13 lukem el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
570 1.13 lukem
571 1.13 lukem el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
572 1.13 lukem el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
573 1.13 lukem
574 1.13 lukem el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
575 1.13 lukem el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
576 1.13 lukem
577 1.13 lukem tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
578 1.13 lukem tty_bind_char(el, 1);
579 1.38 christos return 0;
580 1.1 cgd }
581 1.1 cgd
582 1.1 cgd protected int
583 1.13 lukem tty_init(EditLine *el)
584 1.1 cgd {
585 1.13 lukem
586 1.13 lukem el->el_tty.t_mode = EX_IO;
587 1.13 lukem el->el_tty.t_vdisable = _POSIX_VDISABLE;
588 1.13 lukem (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
589 1.13 lukem (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
590 1.38 christos return tty_setup(el);
591 1.13 lukem }
592 1.1 cgd
593 1.1 cgd
594 1.1 cgd /* tty_end():
595 1.1 cgd * Restore the tty to its original settings
596 1.1 cgd */
597 1.1 cgd protected void
598 1.1 cgd /*ARGSUSED*/
599 1.42 christos tty_end(EditLine *el)
600 1.1 cgd {
601 1.42 christos if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
602 1.42 christos #ifdef DEBUG_TTY
603 1.42 christos (void) fprintf(el->el_errfile,
604 1.42 christos "%s: tty_setty: %s\n", __func__, strerror(errno));
605 1.42 christos #endif /* DEBUG_TTY */
606 1.42 christos }
607 1.1 cgd }
608 1.1 cgd
609 1.1 cgd
610 1.1 cgd /* tty__getspeed():
611 1.1 cgd * Get the tty speed
612 1.1 cgd */
613 1.1 cgd private speed_t
614 1.13 lukem tty__getspeed(struct termios *td)
615 1.1 cgd {
616 1.13 lukem speed_t spd;
617 1.1 cgd
618 1.13 lukem if ((spd = cfgetispeed(td)) == 0)
619 1.13 lukem spd = cfgetospeed(td);
620 1.38 christos return spd;
621 1.13 lukem }
622 1.1 cgd
623 1.19 christos /* tty__getspeed():
624 1.19 christos * Return the index of the asked char in the c_cc array
625 1.19 christos */
626 1.19 christos private int
627 1.19 christos tty__getcharindex(int i)
628 1.19 christos {
629 1.19 christos switch (i) {
630 1.19 christos #ifdef VINTR
631 1.19 christos case C_INTR:
632 1.19 christos return VINTR;
633 1.19 christos #endif /* VINTR */
634 1.19 christos #ifdef VQUIT
635 1.19 christos case C_QUIT:
636 1.19 christos return VQUIT;
637 1.19 christos #endif /* VQUIT */
638 1.19 christos #ifdef VERASE
639 1.19 christos case C_ERASE:
640 1.19 christos return VERASE;
641 1.19 christos #endif /* VERASE */
642 1.19 christos #ifdef VKILL
643 1.19 christos case C_KILL:
644 1.19 christos return VKILL;
645 1.19 christos #endif /* VKILL */
646 1.19 christos #ifdef VEOF
647 1.19 christos case C_EOF:
648 1.19 christos return VEOF;
649 1.19 christos #endif /* VEOF */
650 1.19 christos #ifdef VEOL
651 1.19 christos case C_EOL:
652 1.19 christos return VEOL;
653 1.19 christos #endif /* VEOL */
654 1.19 christos #ifdef VEOL2
655 1.19 christos case C_EOL2:
656 1.19 christos return VEOL2;
657 1.19 christos #endif /* VEOL2 */
658 1.19 christos #ifdef VSWTCH
659 1.19 christos case C_SWTCH:
660 1.19 christos return VSWTCH;
661 1.19 christos #endif /* VSWTCH */
662 1.19 christos #ifdef VDSWTCH
663 1.19 christos case C_DSWTCH:
664 1.19 christos return VDSWTCH;
665 1.19 christos #endif /* VDSWTCH */
666 1.19 christos #ifdef VERASE2
667 1.19 christos case C_ERASE2:
668 1.19 christos return VERASE2;
669 1.19 christos #endif /* VERASE2 */
670 1.19 christos #ifdef VSTART
671 1.19 christos case C_START:
672 1.19 christos return VSTART;
673 1.19 christos #endif /* VSTART */
674 1.19 christos #ifdef VSTOP
675 1.19 christos case C_STOP:
676 1.19 christos return VSTOP;
677 1.19 christos #endif /* VSTOP */
678 1.19 christos #ifdef VWERASE
679 1.19 christos case C_WERASE:
680 1.19 christos return VWERASE;
681 1.19 christos #endif /* VWERASE */
682 1.19 christos #ifdef VSUSP
683 1.19 christos case C_SUSP:
684 1.19 christos return VSUSP;
685 1.19 christos #endif /* VSUSP */
686 1.19 christos #ifdef VDSUSP
687 1.19 christos case C_DSUSP:
688 1.19 christos return VDSUSP;
689 1.19 christos #endif /* VDSUSP */
690 1.19 christos #ifdef VREPRINT
691 1.19 christos case C_REPRINT:
692 1.19 christos return VREPRINT;
693 1.19 christos #endif /* VREPRINT */
694 1.19 christos #ifdef VDISCARD
695 1.19 christos case C_DISCARD:
696 1.19 christos return VDISCARD;
697 1.19 christos #endif /* VDISCARD */
698 1.19 christos #ifdef VLNEXT
699 1.19 christos case C_LNEXT:
700 1.19 christos return VLNEXT;
701 1.19 christos #endif /* VLNEXT */
702 1.19 christos #ifdef VSTATUS
703 1.19 christos case C_STATUS:
704 1.19 christos return VSTATUS;
705 1.19 christos #endif /* VSTATUS */
706 1.19 christos #ifdef VPAGE
707 1.19 christos case C_PAGE:
708 1.19 christos return VPAGE;
709 1.19 christos #endif /* VPAGE */
710 1.19 christos #ifdef VPGOFF
711 1.19 christos case C_PGOFF:
712 1.19 christos return VPGOFF;
713 1.19 christos #endif /* VPGOFF */
714 1.19 christos #ifdef VKILL2
715 1.19 christos case C_KILL2:
716 1.19 christos return VKILL2;
717 1.19 christos #endif /* KILL2 */
718 1.19 christos #ifdef VMIN
719 1.19 christos case C_MIN:
720 1.19 christos return VMIN;
721 1.19 christos #endif /* VMIN */
722 1.19 christos #ifdef VTIME
723 1.19 christos case C_TIME:
724 1.19 christos return VTIME;
725 1.19 christos #endif /* VTIME */
726 1.19 christos default:
727 1.19 christos return -1;
728 1.19 christos }
729 1.19 christos }
730 1.1 cgd
731 1.1 cgd /* tty__getchar():
732 1.1 cgd * Get the tty characters
733 1.1 cgd */
734 1.1 cgd private void
735 1.13 lukem tty__getchar(struct termios *td, unsigned char *s)
736 1.11 simonb {
737 1.13 lukem
738 1.13 lukem #ifdef VINTR
739 1.13 lukem s[C_INTR] = td->c_cc[VINTR];
740 1.13 lukem #endif /* VINTR */
741 1.13 lukem #ifdef VQUIT
742 1.13 lukem s[C_QUIT] = td->c_cc[VQUIT];
743 1.13 lukem #endif /* VQUIT */
744 1.13 lukem #ifdef VERASE
745 1.13 lukem s[C_ERASE] = td->c_cc[VERASE];
746 1.13 lukem #endif /* VERASE */
747 1.13 lukem #ifdef VKILL
748 1.13 lukem s[C_KILL] = td->c_cc[VKILL];
749 1.13 lukem #endif /* VKILL */
750 1.13 lukem #ifdef VEOF
751 1.13 lukem s[C_EOF] = td->c_cc[VEOF];
752 1.13 lukem #endif /* VEOF */
753 1.13 lukem #ifdef VEOL
754 1.13 lukem s[C_EOL] = td->c_cc[VEOL];
755 1.13 lukem #endif /* VEOL */
756 1.13 lukem #ifdef VEOL2
757 1.13 lukem s[C_EOL2] = td->c_cc[VEOL2];
758 1.13 lukem #endif /* VEOL2 */
759 1.13 lukem #ifdef VSWTCH
760 1.13 lukem s[C_SWTCH] = td->c_cc[VSWTCH];
761 1.13 lukem #endif /* VSWTCH */
762 1.13 lukem #ifdef VDSWTCH
763 1.13 lukem s[C_DSWTCH] = td->c_cc[VDSWTCH];
764 1.13 lukem #endif /* VDSWTCH */
765 1.13 lukem #ifdef VERASE2
766 1.13 lukem s[C_ERASE2] = td->c_cc[VERASE2];
767 1.13 lukem #endif /* VERASE2 */
768 1.13 lukem #ifdef VSTART
769 1.13 lukem s[C_START] = td->c_cc[VSTART];
770 1.13 lukem #endif /* VSTART */
771 1.13 lukem #ifdef VSTOP
772 1.13 lukem s[C_STOP] = td->c_cc[VSTOP];
773 1.13 lukem #endif /* VSTOP */
774 1.13 lukem #ifdef VWERASE
775 1.13 lukem s[C_WERASE] = td->c_cc[VWERASE];
776 1.13 lukem #endif /* VWERASE */
777 1.13 lukem #ifdef VSUSP
778 1.13 lukem s[C_SUSP] = td->c_cc[VSUSP];
779 1.13 lukem #endif /* VSUSP */
780 1.13 lukem #ifdef VDSUSP
781 1.13 lukem s[C_DSUSP] = td->c_cc[VDSUSP];
782 1.13 lukem #endif /* VDSUSP */
783 1.13 lukem #ifdef VREPRINT
784 1.13 lukem s[C_REPRINT] = td->c_cc[VREPRINT];
785 1.13 lukem #endif /* VREPRINT */
786 1.13 lukem #ifdef VDISCARD
787 1.13 lukem s[C_DISCARD] = td->c_cc[VDISCARD];
788 1.13 lukem #endif /* VDISCARD */
789 1.13 lukem #ifdef VLNEXT
790 1.13 lukem s[C_LNEXT] = td->c_cc[VLNEXT];
791 1.13 lukem #endif /* VLNEXT */
792 1.13 lukem #ifdef VSTATUS
793 1.13 lukem s[C_STATUS] = td->c_cc[VSTATUS];
794 1.13 lukem #endif /* VSTATUS */
795 1.13 lukem #ifdef VPAGE
796 1.13 lukem s[C_PAGE] = td->c_cc[VPAGE];
797 1.13 lukem #endif /* VPAGE */
798 1.13 lukem #ifdef VPGOFF
799 1.13 lukem s[C_PGOFF] = td->c_cc[VPGOFF];
800 1.13 lukem #endif /* VPGOFF */
801 1.13 lukem #ifdef VKILL2
802 1.13 lukem s[C_KILL2] = td->c_cc[VKILL2];
803 1.13 lukem #endif /* KILL2 */
804 1.13 lukem #ifdef VMIN
805 1.13 lukem s[C_MIN] = td->c_cc[VMIN];
806 1.13 lukem #endif /* VMIN */
807 1.13 lukem #ifdef VTIME
808 1.13 lukem s[C_TIME] = td->c_cc[VTIME];
809 1.13 lukem #endif /* VTIME */
810 1.13 lukem } /* tty__getchar */
811 1.1 cgd
812 1.1 cgd
813 1.1 cgd /* tty__setchar():
814 1.1 cgd * Set the tty characters
815 1.1 cgd */
816 1.1 cgd private void
817 1.13 lukem tty__setchar(struct termios *td, unsigned char *s)
818 1.11 simonb {
819 1.13 lukem
820 1.13 lukem #ifdef VINTR
821 1.13 lukem td->c_cc[VINTR] = s[C_INTR];
822 1.13 lukem #endif /* VINTR */
823 1.13 lukem #ifdef VQUIT
824 1.13 lukem td->c_cc[VQUIT] = s[C_QUIT];
825 1.13 lukem #endif /* VQUIT */
826 1.13 lukem #ifdef VERASE
827 1.13 lukem td->c_cc[VERASE] = s[C_ERASE];
828 1.13 lukem #endif /* VERASE */
829 1.13 lukem #ifdef VKILL
830 1.13 lukem td->c_cc[VKILL] = s[C_KILL];
831 1.13 lukem #endif /* VKILL */
832 1.13 lukem #ifdef VEOF
833 1.13 lukem td->c_cc[VEOF] = s[C_EOF];
834 1.13 lukem #endif /* VEOF */
835 1.13 lukem #ifdef VEOL
836 1.13 lukem td->c_cc[VEOL] = s[C_EOL];
837 1.13 lukem #endif /* VEOL */
838 1.13 lukem #ifdef VEOL2
839 1.13 lukem td->c_cc[VEOL2] = s[C_EOL2];
840 1.13 lukem #endif /* VEOL2 */
841 1.13 lukem #ifdef VSWTCH
842 1.13 lukem td->c_cc[VSWTCH] = s[C_SWTCH];
843 1.13 lukem #endif /* VSWTCH */
844 1.13 lukem #ifdef VDSWTCH
845 1.13 lukem td->c_cc[VDSWTCH] = s[C_DSWTCH];
846 1.13 lukem #endif /* VDSWTCH */
847 1.13 lukem #ifdef VERASE2
848 1.13 lukem td->c_cc[VERASE2] = s[C_ERASE2];
849 1.13 lukem #endif /* VERASE2 */
850 1.13 lukem #ifdef VSTART
851 1.13 lukem td->c_cc[VSTART] = s[C_START];
852 1.13 lukem #endif /* VSTART */
853 1.13 lukem #ifdef VSTOP
854 1.13 lukem td->c_cc[VSTOP] = s[C_STOP];
855 1.13 lukem #endif /* VSTOP */
856 1.13 lukem #ifdef VWERASE
857 1.13 lukem td->c_cc[VWERASE] = s[C_WERASE];
858 1.13 lukem #endif /* VWERASE */
859 1.13 lukem #ifdef VSUSP
860 1.13 lukem td->c_cc[VSUSP] = s[C_SUSP];
861 1.13 lukem #endif /* VSUSP */
862 1.13 lukem #ifdef VDSUSP
863 1.13 lukem td->c_cc[VDSUSP] = s[C_DSUSP];
864 1.13 lukem #endif /* VDSUSP */
865 1.13 lukem #ifdef VREPRINT
866 1.13 lukem td->c_cc[VREPRINT] = s[C_REPRINT];
867 1.13 lukem #endif /* VREPRINT */
868 1.13 lukem #ifdef VDISCARD
869 1.13 lukem td->c_cc[VDISCARD] = s[C_DISCARD];
870 1.13 lukem #endif /* VDISCARD */
871 1.13 lukem #ifdef VLNEXT
872 1.13 lukem td->c_cc[VLNEXT] = s[C_LNEXT];
873 1.13 lukem #endif /* VLNEXT */
874 1.13 lukem #ifdef VSTATUS
875 1.13 lukem td->c_cc[VSTATUS] = s[C_STATUS];
876 1.13 lukem #endif /* VSTATUS */
877 1.13 lukem #ifdef VPAGE
878 1.13 lukem td->c_cc[VPAGE] = s[C_PAGE];
879 1.13 lukem #endif /* VPAGE */
880 1.13 lukem #ifdef VPGOFF
881 1.13 lukem td->c_cc[VPGOFF] = s[C_PGOFF];
882 1.13 lukem #endif /* VPGOFF */
883 1.13 lukem #ifdef VKILL2
884 1.13 lukem td->c_cc[VKILL2] = s[C_KILL2];
885 1.13 lukem #endif /* VKILL2 */
886 1.13 lukem #ifdef VMIN
887 1.13 lukem td->c_cc[VMIN] = s[C_MIN];
888 1.13 lukem #endif /* VMIN */
889 1.13 lukem #ifdef VTIME
890 1.13 lukem td->c_cc[VTIME] = s[C_TIME];
891 1.13 lukem #endif /* VTIME */
892 1.13 lukem } /* tty__setchar */
893 1.1 cgd
894 1.1 cgd
895 1.1 cgd /* tty_bind_char():
896 1.1 cgd * Rebind the editline functions
897 1.1 cgd */
898 1.1 cgd protected void
899 1.13 lukem tty_bind_char(EditLine *el, int force)
900 1.1 cgd {
901 1.13 lukem
902 1.13 lukem unsigned char *t_n = el->el_tty.t_c[ED_IO];
903 1.13 lukem unsigned char *t_o = el->el_tty.t_ed.c_cc;
904 1.32 christos Char new[2], old[2];
905 1.14 jdolecek const ttymap_t *tp;
906 1.14 jdolecek el_action_t *map, *alt;
907 1.14 jdolecek const el_action_t *dmap, *dalt;
908 1.13 lukem new[1] = old[1] = '\0';
909 1.13 lukem
910 1.13 lukem map = el->el_map.key;
911 1.13 lukem alt = el->el_map.alt;
912 1.13 lukem if (el->el_map.type == MAP_VI) {
913 1.13 lukem dmap = el->el_map.vii;
914 1.13 lukem dalt = el->el_map.vic;
915 1.13 lukem } else {
916 1.13 lukem dmap = el->el_map.emacs;
917 1.13 lukem dalt = NULL;
918 1.13 lukem }
919 1.13 lukem
920 1.41 christos for (tp = tty_map; tp->nch != (Int)-1; tp++) {
921 1.13 lukem new[0] = t_n[tp->nch];
922 1.13 lukem old[0] = t_o[tp->och];
923 1.13 lukem if (new[0] == old[0] && !force)
924 1.13 lukem continue;
925 1.13 lukem /* Put the old default binding back, and set the new binding */
926 1.37 christos keymacro_clear(el, map, old);
927 1.32 christos map[UC(old[0])] = dmap[UC(old[0])];
928 1.37 christos keymacro_clear(el, map, new);
929 1.13 lukem /* MAP_VI == 1, MAP_EMACS == 0... */
930 1.32 christos map[UC(new[0])] = tp->bind[el->el_map.type];
931 1.13 lukem if (dalt) {
932 1.37 christos keymacro_clear(el, alt, old);
933 1.32 christos alt[UC(old[0])] = dalt[UC(old[0])];
934 1.37 christos keymacro_clear(el, alt, new);
935 1.32 christos alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
936 1.13 lukem }
937 1.1 cgd }
938 1.1 cgd }
939 1.1 cgd
940 1.13 lukem
941 1.1 cgd /* tty_rawmode():
942 1.1 cgd * Set terminal into 1 character at a time mode.
943 1.1 cgd */
944 1.1 cgd protected int
945 1.13 lukem tty_rawmode(EditLine *el)
946 1.1 cgd {
947 1.1 cgd
948 1.13 lukem if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
949 1.38 christos return 0;
950 1.13 lukem
951 1.13 lukem if (el->el_flags & EDIT_DISABLED)
952 1.38 christos return 0;
953 1.12 sommerfe
954 1.13 lukem if (tty_getty(el, &el->el_tty.t_ts) == -1) {
955 1.1 cgd #ifdef DEBUG_TTY
956 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
957 1.13 lukem strerror(errno));
958 1.1 cgd #endif /* DEBUG_TTY */
959 1.38 christos return -1;
960 1.1 cgd }
961 1.13 lukem /*
962 1.13 lukem * We always keep up with the eight bit setting and the speed of the
963 1.32 christos * tty. But we only believe changes that are made to cooked mode!
964 1.13 lukem */
965 1.13 lukem el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
966 1.13 lukem el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
967 1.13 lukem
968 1.13 lukem if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
969 1.13 lukem tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
970 1.13 lukem (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
971 1.13 lukem (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
972 1.13 lukem (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
973 1.13 lukem (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
974 1.1 cgd }
975 1.13 lukem if (tty__cooked_mode(&el->el_tty.t_ts)) {
976 1.13 lukem if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
977 1.13 lukem el->el_tty.t_ex.c_cflag =
978 1.13 lukem el->el_tty.t_ts.c_cflag;
979 1.13 lukem el->el_tty.t_ex.c_cflag &=
980 1.13 lukem ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
981 1.13 lukem el->el_tty.t_ex.c_cflag |=
982 1.13 lukem el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
983 1.13 lukem
984 1.13 lukem el->el_tty.t_ed.c_cflag =
985 1.13 lukem el->el_tty.t_ts.c_cflag;
986 1.13 lukem el->el_tty.t_ed.c_cflag &=
987 1.13 lukem ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
988 1.13 lukem el->el_tty.t_ed.c_cflag |=
989 1.13 lukem el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
990 1.13 lukem }
991 1.13 lukem if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
992 1.13 lukem (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
993 1.13 lukem el->el_tty.t_ex.c_lflag =
994 1.13 lukem el->el_tty.t_ts.c_lflag;
995 1.13 lukem el->el_tty.t_ex.c_lflag &=
996 1.13 lukem ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
997 1.13 lukem el->el_tty.t_ex.c_lflag |=
998 1.13 lukem el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
999 1.13 lukem
1000 1.13 lukem el->el_tty.t_ed.c_lflag =
1001 1.13 lukem el->el_tty.t_ts.c_lflag;
1002 1.13 lukem el->el_tty.t_ed.c_lflag &=
1003 1.13 lukem ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
1004 1.13 lukem el->el_tty.t_ed.c_lflag |=
1005 1.13 lukem el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
1006 1.13 lukem }
1007 1.13 lukem if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
1008 1.13 lukem (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
1009 1.13 lukem el->el_tty.t_ex.c_iflag =
1010 1.13 lukem el->el_tty.t_ts.c_iflag;
1011 1.13 lukem el->el_tty.t_ex.c_iflag &=
1012 1.13 lukem ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
1013 1.13 lukem el->el_tty.t_ex.c_iflag |=
1014 1.13 lukem el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
1015 1.13 lukem
1016 1.13 lukem el->el_tty.t_ed.c_iflag =
1017 1.13 lukem el->el_tty.t_ts.c_iflag;
1018 1.13 lukem el->el_tty.t_ed.c_iflag &=
1019 1.13 lukem ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
1020 1.13 lukem el->el_tty.t_ed.c_iflag |=
1021 1.13 lukem el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
1022 1.13 lukem }
1023 1.13 lukem if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
1024 1.13 lukem (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
1025 1.13 lukem el->el_tty.t_ex.c_oflag =
1026 1.13 lukem el->el_tty.t_ts.c_oflag;
1027 1.13 lukem el->el_tty.t_ex.c_oflag &=
1028 1.13 lukem ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
1029 1.13 lukem el->el_tty.t_ex.c_oflag |=
1030 1.13 lukem el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
1031 1.13 lukem
1032 1.13 lukem el->el_tty.t_ed.c_oflag =
1033 1.13 lukem el->el_tty.t_ts.c_oflag;
1034 1.13 lukem el->el_tty.t_ed.c_oflag &=
1035 1.13 lukem ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
1036 1.13 lukem el->el_tty.t_ed.c_oflag |=
1037 1.13 lukem el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
1038 1.13 lukem }
1039 1.13 lukem if (tty__gettabs(&el->el_tty.t_ex) == 0)
1040 1.13 lukem el->el_tty.t_tabs = 0;
1041 1.13 lukem else
1042 1.13 lukem el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
1043 1.1 cgd
1044 1.13 lukem {
1045 1.13 lukem int i;
1046 1.1 cgd
1047 1.13 lukem tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
1048 1.13 lukem /*
1049 1.13 lukem * Check if the user made any changes.
1050 1.13 lukem * If he did, then propagate the changes to the
1051 1.13 lukem * edit and execute data structures.
1052 1.13 lukem */
1053 1.13 lukem for (i = 0; i < C_NCC; i++)
1054 1.13 lukem if (el->el_tty.t_c[TS_IO][i] !=
1055 1.13 lukem el->el_tty.t_c[EX_IO][i])
1056 1.13 lukem break;
1057 1.13 lukem
1058 1.13 lukem if (i != C_NCC) {
1059 1.13 lukem /*
1060 1.13 lukem * Propagate changes only to the unprotected
1061 1.13 lukem * chars that have been modified just now.
1062 1.13 lukem */
1063 1.13 lukem for (i = 0; i < C_NCC; i++) {
1064 1.13 lukem if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
1065 1.13 lukem && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
1066 1.13 lukem el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
1067 1.13 lukem if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
1068 1.13 lukem el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
1069 1.13 lukem }
1070 1.13 lukem tty_bind_char(el, 0);
1071 1.13 lukem tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
1072 1.13 lukem
1073 1.13 lukem for (i = 0; i < C_NCC; i++) {
1074 1.13 lukem if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
1075 1.13 lukem && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
1076 1.13 lukem el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
1077 1.13 lukem if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
1078 1.13 lukem el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
1079 1.13 lukem }
1080 1.13 lukem tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
1081 1.13 lukem }
1082 1.1 cgd }
1083 1.1 cgd }
1084 1.26 christos if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
1085 1.1 cgd #ifdef DEBUG_TTY
1086 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
1087 1.13 lukem strerror(errno));
1088 1.1 cgd #endif /* DEBUG_TTY */
1089 1.38 christos return -1;
1090 1.13 lukem }
1091 1.13 lukem el->el_tty.t_mode = ED_IO;
1092 1.38 christos return 0;
1093 1.13 lukem }
1094 1.1 cgd
1095 1.1 cgd
1096 1.1 cgd /* tty_cookedmode():
1097 1.1 cgd * Set the tty back to normal mode
1098 1.1 cgd */
1099 1.1 cgd protected int
1100 1.13 lukem tty_cookedmode(EditLine *el)
1101 1.1 cgd { /* set tty in normal setup */
1102 1.1 cgd
1103 1.13 lukem if (el->el_tty.t_mode == EX_IO)
1104 1.38 christos return 0;
1105 1.13 lukem
1106 1.13 lukem if (el->el_flags & EDIT_DISABLED)
1107 1.38 christos return 0;
1108 1.13 lukem
1109 1.26 christos if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
1110 1.1 cgd #ifdef DEBUG_TTY
1111 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
1112 1.13 lukem strerror(errno));
1113 1.1 cgd #endif /* DEBUG_TTY */
1114 1.38 christos return -1;
1115 1.13 lukem }
1116 1.13 lukem el->el_tty.t_mode = EX_IO;
1117 1.38 christos return 0;
1118 1.13 lukem }
1119 1.1 cgd
1120 1.1 cgd
1121 1.1 cgd /* tty_quotemode():
1122 1.1 cgd * Turn on quote mode
1123 1.1 cgd */
1124 1.1 cgd protected int
1125 1.13 lukem tty_quotemode(EditLine *el)
1126 1.1 cgd {
1127 1.13 lukem if (el->el_tty.t_mode == QU_IO)
1128 1.38 christos return 0;
1129 1.1 cgd
1130 1.13 lukem el->el_tty.t_qu = el->el_tty.t_ed;
1131 1.1 cgd
1132 1.13 lukem el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
1133 1.13 lukem el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
1134 1.1 cgd
1135 1.13 lukem el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
1136 1.13 lukem el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
1137 1.1 cgd
1138 1.13 lukem el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
1139 1.13 lukem el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
1140 1.1 cgd
1141 1.13 lukem el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
1142 1.13 lukem el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
1143 1.1 cgd
1144 1.26 christos if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
1145 1.1 cgd #ifdef DEBUG_TTY
1146 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
1147 1.13 lukem strerror(errno));
1148 1.1 cgd #endif /* DEBUG_TTY */
1149 1.38 christos return -1;
1150 1.13 lukem }
1151 1.13 lukem el->el_tty.t_mode = QU_IO;
1152 1.38 christos return 0;
1153 1.13 lukem }
1154 1.1 cgd
1155 1.1 cgd
1156 1.1 cgd /* tty_noquotemode():
1157 1.1 cgd * Turn off quote mode
1158 1.1 cgd */
1159 1.1 cgd protected int
1160 1.13 lukem tty_noquotemode(EditLine *el)
1161 1.1 cgd {
1162 1.13 lukem
1163 1.13 lukem if (el->el_tty.t_mode != QU_IO)
1164 1.38 christos return 0;
1165 1.26 christos if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
1166 1.1 cgd #ifdef DEBUG_TTY
1167 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
1168 1.13 lukem strerror(errno));
1169 1.1 cgd #endif /* DEBUG_TTY */
1170 1.38 christos return -1;
1171 1.13 lukem }
1172 1.13 lukem el->el_tty.t_mode = ED_IO;
1173 1.38 christos return 0;
1174 1.1 cgd }
1175 1.1 cgd
1176 1.13 lukem
1177 1.1 cgd /* tty_stty():
1178 1.1 cgd * Stty builtin
1179 1.1 cgd */
1180 1.1 cgd protected int
1181 1.1 cgd /*ARGSUSED*/
1182 1.32 christos tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
1183 1.1 cgd {
1184 1.14 jdolecek const ttymodes_t *m;
1185 1.16 christos char x;
1186 1.13 lukem int aflag = 0;
1187 1.32 christos const Char *s, *d;
1188 1.32 christos char name[EL_BUFSIZ];
1189 1.19 christos struct termios *tios = &el->el_tty.t_ex;
1190 1.13 lukem int z = EX_IO;
1191 1.13 lukem
1192 1.13 lukem if (argv == NULL)
1193 1.38 christos return -1;
1194 1.32 christos strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
1195 1.32 christos name[sizeof(name) - 1] = '\0';
1196 1.13 lukem
1197 1.13 lukem while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1198 1.13 lukem switch (argv[0][1]) {
1199 1.13 lukem case 'a':
1200 1.13 lukem aflag++;
1201 1.13 lukem argv++;
1202 1.13 lukem break;
1203 1.13 lukem case 'd':
1204 1.13 lukem argv++;
1205 1.19 christos tios = &el->el_tty.t_ed;
1206 1.13 lukem z = ED_IO;
1207 1.13 lukem break;
1208 1.13 lukem case 'x':
1209 1.13 lukem argv++;
1210 1.19 christos tios = &el->el_tty.t_ex;
1211 1.13 lukem z = EX_IO;
1212 1.13 lukem break;
1213 1.13 lukem case 'q':
1214 1.13 lukem argv++;
1215 1.19 christos tios = &el->el_tty.t_ts;
1216 1.13 lukem z = QU_IO;
1217 1.13 lukem break;
1218 1.13 lukem default:
1219 1.13 lukem (void) fprintf(el->el_errfile,
1220 1.13 lukem "%s: Unknown switch `%c'.\n",
1221 1.13 lukem name, argv[0][1]);
1222 1.38 christos return -1;
1223 1.13 lukem }
1224 1.1 cgd
1225 1.13 lukem if (!argv || !*argv) {
1226 1.13 lukem int i = -1;
1227 1.29 christos size_t len = 0, st = 0, cu;
1228 1.13 lukem for (m = ttymodes; m->m_name; m++) {
1229 1.13 lukem if (m->m_type != i) {
1230 1.13 lukem (void) fprintf(el->el_outfile, "%s%s",
1231 1.13 lukem i != -1 ? "\n" : "",
1232 1.13 lukem el->el_tty.t_t[z][m->m_type].t_name);
1233 1.13 lukem i = m->m_type;
1234 1.13 lukem st = len =
1235 1.13 lukem strlen(el->el_tty.t_t[z][m->m_type].t_name);
1236 1.13 lukem }
1237 1.24 christos if (i != -1) {
1238 1.24 christos x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
1239 1.24 christos ? '+' : '\0';
1240 1.40 christos
1241 1.40 christos if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
1242 1.40 christos x = '-';
1243 1.24 christos } else {
1244 1.24 christos x = '\0';
1245 1.24 christos }
1246 1.13 lukem
1247 1.13 lukem if (x != '\0' || aflag) {
1248 1.13 lukem
1249 1.13 lukem cu = strlen(m->m_name) + (x != '\0') + 1;
1250 1.13 lukem
1251 1.42 christos if (len + cu >=
1252 1.42 christos (size_t)el->el_terminal.t_size.h) {
1253 1.13 lukem (void) fprintf(el->el_outfile, "\n%*s",
1254 1.29 christos (int)st, "");
1255 1.13 lukem len = st + cu;
1256 1.13 lukem } else
1257 1.13 lukem len += cu;
1258 1.13 lukem
1259 1.13 lukem if (x != '\0')
1260 1.13 lukem (void) fprintf(el->el_outfile, "%c%s ",
1261 1.13 lukem x, m->m_name);
1262 1.13 lukem else
1263 1.13 lukem (void) fprintf(el->el_outfile, "%s ",
1264 1.13 lukem m->m_name);
1265 1.13 lukem }
1266 1.1 cgd }
1267 1.13 lukem (void) fprintf(el->el_outfile, "\n");
1268 1.38 christos return 0;
1269 1.1 cgd }
1270 1.13 lukem while (argv && (s = *argv++)) {
1271 1.32 christos const Char *p;
1272 1.13 lukem switch (*s) {
1273 1.13 lukem case '+':
1274 1.13 lukem case '-':
1275 1.40 christos x = (char)*s++;
1276 1.13 lukem break;
1277 1.13 lukem default:
1278 1.13 lukem x = '\0';
1279 1.13 lukem break;
1280 1.13 lukem }
1281 1.13 lukem d = s;
1282 1.32 christos p = Strchr(s, '=');
1283 1.13 lukem for (m = ttymodes; m->m_name; m++)
1284 1.42 christos if ((p ? strncmp(m->m_name, ct_encode_string(d,
1285 1.42 christos &el->el_scratch), (size_t)(p - d)) :
1286 1.42 christos strcmp(m->m_name, ct_encode_string(d,
1287 1.42 christos &el->el_scratch))) == 0 &&
1288 1.19 christos (p == NULL || m->m_type == MD_CHAR))
1289 1.13 lukem break;
1290 1.13 lukem
1291 1.13 lukem if (!m->m_name) {
1292 1.13 lukem (void) fprintf(el->el_errfile,
1293 1.32 christos "%s: Invalid argument `" FSTR "'.\n", name, d);
1294 1.38 christos return -1;
1295 1.19 christos }
1296 1.19 christos if (p) {
1297 1.19 christos int c = ffs((int)m->m_value);
1298 1.32 christos int v = *++p ? parse__escape(&p) :
1299 1.19 christos el->el_tty.t_vdisable;
1300 1.31 christos assert(c != 0);
1301 1.31 christos c--;
1302 1.19 christos c = tty__getcharindex(c);
1303 1.19 christos assert(c != -1);
1304 1.40 christos tios->c_cc[c] = (cc_t)v;
1305 1.19 christos continue;
1306 1.13 lukem }
1307 1.13 lukem switch (x) {
1308 1.13 lukem case '+':
1309 1.13 lukem el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1310 1.13 lukem el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1311 1.13 lukem break;
1312 1.13 lukem case '-':
1313 1.13 lukem el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1314 1.13 lukem el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1315 1.13 lukem break;
1316 1.13 lukem default:
1317 1.13 lukem el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1318 1.13 lukem el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1319 1.13 lukem break;
1320 1.13 lukem }
1321 1.1 cgd }
1322 1.27 christos
1323 1.27 christos if (el->el_tty.t_mode == z) {
1324 1.27 christos if (tty_setty(el, TCSADRAIN, tios) == -1) {
1325 1.27 christos #ifdef DEBUG_TTY
1326 1.42 christos (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
1327 1.42 christos __func__, strerror(errno));
1328 1.27 christos #endif /* DEBUG_TTY */
1329 1.38 christos return -1;
1330 1.27 christos }
1331 1.27 christos }
1332 1.27 christos
1333 1.38 christos return 0;
1334 1.13 lukem }
1335 1.1 cgd
1336 1.1 cgd
1337 1.1 cgd #ifdef notyet
1338 1.1 cgd /* tty_printchar():
1339 1.1 cgd * DEbugging routine to print the tty characters
1340 1.1 cgd */
1341 1.1 cgd private void
1342 1.13 lukem tty_printchar(EditLine *el, unsigned char *s)
1343 1.1 cgd {
1344 1.13 lukem ttyperm_t *m;
1345 1.13 lukem int i;
1346 1.1 cgd
1347 1.13 lukem for (i = 0; i < C_NCC; i++) {
1348 1.13 lukem for (m = el->el_tty.t_t; m->m_name; m++)
1349 1.13 lukem if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
1350 1.13 lukem break;
1351 1.13 lukem if (m->m_name)
1352 1.13 lukem (void) fprintf(el->el_errfile, "%s ^%c ",
1353 1.13 lukem m->m_name, s[i] + 'A' - 1);
1354 1.13 lukem if (i % 5 == 0)
1355 1.13 lukem (void) fprintf(el->el_errfile, "\n");
1356 1.13 lukem }
1357 1.13 lukem (void) fprintf(el->el_errfile, "\n");
1358 1.1 cgd }
1359 1.1 cgd #endif /* notyet */
1360