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