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