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