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