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