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