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