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