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