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