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