1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)tty.c 7.17 (Berkeley) 05/09/89 7 */ 8 9 #include "param.h" 10 #include "systm.h" 11 #include "user.h" 12 #include "ioctl.h" 13 #include "tty.h" 14 #define TTYDEFCHARS 15 #include "ttydefaults.h" 16 #undef TTYDEFCHARS 17 #include "termios.h" 18 #include "proc.h" 19 #include "file.h" 20 #include "conf.h" 21 #include "dkstat.h" 22 #include "uio.h" 23 #include "kernel.h" 24 #include "vnode.h" 25 #include "syslog.h" 26 27 #include "machine/reg.h" 28 29 /* 30 * Table giving parity for characters and indicating 31 * character classes to tty driver. The 8th bit 32 * indicates parity, the 7th bit indicates the character 33 * is an alphameric or underscore (for ALTWERASE), and the 34 * low 6 bits indicate delay type. If the low 6 bits are 0 35 * then the character needs no special processing on output. 36 */ 37 38 char partab[] = { 39 0001,0201,0201,0001,0201,0001,0001,0201, /* nul - bel */ 40 0202,0004,0003,0201,0005,0206,0201,0001, /* bs - si */ 41 0201,0001,0001,0201,0001,0201,0201,0001, /* dle - etb */ 42 0001,0201,0201,0001,0201,0001,0001,0201, /* can - us */ 43 0200,0000,0000,0200,0000,0200,0200,0000, /* sp - ' */ 44 0000,0200,0200,0000,0200,0000,0000,0200, /* ( - / */ 45 0100,0300,0300,0100,0300,0100,0100,0300, /* 0 - 7 */ 46 0300,0100,0000,0200,0000,0200,0200,0000, /* 8 - ? */ 47 0200,0100,0100,0300,0100,0300,0300,0100, /* @ - G */ 48 0100,0300,0300,0100,0300,0100,0100,0300, /* H - O */ 49 0100,0300,0300,0100,0300,0100,0100,0300, /* P - W */ 50 0300,0100,0100,0200,0000,0200,0200,0300, /* X - _ */ 51 0000,0300,0300,0100,0300,0100,0100,0300, /* ` - g */ 52 0300,0100,0100,0300,0100,0300,0300,0100, /* h - o */ 53 0300,0100,0100,0300,0100,0300,0300,0100, /* p - w */ 54 0100,0300,0300,0000,0200,0000,0000,0201, /* x - del */ 55 /* 56 * meta chars 57 */ 58 0001,0201,0201,0001,0201,0001,0001,0201, /* nul - bel */ 59 0202,0004,0003,0201,0005,0206,0201,0001, /* bs - si */ 60 0201,0001,0001,0201,0001,0201,0201,0001, /* dle - etb */ 61 0001,0201,0201,0001,0201,0001,0001,0201, /* can - us */ 62 0200,0000,0000,0200,0000,0200,0200,0000, /* sp - ' */ 63 0000,0200,0200,0000,0200,0000,0000,0200, /* ( - / */ 64 0100,0300,0300,0100,0300,0100,0100,0300, /* 0 - 7 */ 65 0300,0100,0000,0200,0000,0200,0200,0000, /* 8 - ? */ 66 0200,0100,0100,0300,0100,0300,0300,0100, /* @ - G */ 67 0100,0300,0300,0100,0300,0100,0100,0300, /* H - O */ 68 0100,0300,0300,0100,0300,0100,0100,0300, /* P - W */ 69 0300,0100,0100,0200,0000,0200,0200,0300, /* X - _ */ 70 0000,0300,0300,0100,0300,0100,0100,0300, /* ` - g */ 71 0300,0100,0100,0300,0100,0300,0300,0100, /* h - o */ 72 0300,0100,0100,0300,0100,0300,0300,0100, /* p - w */ 73 0100,0300,0300,0000,0200,0000,0000,0201, /* x - del */ 74 }; 75 76 extern struct tty *constty; /* temporary virtual console */ 77 extern char partab[], maptab[]; 78 79 /* 80 * Is 'c' a line delimiter ("break" character)? 81 */ 82 #define ttbreakc(c) (c == '\n' || CCEQ(cc[VEOF], c) || \ 83 CCEQ(cc[VEOL], c) || CCEQ(cc[VEOL2], c)) 84 85 ttychars(tp) 86 struct tty *tp; 87 { 88 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 89 } 90 91 /* 92 * Wait for output to drain, then flush input waiting. 93 */ 94 ttywflush(tp) 95 struct tty *tp; 96 { 97 98 ttywait(tp); 99 ttyflush(tp, FREAD); 100 } 101 102 /* 103 * Wait for output to drain. 104 */ 105 ttywait(tp) 106 register struct tty *tp; 107 { 108 int s = spltty(); 109 110 while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) && 111 (tp->t_state&TS_CARR_ON || tp->t_cflag&CLOCAL) && 112 tp->t_oproc) { 113 (*tp->t_oproc)(tp); 114 tp->t_state |= TS_ASLEEP; 115 sleep((caddr_t)&tp->t_outq, TTOPRI); 116 } 117 splx(s); 118 } 119 120 /* 121 * Flush all TTY queues 122 */ 123 ttyflush(tp, rw) 124 register struct tty *tp; 125 { 126 register s; 127 128 s = spltty(); 129 if (rw & FREAD) { 130 while (getc(&tp->t_canq) >= 0) 131 ; 132 ttwakeup(tp); 133 } 134 if (rw & FWRITE) { 135 wakeup((caddr_t)&tp->t_outq); /* XXX? what about selwakeup? */ 136 tp->t_state &= ~TS_TTSTOP; 137 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 138 while (getc(&tp->t_outq) >= 0) 139 ; 140 } 141 if (rw & FREAD) { 142 while (getc(&tp->t_rawq) >= 0) 143 ; 144 tp->t_rocount = 0; 145 tp->t_rocol = 0; 146 tp->t_state &= ~TS_LOCAL; 147 } 148 splx(s); 149 } 150 151 /* 152 * Send stop character on input overflow. 153 */ 154 ttyblock(tp) 155 register struct tty *tp; 156 { 157 register x; 158 159 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 160 if (tp->t_rawq.c_cc > TTYHOG) { 161 ttyflush(tp, FREAD|FWRITE); 162 tp->t_state &= ~TS_TBLOCK; 163 } 164 /* 165 * Block further input iff: 166 * Current input > threshold AND input is available to user program 167 */ 168 if (x >= TTYHOG/2 && 169 (!(tp->t_lflag&ICANON)) || (tp->t_canq.c_cc > 0) && 170 tp->t_cc[VSTOP] != _POSIX_VDISABLE) { 171 if (putc(tp->t_cc[VSTOP], &tp->t_outq)==0) { 172 tp->t_state |= TS_TBLOCK; 173 ttstart(tp); 174 } 175 } 176 } 177 178 /* 179 * Restart typewriter output following a delay 180 * timeout. 181 * The name of the routine is passed to the timeout 182 * subroutine and it is called during a clock interrupt. 183 */ 184 ttrstrt(tp) 185 struct tty *tp; 186 { 187 188 if (tp == 0) 189 panic("ttrstrt"); 190 tp->t_state &= ~TS_TIMEOUT; 191 ttstart(tp); 192 } 193 194 /* 195 * Start output on the typewriter. It is used from the top half 196 * after some characters have been put on the output queue, 197 * from the interrupt routine to transmit the next 198 * character, and after a timeout has finished. 199 */ 200 ttstart(tp) 201 struct tty *tp; 202 { 203 204 if (tp->t_oproc) /* kludge for pty */ 205 (*tp->t_oproc)(tp); 206 } 207 208 /* 209 * Common code for tty ioctls. 210 */ 211 /*ARGSUSED*/ 212 ttioctl(tp, com, data, flag) 213 register struct tty *tp; 214 caddr_t data; 215 { 216 extern int nldisp; 217 int softset = 0; 218 int s, error; 219 220 221 /* 222 * If the ioctl involves modification, 223 * hang if in the background. 224 */ 225 switch (com) { 226 227 case TIOCSETD: 228 case TIOCFLUSH: 229 /*case TIOCSPGRP:*/ 230 case TIOCSTI: 231 case TIOCSWINSZ: 232 case TIOCSETA: 233 case TIOCSETAW: 234 case TIOCSETAF: 235 case TIOCSETAS: 236 case TIOCSETAWS: 237 case TIOCSETAFS: 238 while (u.u_procp->p_pgid != tp->t_pgid && 239 tp == u.u_ttyp && 240 u.u_procp->p_pgrp->pg_jobc && 241 (u.u_procp->p_flag&SVFORK) == 0 && 242 !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) && 243 !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) { 244 pgsignal(u.u_procp->p_pgrp, SIGTTOU); 245 sleep((caddr_t)&lbolt, TTOPRI); 246 } 247 break; 248 } 249 250 /* 251 * Process the ioctl. 252 */ 253 switch (com) { 254 255 /* get discipline number */ 256 case TIOCGETD: 257 *(int *)data = tp->t_line; 258 break; 259 260 /* set line discipline */ 261 case TIOCSETD: { 262 register int t = *(int *)data; 263 dev_t dev = tp->t_dev; 264 int error = 0; 265 266 if ((unsigned)t >= nldisp) 267 return (ENXIO); 268 if (t != tp->t_line) { 269 s = spltty(); 270 (*linesw[tp->t_line].l_close)(tp); 271 error = (*linesw[t].l_open)(dev, tp); 272 if (error) { 273 (void)(*linesw[tp->t_line].l_open)(dev, tp); 274 splx(s); 275 return (error); 276 } 277 tp->t_line = t; 278 splx(s); 279 } 280 break; 281 } 282 283 /* prevent more opens on channel */ 284 case TIOCEXCL: 285 tp->t_state |= TS_XCLUDE; 286 break; 287 288 case TIOCNXCL: 289 tp->t_state &= ~TS_XCLUDE; 290 break; 291 292 case TIOCHPCL: 293 tp->t_cflag |= HUPCL; 294 break; 295 296 case TIOCFLUSH: { 297 register int flags = *(int *)data; 298 299 if (flags == 0) 300 flags = FREAD|FWRITE; 301 else 302 flags &= FREAD|FWRITE; 303 ttyflush(tp, flags); 304 break; 305 } 306 307 case FIOASYNC: 308 if (*(int *)data) 309 tp->t_state |= TS_ASYNC; 310 else 311 tp->t_state &= ~TS_ASYNC; 312 break; 313 314 case FIONBIO: 315 break; /* XXX remove */ 316 317 /* return number of characters immediately available */ 318 case FIONREAD: 319 *(off_t *)data = ttnread(tp); 320 break; 321 322 case TIOCOUTQ: 323 *(int *)data = tp->t_outq.c_cc; 324 break; 325 326 case TIOCSTOP: 327 s = spltty(); 328 if ((tp->t_state&TS_TTSTOP) == 0) { 329 tp->t_state |= TS_TTSTOP; 330 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 331 } 332 splx(s); 333 break; 334 335 case TIOCSTART: 336 s = spltty(); 337 if ((tp->t_state&TS_TTSTOP) || (tp->t_lflag&FLUSHO)) { 338 tp->t_state &= ~TS_TTSTOP; 339 tp->t_lflag &= ~FLUSHO; 340 ttstart(tp); 341 } 342 splx(s); 343 break; 344 345 /* 346 * Simulate typing of a character at the terminal. 347 */ 348 case TIOCSTI: 349 if (u.u_uid && (flag & FREAD) == 0) 350 return (EPERM); 351 if (u.u_uid && u.u_ttyp != tp) 352 return (EACCES); 353 (*linesw[tp->t_line].l_rint)(*(char *)data, tp); 354 break; 355 356 case TIOCGETA: { 357 struct termios *t = (struct termios *)data; 358 359 bcopy(&tp->t_termios, t, sizeof(struct termios)); 360 break; 361 } 362 363 case TIOCSETAS: 364 case TIOCSETAWS: 365 case TIOCSETAFS: 366 softset = 1; 367 /*FALLTHROUGH*/ 368 case TIOCSETA: 369 case TIOCSETAW: 370 case TIOCSETAF: { 371 register struct termios *t = (struct termios *)data; 372 int error; 373 374 s = spltty(); 375 if (!softset) { 376 /* 377 * set device hardware 378 */ 379 if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 380 splx(s); 381 return (error); 382 } else { 383 if (!(tp->t_state&TS_CARR_ON) && 384 (tp->t_cflag&CLOCAL) && 385 !(t->c_cflag&CLOCAL)) { 386 tp->t_state &= ~TS_ISOPEN; 387 tp->t_state |= TS_WOPEN; 388 ttwakeup(tp); 389 } 390 tp->t_cflag = t->c_cflag; 391 tp->t_ispeed = t->c_ispeed; 392 tp->t_ospeed = t->c_ospeed; 393 } 394 ttsetwater(tp); 395 } 396 if (com == TIOCSETAF || com == TIOCSETAFS) 397 ttywflush(tp); 398 else { 399 if (com == TIOCSETAW || com == TIOCSETAWS) 400 ttywait(tp); 401 if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON)) 402 if (t->c_lflag&ICANON) { 403 tp->t_lflag |= PENDIN; 404 ttwakeup(tp); 405 } 406 else { 407 struct clist tq; 408 409 catq(&tp->t_rawq, &tp->t_canq); 410 tq = tp->t_rawq; 411 tp->t_rawq = tp->t_canq; 412 tp->t_canq = tq; 413 } 414 } 415 tp->t_iflag = t->c_iflag; 416 tp->t_oflag = t->c_oflag; 417 tp->t_lflag = t->c_lflag; 418 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 419 splx(s); 420 break; 421 } 422 423 /* 424 * Acquire controlling terminal. 425 */ 426 case TIOCSCTTY: { 427 register struct proc *p = u.u_procp; 428 429 /* RETHINK - whether non-session leader 430 * can allocate a new ctty for a session. 431 */ 432 if (u.u_ttyp || 433 (tp->t_session && tp->t_session != p->p_session) || 434 (!tp->t_session && !SESS_LEADER(p))) 435 return(EPERM); 436 u.u_ttyp = tp; 437 u.u_ttyd = tp->t_dev; 438 if (tp->t_pgid == 0) 439 tp->t_pgid = p->p_pgrp->pg_id; 440 tp->t_session = p->p_session; 441 break; 442 } 443 444 /* 445 * Set terminal process group. 446 */ 447 case TIOCSPGRP: { 448 register struct proc *p = u.u_procp; 449 register struct pgrp *pgrp = pgfind(*(int *)data); 450 451 if (u.u_uid && 452 (tp != u.u_ttyp || 453 (pgrp && pgrp->pg_session != p->p_session))) { 454 if (u.u_ttyp == NULL) 455 return (ENOTTY); 456 else 457 return (EPERM); 458 } 459 tp->t_pgid = *(int *)data; 460 break; 461 } 462 463 case TIOCGPGRP: 464 *(int *)data = tp->t_pgid; 465 break; 466 467 case TIOCSWINSZ: 468 if (bcmp((caddr_t)&tp->t_winsize, data, 469 sizeof (struct winsize))) { 470 tp->t_winsize = *(struct winsize *)data; 471 gsignal(tp->t_pgid, SIGWINCH); 472 } 473 break; 474 475 case TIOCGWINSZ: 476 *(struct winsize *)data = tp->t_winsize; 477 break; 478 479 case TIOCCONS: 480 if (*(int *)data) { 481 if (constty != NULL) 482 return (EBUSY); 483 #ifndef UCONSOLE 484 if (error = suser(u.u_cred, &u.u_acflag)) 485 return (error); 486 #endif 487 constty = tp; 488 } else if (tp == constty) 489 constty = NULL; 490 break; 491 492 #ifdef COMPAT_43 493 case TIOCGETP: 494 case TIOCSETP: 495 case TIOCSETN: 496 case TIOCGETC: 497 case TIOCSETC: 498 case TIOCSLTC: 499 case TIOCGLTC: 500 case TIOCLBIS: 501 case TIOCLBIC: 502 case TIOCLSET: 503 case TIOCLGET: 504 case TIOCGETDCOMPAT: 505 case TIOCSETDCOMPAT: 506 return(ttcompat(tp, com, data, flag)); 507 #endif 508 509 default: 510 return (-1); 511 } 512 return (0); 513 } 514 515 ttnread(tp) 516 struct tty *tp; 517 { 518 int nread = 0; 519 520 if (tp->t_lflag & PENDIN) 521 ttypend(tp); 522 nread = tp->t_canq.c_cc; 523 if ((tp->t_lflag & ICANON) == 0) 524 nread += tp->t_rawq.c_cc; 525 return (nread); 526 } 527 528 ttselect(dev, rw) 529 dev_t dev; 530 int rw; 531 { 532 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 533 int nread; 534 int s = spltty(); 535 536 switch (rw) { 537 538 case FREAD: 539 nread = ttnread(tp); 540 if (nread > 0 || 541 (!(tp->t_cflag&CLOCAL) && !(tp->t_state&TS_CARR_ON))) 542 goto win; 543 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 544 tp->t_state |= TS_RCOLL; 545 else 546 tp->t_rsel = u.u_procp; 547 break; 548 549 case FWRITE: 550 if (tp->t_outq.c_cc <= tp->t_lowat) 551 goto win; 552 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 553 tp->t_state |= TS_WCOLL; 554 else 555 tp->t_wsel = u.u_procp; 556 break; 557 } 558 splx(s); 559 return (0); 560 win: 561 splx(s); 562 return (1); 563 } 564 565 /* 566 * Initial open of tty, or (re)entry to line discipline. 567 */ 568 ttyopen(dev, tp) 569 dev_t dev; 570 register struct tty *tp; 571 { 572 573 tp->t_dev = dev; 574 575 tp->t_state &= ~TS_WOPEN; 576 if ((tp->t_state & TS_ISOPEN) == 0) { 577 tp->t_state |= TS_ISOPEN; 578 bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize)); 579 } 580 return (0); 581 } 582 583 /* 584 * "close" a line discipline 585 */ 586 ttylclose(tp) 587 register struct tty *tp; 588 { 589 590 ttywflush(tp); 591 } 592 593 /* 594 * clean tp on last close 595 */ 596 ttyclose(tp) 597 register struct tty *tp; 598 { 599 if (constty == tp) 600 constty = NULL; 601 ttyflush(tp, FREAD|FWRITE); 602 tp->t_pgid = 0; 603 tp->t_state = 0; 604 } 605 606 /* 607 * Handle modem control transition on a tty. 608 * Flag indicates new state of carrier. 609 * Returns 0 if the line should be turned off, otherwise 1. 610 */ 611 ttymodem(tp, flag) 612 register struct tty *tp; 613 { 614 615 if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag & MDMBUF)) { 616 /* 617 * MDMBUF: do flow control according to carrier flag 618 */ 619 if (flag) { 620 tp->t_state &= ~TS_TTSTOP; 621 ttstart(tp); 622 } else if ((tp->t_state&TS_TTSTOP) == 0) { 623 tp->t_state |= TS_TTSTOP; 624 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 625 } 626 } else if (flag == 0) { 627 /* 628 * Lost carrier. 629 */ 630 tp->t_state &= ~TS_CARR_ON; 631 if (tp->t_state & TS_ISOPEN) { 632 if ((tp->t_lflag & NOHANG) == 0) { 633 gsignal(tp->t_pgid, SIGHUP); 634 gsignal(tp->t_pgid, SIGCONT); 635 ttyflush(tp, FREAD|FWRITE); 636 return (0); 637 } 638 } 639 } else { 640 /* 641 * Carrier now on. 642 */ 643 tp->t_state |= TS_CARR_ON; 644 ttwakeup(tp); 645 } 646 return (1); 647 } 648 649 /* 650 * Default modem control routine (for other line disciplines). 651 * Return argument flag, to turn off device on carrier drop. 652 */ 653 nullmodem(tp, flag) 654 register struct tty *tp; 655 int flag; 656 { 657 658 if (flag) 659 tp->t_state |= TS_CARR_ON; 660 else 661 tp->t_state &= ~TS_CARR_ON; 662 return (flag); 663 } 664 665 /* 666 * reinput pending characters after state switch 667 * call at spltty(). 668 */ 669 ttypend(tp) 670 register struct tty *tp; 671 { 672 struct clist tq; 673 register c; 674 675 tp->t_lflag &= ~PENDIN; 676 tp->t_state |= TS_TYPEN; 677 tq = tp->t_rawq; 678 tp->t_rawq.c_cc = 0; 679 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 680 while ((c = getc(&tq)) >= 0) 681 ttyinput(c, tp); 682 tp->t_state &= ~TS_TYPEN; 683 } 684 685 /* 686 * 687 * Place a character on raw TTY input queue, 688 * putting in delimiters and waking up top 689 * half as needed. Also echo if required. 690 * The arguments are the character and the 691 * appropriate tty structure. 692 */ 693 ttyinput(c, tp) 694 register c; 695 register struct tty *tp; 696 { 697 register int iflag = tp->t_iflag; 698 register int lflag = tp->t_lflag; 699 register u_char *cc = tp->t_cc; 700 int i, err; 701 702 /* 703 * If input is pending take it first. 704 */ 705 if (lflag&PENDIN) 706 ttypend(tp); 707 /* 708 * Gather stats. 709 */ 710 tk_nin++; 711 if (lflag&ICANON) { 712 tk_cancc++; 713 tp->t_cancc++; 714 } else { 715 tk_rawcc++; 716 tp->t_rawcc++; 717 } 718 /* 719 * Handle exceptional conditions (break, parity, framing). 720 */ 721 if (err = (c&TTY_ERRORMASK)) { 722 c &= ~TTY_ERRORMASK; 723 if (err&TTY_FE && !c) { /* break */ 724 if (iflag&IGNBRK) 725 goto endcase; 726 else if (iflag&BRKINT && lflag&ISIG && 727 (cc[VINTR] != _POSIX_VDISABLE)) 728 c = cc[VINTR]; 729 else { 730 c = 0; 731 if (iflag&PARMRK) 732 goto parmrk; 733 } 734 } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) { 735 if (iflag&IGNPAR) 736 goto endcase; 737 else if (iflag&PARMRK) { 738 parmrk: 739 putc(0377|TTY_QUOTE, &tp->t_rawq); 740 putc(0|TTY_QUOTE, &tp->t_rawq); 741 putc(c|TTY_QUOTE, &tp->t_rawq); 742 goto endcase; 743 } else 744 c = 0; 745 } 746 } 747 /* 748 * In tandem mode, check high water mark. 749 */ 750 if (iflag&IXOFF) 751 ttyblock(tp); 752 if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP)) 753 c &= 0177; 754 /* 755 * Check for literal nexting very first 756 */ 757 if (tp->t_state&TS_LNCH) { 758 c |= TTY_QUOTE; 759 tp->t_state &= ~TS_LNCH; 760 } 761 /* 762 * Scan for special characters. This code 763 * is really just a big case statement with 764 * non-constant cases. The bottom of the 765 * case statement is labeled ``endcase'', so goto 766 * it after a case match, or similar. 767 */ 768 /* 769 * Control chars which aren't controlled 770 * by ICANON, ISIG, or IXON. 771 */ 772 if (iflag&IEXTEN) { 773 if (CCEQ(cc[VLNEXT],c)) { 774 if (lflag&ECHO) { 775 if (lflag&ECHOE) 776 ttyout("^\b", tp); 777 else 778 ttyecho(c, tp); 779 } 780 tp->t_state |= TS_LNCH; 781 goto endcase; 782 } 783 if (CCEQ(cc[VFLUSHO],c)) { 784 if (lflag&FLUSHO) 785 tp->t_lflag &= ~FLUSHO; 786 else { 787 ttyflush(tp, FWRITE); 788 ttyecho(c, tp); 789 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 790 ttyretype(tp); 791 tp->t_lflag |= FLUSHO; 792 } 793 goto startoutput; 794 } 795 } 796 /* 797 * Signals. 798 */ 799 if (lflag&ISIG) { 800 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 801 if ((lflag&NOFLSH) == 0) 802 ttyflush(tp, FREAD|FWRITE); 803 ttyecho(c, tp); 804 gsignal(tp->t_pgid, CCEQ(cc[VINTR],c) ? 805 SIGINT : SIGQUIT); 806 goto endcase; 807 } 808 if (CCEQ(cc[VSUSP],c)) { 809 if ((lflag&NOFLSH) == 0) 810 ttyflush(tp, FREAD); 811 ttyecho(c, tp); 812 gsignal(tp->t_pgid, SIGTSTP); 813 goto endcase; 814 } 815 } 816 /* 817 * Handle start/stop characters. 818 */ 819 if (iflag&IXON) { 820 if (CCEQ(cc[VSTOP],c)) { 821 if ((tp->t_state&TS_TTSTOP) == 0) { 822 tp->t_state |= TS_TTSTOP; 823 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 824 return; 825 } 826 if (!CCEQ(cc[VSTART], c)) 827 return; 828 /* 829 * if VSTART == VSTOP then toggle 830 */ 831 goto endcase; 832 } 833 if (CCEQ(cc[VSTART], c)) 834 goto restartoutput; 835 } 836 /* 837 * IGNCR, ICRNL, & INLCR 838 */ 839 if (c == '\r') { 840 if (iflag&IGNCR) 841 goto endcase; 842 else if (iflag&ICRNL) 843 c = '\n'; 844 } 845 else if (c == '\n' && iflag&INLCR) 846 c = '\r'; 847 /* 848 * Non canonical mode; don't process line editing 849 * characters; check high water mark for wakeup. 850 * 851 */ 852 if (!(lflag&ICANON)) { 853 if (tp->t_rawq.c_cc > TTYHOG) { 854 if (iflag&IMAXBEL) { 855 if (tp->t_outq.c_cc < tp->t_hiwat) 856 (void) ttyoutput(CTRL('g'), tp); 857 } else 858 ttyflush(tp, FREAD | FWRITE); 859 } else { 860 if (putc(c, &tp->t_rawq) >= 0) { 861 ttwakeup(tp); 862 ttyecho(c, tp); 863 } 864 } 865 goto endcase; 866 } 867 /* 868 * From here on down canonical mode character 869 * processing takes place. 870 */ 871 /* 872 * erase (^H / ^?) 873 */ 874 if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c)) { 875 if (tp->t_rawq.c_cc) 876 ttyrub(unputc(&tp->t_rawq), tp); 877 goto endcase; 878 } 879 /* 880 * kill (^U) 881 */ 882 if (CCEQ(cc[VKILL], c)) { 883 if (lflag&ECHOKE && tp->t_rawq.c_cc == tp->t_rocount && 884 !(lflag&ECHOPRT)) { 885 while (tp->t_rawq.c_cc) 886 ttyrub(unputc(&tp->t_rawq), tp); 887 } else { 888 ttyecho(c, tp); 889 if (lflag&ECHOK || lflag&ECHOKE) 890 ttyecho('\n', tp); 891 while (getc(&tp->t_rawq) > 0) 892 ; 893 tp->t_rocount = 0; 894 } 895 tp->t_state &= ~TS_LOCAL; 896 goto endcase; 897 } 898 /* 899 * word erase (^W) 900 */ 901 if (CCEQ(cc[VWERASE], c)) { 902 int ctype; 903 904 #define CTYPE(c) ((lflag&ALTWERASE) ? (partab[(c)&TTY_CHARMASK]&0100) : 0) 905 /* 906 * erase whitespace 907 */ 908 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t') 909 ttyrub(c, tp); 910 if (c == -1) 911 goto endcase; 912 /* 913 * special case last char of token 914 */ 915 ttyrub(c, tp); 916 c = unputc(&tp->t_rawq); 917 if (c == -1 || c == ' ' || c == '\t') { 918 if (c != -1) 919 (void) putc(c, &tp->t_rawq); 920 goto endcase; 921 } 922 /* 923 * erase rest of token 924 */ 925 ctype = CTYPE(c); 926 do { 927 ttyrub(c, tp); 928 c = unputc(&tp->t_rawq); 929 if (c == -1) 930 goto endcase; 931 } while (c != ' ' && c != '\t' && CTYPE(c) == ctype); 932 (void) putc(c, &tp->t_rawq); 933 goto endcase; 934 #undef CTYPE 935 } 936 /* 937 * reprint line (^R) 938 */ 939 if (CCEQ(cc[VREPRINT], c)) { 940 ttyretype(tp); 941 goto endcase; 942 } 943 /* 944 * Check for input buffer overflow 945 */ 946 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 947 if (iflag&IMAXBEL) { 948 if (tp->t_outq.c_cc < tp->t_hiwat) 949 (void) ttyoutput(CTRL('g'), tp); 950 } else 951 ttyflush(tp, FREAD | FWRITE); 952 goto endcase; 953 } 954 /* 955 * Put data char in q for user and 956 * wakeup on seeing a line delimiter. 957 */ 958 if (putc(c, &tp->t_rawq) >= 0) { 959 if (ttbreakc(c)) { 960 tp->t_rocount = 0; 961 catq(&tp->t_rawq, &tp->t_canq); 962 ttwakeup(tp); 963 } else if (tp->t_rocount++ == 0) 964 tp->t_rocol = tp->t_col; 965 if (tp->t_state&TS_ERASE) { 966 /* 967 * end of prterase \.../ 968 */ 969 tp->t_state &= ~TS_ERASE; 970 (void) ttyoutput('/', tp); 971 } 972 i = tp->t_col; 973 ttyecho(c, tp); 974 if (CCEQ(cc[VEOF], c) && lflag&ECHO) { 975 /* 976 * Place the cursor over the '^' of the ^D. 977 */ 978 i = MIN(2, tp->t_col - i); 979 while (i > 0) { 980 (void) ttyoutput('\b', tp); 981 i--; 982 } 983 } 984 } 985 endcase: 986 /* 987 * IXANY means allow any character to restart output. 988 */ 989 if ((tp->t_state&TS_TTSTOP) && !(iflag&IXANY) 990 && cc[VSTART] != cc[VSTOP]) 991 return; 992 restartoutput: 993 tp->t_state &= ~TS_TTSTOP; 994 tp->t_lflag &= ~FLUSHO; 995 startoutput: 996 ttstart(tp); 997 } 998 999 /* 1000 * Put character on TTY output queue, adding delays, 1001 * expanding tabs, and handling the CR/NL bit. 1002 * This is called both from the top half for output, 1003 * and from interrupt level for echoing. 1004 * The arguments are the character and the tty structure. 1005 * Returns < 0 if putc succeeds, otherwise returns char to resend 1006 * Must be recursive. 1007 */ 1008 ttyoutput(c, tp) 1009 register c; 1010 register struct tty *tp; 1011 { 1012 register char *colp; 1013 register ctype; 1014 register long oflag = tp->t_oflag; 1015 1016 if (!(oflag&OPOST)) { 1017 if (tp->t_lflag&FLUSHO) 1018 return (-1); 1019 if (putc(c, &tp->t_outq)) 1020 return (c); 1021 tk_nout++; 1022 tp->t_outcc++; 1023 return (-1); 1024 } 1025 c &= TTY_CHARMASK; 1026 /* 1027 * Turn tabs to spaces as required 1028 */ 1029 if (c == '\t' && oflag&OXTABS ) { 1030 register int s; 1031 1032 c = 8 - (tp->t_col&7); 1033 if ((tp->t_lflag&FLUSHO) == 0) { 1034 s = spltty(); /* don't interrupt tabs */ 1035 c -= b_to_q(" ", c, &tp->t_outq); 1036 tk_nout += c; 1037 tp->t_outcc += c; 1038 splx(s); 1039 } 1040 tp->t_col += c; 1041 return (c ? -1 : '\t'); 1042 } 1043 if (c == CEOT && oflag&ONOEOT) 1044 return(-1); 1045 tk_nout++; 1046 tp->t_outcc++; 1047 /* 1048 * turn <nl> to <cr><lf> if desired. 1049 */ 1050 if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0) 1051 return (c); 1052 if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq)) 1053 return (c); 1054 /* 1055 * Calculate delays. 1056 * The numbers here represent clock ticks 1057 * and are not necessarily optimal for all terminals. 1058 * 1059 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 1060 * 1061 * (actually, should THROW AWAY terminals which need delays) 1062 */ 1063 colp = &tp->t_col; 1064 ctype = partab[c]; 1065 c = 0; 1066 switch (ctype&077) { 1067 1068 case ORDINARY: 1069 (*colp)++; 1070 1071 case CONTROL: 1072 break; 1073 1074 case BACKSPACE: 1075 if (*colp) 1076 (*colp)--; 1077 break; 1078 1079 /* 1080 * This macro is close enough to the correct thing; 1081 * it should be replaced by real user settable delays 1082 * in any event... 1083 */ 1084 #define mstohz(ms) (((ms) * hz) >> 10) 1085 case NEWLINE: 1086 ctype = (tp->t_flags >> 8) & 03; 1087 if (ctype == 1) { /* tty 37 */ 1088 if (*colp > 0) { 1089 c = (((unsigned)*colp) >> 4) + 3; 1090 if ((unsigned)c > 6) 1091 c = 6; 1092 } 1093 } else if (ctype == 2) /* vt05 */ 1094 c = mstohz(100); 1095 *colp = 0; 1096 break; 1097 1098 case TAB: 1099 ctype = (tp->t_flags >> 10) & 03; 1100 if (ctype == 1) { /* tty 37 */ 1101 c = 1 - (*colp | ~07); 1102 if (c < 5) 1103 c = 0; 1104 } 1105 *colp |= 07; 1106 (*colp)++; 1107 break; 1108 1109 case VTAB: 1110 if (tp->t_flags&VTDELAY) /* tty 37 */ 1111 c = 0177; 1112 break; 1113 1114 case RETURN: 1115 ctype = (tp->t_flags >> 12) & 03; 1116 if (ctype == 1) /* tn 300 */ 1117 c = mstohz(83); 1118 else if (ctype == 2) /* ti 700 */ 1119 c = mstohz(166); 1120 else if (ctype == 3) { /* concept 100 */ 1121 int i; 1122 1123 if ((i = *colp) >= 0) 1124 for (; i < 9; i++) 1125 (void) putc(0177, &tp->t_outq); 1126 } 1127 *colp = 0; 1128 } 1129 if (c && (tp->t_lflag&FLUSHO) == 0) 1130 (void) putc(c|TTY_QUOTE, &tp->t_outq); 1131 return (-1); 1132 } 1133 #undef mstohz 1134 1135 /* 1136 * Called from device's read routine after it has 1137 * calculated the tty-structure given as argument. 1138 */ 1139 ttread(tp, uio, flag) 1140 register struct tty *tp; 1141 struct uio *uio; 1142 { 1143 register struct clist *qp; 1144 register int c; 1145 register long lflag = tp->t_lflag; 1146 register u_char *cc = tp->t_cc; 1147 int s, first, error = 0; 1148 1149 loop: 1150 s = spltty(); 1151 /* 1152 * take pending input first 1153 */ 1154 if (lflag&PENDIN) 1155 ttypend(tp); 1156 /* 1157 * Handle carrier. 1158 */ 1159 if (!(tp->t_state&TS_CARR_ON) && !(tp->t_cflag&CLOCAL)) { 1160 if (tp->t_state&TS_ISOPEN) { 1161 splx(s); 1162 return (0); /* EOF */ 1163 } else if (flag & IO_NDELAY) { 1164 splx(s); 1165 return (EWOULDBLOCK); 1166 } else { 1167 /* 1168 * sleep awaiting carrier 1169 */ 1170 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1171 splx(s); 1172 goto loop; 1173 } 1174 } 1175 splx(s); 1176 /* 1177 * Hang process if it's in the background. 1178 */ 1179 if (u.u_ttyp == tp && u.u_procp->p_pgid != tp->t_pgid) { 1180 if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 1181 (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || 1182 u.u_procp->p_flag&SVFORK || u.u_procp->p_pgrp->pg_jobc == 0) 1183 return (EIO); 1184 pgsignal(u.u_procp->p_pgrp, SIGTTIN); 1185 sleep((caddr_t)&lbolt, TTIPRI); 1186 goto loop; 1187 } 1188 /* 1189 * If canonical, use the canonical queue, 1190 * else use the raw queue. 1191 * 1192 * XXX - should get rid of canonical queue. 1193 * (actually, should get rid of clists...) 1194 */ 1195 qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq; 1196 /* 1197 * No input, sleep on rawq awaiting hardware 1198 * receipt and notification. 1199 */ 1200 s = spltty(); 1201 if (qp->c_cc <= 0) { 1202 /** XXX ??? ask mike why TS_CARR_ON was (once) necessary here 1203 if ((tp->t_state&TS_CARR_ON) == 0 || 1204 (tp->t_state&TS_NBIO)) { 1205 splx(s); 1206 return (EWOULDBLOCK); 1207 } 1208 **/ 1209 if (flag & IO_NDELAY) { 1210 splx(s); 1211 return (EWOULDBLOCK); 1212 } 1213 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1214 splx(s); 1215 goto loop; 1216 } 1217 splx(s); 1218 /* 1219 * Input present, check for input mapping and processing. 1220 */ 1221 first = 1; 1222 while ((c = getc(qp)) >= 0) { 1223 /* 1224 * delayed suspend (^Y) 1225 */ 1226 if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) { 1227 gsignal(tp->t_pgid, SIGTSTP); 1228 if (first) { 1229 sleep((caddr_t)&lbolt, TTIPRI); 1230 goto loop; 1231 } 1232 break; 1233 } 1234 /* 1235 * Interpret EOF only in canonical mode. 1236 */ 1237 if (CCEQ(cc[VEOF], c) && lflag&ICANON) 1238 break; 1239 /* 1240 * Give user character. 1241 */ 1242 error = ureadc(c , uio); 1243 if (error) 1244 break; 1245 if (uio->uio_resid == 0) 1246 break; 1247 /* 1248 * In canonical mode check for a "break character" 1249 * marking the end of a "line of input". 1250 */ 1251 if (lflag&ICANON && ttbreakc(c)) { 1252 break; 1253 } 1254 first = 0; 1255 } 1256 /* 1257 * Look to unblock output now that (presumably) 1258 * the input queue has gone down. 1259 */ 1260 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) { 1261 if (cc[VSTART] != _POSIX_VDISABLE 1262 && putc(cc[VSTART], &tp->t_outq) == 0) { 1263 tp->t_state &= ~TS_TBLOCK; 1264 ttstart(tp); 1265 } 1266 } 1267 return (error); 1268 } 1269 1270 /* 1271 * Check the output queue on tp for space for a kernel message 1272 * (from uprintf/tprintf). Allow some space over the normal 1273 * hiwater mark so we don't lose messages due to normal flow 1274 * control, but don't let the tty run amok. 1275 * Sleeps here are not interruptible, but we return prematurely 1276 * if new signals come in. 1277 */ 1278 ttycheckoutq(tp, wait) 1279 register struct tty *tp; 1280 int wait; 1281 { 1282 int hiwat, s, oldsig; 1283 1284 hiwat = tp->t_hiwat; 1285 s = spltty(); 1286 oldsig = u.u_procp->p_sig; 1287 if (tp->t_outq.c_cc > hiwat + 200) 1288 while (tp->t_outq.c_cc > hiwat) { 1289 ttstart(tp); 1290 if (wait == 0 || u.u_procp->p_sig != oldsig) { 1291 splx(s); 1292 return (0); 1293 } 1294 timeout(wakeup, (caddr_t)&tp->t_outq, hz); 1295 tp->t_state |= TS_ASLEEP; 1296 sleep((caddr_t)&tp->t_outq, PZERO - 1); 1297 } 1298 splx(s); 1299 return (1); 1300 } 1301 1302 /* 1303 * Called from the device's write routine after it has 1304 * calculated the tty-structure given as argument. 1305 */ 1306 ttwrite(tp, uio, flag) 1307 register struct tty *tp; 1308 register struct uio *uio; 1309 { 1310 register char *cp; 1311 register int cc, ce; 1312 int i, hiwat, cnt, error, s; 1313 char obuf[OBUFSIZ]; 1314 1315 hiwat = tp->t_hiwat; 1316 cnt = uio->uio_resid; 1317 error = 0; 1318 loop: 1319 s = spltty(); 1320 if (!(tp->t_state&TS_CARR_ON) && !(tp->t_cflag&CLOCAL)) { 1321 if (tp->t_state&TS_ISOPEN) { 1322 splx(s); 1323 return (EIO); 1324 } else if (flag & IO_NDELAY) { 1325 splx(s); 1326 return (EWOULDBLOCK); 1327 } else { 1328 /* 1329 * sleep awaiting carrier 1330 */ 1331 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1332 splx(s); 1333 goto loop; 1334 } 1335 } 1336 splx(s); 1337 /* 1338 * Hang the process if it's in the background. 1339 */ 1340 if (u.u_ttyp == tp && 1341 u.u_procp->p_pgid != tp->t_pgid && 1342 (tp->t_lflag&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1343 !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) && 1344 !(u.u_procp->p_sigmask & sigmask(SIGTTOU)) && 1345 u.u_procp->p_pgrp->pg_jobc) { 1346 pgsignal(u.u_procp->p_pgrp, SIGTTOU); 1347 sleep((caddr_t)&lbolt, TTIPRI); 1348 goto loop; 1349 } 1350 /* 1351 * Process the user's data in at most OBUFSIZ 1352 * chunks. Perform lower case simulation and 1353 * similar hacks. Keep track of high water 1354 * mark, sleep on overflow awaiting device aid 1355 * in acquiring new space. 1356 */ 1357 while (uio->uio_resid > 0) { 1358 if (tp->t_outq.c_cc > hiwat) { 1359 cc = 0; 1360 goto ovhiwat; 1361 } 1362 /* 1363 * Grab a hunk of data from the user. 1364 */ 1365 cc = uio->uio_iov->iov_len; 1366 if (cc == 0) { 1367 uio->uio_iovcnt--; 1368 uio->uio_iov++; 1369 if (uio->uio_iovcnt <= 0) 1370 panic("ttwrite"); 1371 continue; 1372 } 1373 if (cc > OBUFSIZ) 1374 cc = OBUFSIZ; 1375 cp = obuf; 1376 error = uiomove(cp, cc, uio); 1377 if (error) 1378 break; 1379 if (tp->t_lflag&FLUSHO) 1380 continue; 1381 /* 1382 * If nothing fancy need be done, grab those characters we 1383 * can handle without any of ttyoutput's processing and 1384 * just transfer them to the output q. For those chars 1385 * which require special processing (as indicated by the 1386 * bits in partab), call ttyoutput. After processing 1387 * a hunk of data, look for FLUSHO so ^O's will take effect 1388 * immediately. 1389 */ 1390 while (cc > 0) { 1391 if (!(tp->t_oflag&OPOST)) 1392 ce = cc; 1393 else { 1394 ce = cc - scanc((unsigned)cc, (u_char *)cp, 1395 (u_char *)partab, 077); 1396 /* 1397 * If ce is zero, then we're processing 1398 * a special character through ttyoutput. 1399 */ 1400 if (ce == 0) { 1401 tp->t_rocount = 0; 1402 if (ttyoutput(*cp, tp) >= 0) { 1403 /* no c-lists, wait a bit */ 1404 ttstart(tp); 1405 sleep((caddr_t)&lbolt, TTOPRI); 1406 if (cc != 0) { 1407 uio->uio_iov->iov_base -= cc; 1408 uio->uio_iov->iov_len += cc; 1409 uio->uio_resid += cc; 1410 uio->uio_offset -= cc; 1411 } 1412 goto loop; 1413 } 1414 cp++, cc--; 1415 if ((tp->t_lflag&FLUSHO) || 1416 tp->t_outq.c_cc > hiwat) 1417 goto ovhiwat; 1418 continue; 1419 } 1420 } 1421 /* 1422 * A bunch of normal characters have been found, 1423 * transfer them en masse to the output queue and 1424 * continue processing at the top of the loop. 1425 * If there are any further characters in this 1426 * <= OBUFSIZ chunk, the first should be a character 1427 * requiring special handling by ttyoutput. 1428 */ 1429 tp->t_rocount = 0; 1430 i = b_to_q(cp, ce, &tp->t_outq); 1431 ce -= i; 1432 tp->t_col += ce; 1433 cp += ce, cc -= ce, tk_nout += ce; 1434 tp->t_outcc += ce; 1435 if (i > 0) { 1436 /* out of c-lists, wait a bit */ 1437 ttstart(tp); 1438 sleep((caddr_t)&lbolt, TTOPRI); 1439 uio->uio_iov->iov_base -= cc; 1440 uio->uio_iov->iov_len += cc; 1441 uio->uio_resid += cc; 1442 uio->uio_offset -= cc; 1443 goto loop; 1444 } 1445 if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat) 1446 goto ovhiwat; 1447 } 1448 ttstart(tp); 1449 } 1450 return (error); 1451 ovhiwat: 1452 if (cc != 0) { 1453 uio->uio_iov->iov_base -= cc; 1454 uio->uio_iov->iov_len += cc; 1455 uio->uio_resid += cc; 1456 uio->uio_offset -= cc; 1457 } 1458 ttstart(tp); 1459 s = spltty(); 1460 /* 1461 * This can only occur if FLUSHO is set in t_lflag, 1462 * or if ttstart/oproc is synchronous (or very fast). 1463 */ 1464 if (tp->t_outq.c_cc <= hiwat) { 1465 splx(s); 1466 goto loop; 1467 } 1468 if (flag & IO_NDELAY) { 1469 splx(s); 1470 if (uio->uio_resid == cnt) 1471 return (EWOULDBLOCK); 1472 return (0); 1473 } 1474 tp->t_state |= TS_ASLEEP; 1475 sleep((caddr_t)&tp->t_outq, TTOPRI); 1476 splx(s); 1477 goto loop; 1478 } 1479 1480 /* 1481 * Rubout one character from the rawq of tp 1482 * as cleanly as possible. 1483 */ 1484 ttyrub(c, tp) 1485 register c; 1486 register struct tty *tp; 1487 { 1488 register char *cp; 1489 register int savecol; 1490 int s; 1491 char *nextc(); 1492 1493 if ((tp->t_lflag&ECHO) == 0) 1494 return; 1495 tp->t_lflag &= ~FLUSHO; 1496 if (tp->t_lflag&ECHOE) { 1497 if (tp->t_rocount == 0) { 1498 /* 1499 * Screwed by ttwrite; retype 1500 */ 1501 ttyretype(tp); 1502 return; 1503 } 1504 if (c == ('\t'|TTY_QUOTE) || c == ('\n'|TTY_QUOTE)) 1505 ttyrubo(tp, 2); 1506 else switch (partab[c&=0377]&077) { 1507 1508 case ORDINARY: 1509 ttyrubo(tp, 1); 1510 break; 1511 1512 case VTAB: 1513 case BACKSPACE: 1514 case CONTROL: 1515 case RETURN: 1516 if (tp->t_lflag&ECHOCTL) 1517 ttyrubo(tp, 2); 1518 break; 1519 1520 case TAB: { 1521 int c; 1522 1523 if (tp->t_rocount < tp->t_rawq.c_cc) { 1524 ttyretype(tp); 1525 return; 1526 } 1527 s = spltty(); 1528 savecol = tp->t_col; 1529 tp->t_state |= TS_CNTTB; 1530 tp->t_lflag |= FLUSHO; 1531 tp->t_col = tp->t_rocol; 1532 cp = tp->t_rawq.c_cf; 1533 c = *cp; /* XXX FIX NEXTC */ 1534 for (; cp; cp = nextc(&tp->t_rawq, cp, &c)) 1535 ttyecho(c, tp); 1536 tp->t_lflag &= ~FLUSHO; 1537 tp->t_state &= ~TS_CNTTB; 1538 splx(s); 1539 /* 1540 * savecol will now be length of the tab 1541 */ 1542 savecol -= tp->t_col; 1543 tp->t_col += savecol; 1544 if (savecol > 8) 1545 savecol = 8; /* overflow screw */ 1546 while (--savecol >= 0) 1547 (void) ttyoutput('\b', tp); 1548 break; 1549 } 1550 1551 default: 1552 /* XXX */ 1553 printf("ttyrub: would panic c = %d, val = %d\n", 1554 c, partab[c&=0377]&077); 1555 /*panic("ttyrub");*/ 1556 } 1557 } else if (tp->t_lflag&ECHOPRT) { 1558 if ((tp->t_state&TS_ERASE) == 0) { 1559 (void) ttyoutput('\\', tp); 1560 tp->t_state |= TS_ERASE; 1561 } 1562 ttyecho(c, tp); 1563 } else 1564 ttyecho(tp->t_cc[VERASE], tp); 1565 tp->t_rocount--; 1566 } 1567 1568 /* 1569 * Crt back over cnt chars perhaps 1570 * erasing them. 1571 */ 1572 ttyrubo(tp, cnt) 1573 register struct tty *tp; 1574 int cnt; 1575 { 1576 1577 while (--cnt >= 0) 1578 ttyout("\b \b", tp); 1579 } 1580 1581 /* 1582 * Reprint the rawq line. 1583 * We assume c_cc has already been checked. 1584 */ 1585 ttyretype(tp) 1586 register struct tty *tp; 1587 { 1588 register char *cp; 1589 char *nextc(); 1590 int s, c; 1591 1592 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1593 ttyecho(tp->t_cc[VREPRINT], tp); 1594 (void) ttyoutput('\n', tp); 1595 s = spltty(); 1596 /*** XXX *** FIX *** NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1597 BIT OF FIRST CHAR ****/ 1598 for (cp = tp->t_canq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_canq, cp, &c)) { 1599 ttyecho(c, tp); 1600 } 1601 for (cp = tp->t_rawq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_rawq, cp, &c)) { 1602 ttyecho(c, tp); 1603 } 1604 tp->t_state &= ~TS_ERASE; 1605 splx(s); 1606 tp->t_rocount = tp->t_rawq.c_cc; 1607 tp->t_rocol = 0; 1608 } 1609 1610 /* 1611 * Echo a typed character to the terminal. 1612 */ 1613 ttyecho(c, tp) 1614 register c; 1615 register struct tty *tp; 1616 { 1617 if ((tp->t_state&TS_CNTTB) == 0) 1618 tp->t_lflag &= ~FLUSHO; 1619 if ((tp->t_lflag&ECHO) == 0 && !(tp->t_lflag&ECHONL && c == '\n')) 1620 return; 1621 if (tp->t_lflag&ECHOCTL) { 1622 if ((c&TTY_CHARMASK)<=037 && c!='\t' && c!='\n' || c==0177) { 1623 (void) ttyoutput('^', tp); 1624 c &= TTY_CHARMASK; 1625 if (c == 0177) 1626 c = '?'; 1627 else 1628 c += 'A' - 1; 1629 } 1630 } 1631 (void) ttyoutput(c, tp); 1632 } 1633 1634 /* 1635 * send string cp to tp 1636 */ 1637 ttyout(cp, tp) 1638 register char *cp; 1639 register struct tty *tp; 1640 { 1641 register char c; 1642 1643 while (c = *cp++) 1644 (void) ttyoutput(c, tp); 1645 } 1646 1647 ttwakeup(tp) 1648 struct tty *tp; 1649 { 1650 1651 if (tp->t_rsel) { 1652 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1653 tp->t_state &= ~TS_RCOLL; 1654 tp->t_rsel = 0; 1655 } 1656 if (tp->t_state & TS_ASYNC) 1657 gsignal(tp->t_pgid, SIGIO); 1658 wakeup((caddr_t)&tp->t_rawq); 1659 } 1660 1661 /* 1662 * set tty hi and low water marks 1663 * 1664 * Try to arrange the dynamics so there's about one second 1665 * from hi to low water. 1666 * 1667 */ 1668 ttsetwater(tp) 1669 struct tty *tp; 1670 { 1671 register cps = tp->t_ospeed / 10; 1672 register x; 1673 1674 #define clamp(x, h, l) ((x)>h ? h : ((x)<l) ? l : (x)) 1675 tp->t_lowat = x = clamp(cps/2, TTMAXLOWAT, TTMINLOWAT); 1676 x += cps; 1677 x = clamp(x, TTMAXHIWAT, TTMINHIWAT); 1678 tp->t_hiwat = roundup(x, CBSIZE); 1679 #undef clamp 1680 } 1681 1682 ttspeedtab(speed, table) 1683 struct speedtab table[]; 1684 { 1685 register int i; 1686 1687 for (i = 0; table[i].sp_speed != -1; i++) 1688 if (table[i].sp_speed == speed) 1689 return(table[i].sp_code); 1690 return(-1); 1691 } 1692