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