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