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