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