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