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