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.33 (Berkeley) 06/21/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 = ttysleep(tp, (caddr_t)&tp->t_outq, 124 TTOPRI | PCATCH, ttyout, 0)) 125 break; 126 } 127 splx(s); 128 return (error); 129 } 130 131 /* 132 * Flush all TTY queues 133 */ 134 ttyflush(tp, rw) 135 register struct tty *tp; 136 { 137 register s; 138 139 s = spltty(); 140 if (rw & FREAD) { 141 while (getc(&tp->t_canq) >= 0) 142 ; 143 ttwakeup(tp); 144 } 145 if (rw & FWRITE) { 146 wakeup((caddr_t)&tp->t_outq); /* XXX? what about selwakeup? */ 147 tp->t_state &= ~TS_TTSTOP; 148 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 149 while (getc(&tp->t_outq) >= 0) 150 ; 151 } 152 if (rw & FREAD) { 153 while (getc(&tp->t_rawq) >= 0) 154 ; 155 tp->t_rocount = 0; 156 tp->t_rocol = 0; 157 tp->t_state &= ~TS_LOCAL; 158 } 159 splx(s); 160 } 161 162 /* 163 * Send stop character on input overflow. 164 */ 165 ttyblock(tp) 166 register struct tty *tp; 167 { 168 register x; 169 170 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 171 if (tp->t_rawq.c_cc > TTYHOG) { 172 ttyflush(tp, FREAD|FWRITE); 173 tp->t_state &= ~TS_TBLOCK; 174 } 175 /* 176 * Block further input iff: 177 * Current input > threshold AND input is available to user program 178 */ 179 if (x >= TTYHOG/2 && (tp->t_state & TS_TBLOCK) == 0 && 180 ((tp->t_lflag&ICANON) == 0) || (tp->t_canq.c_cc > 0) && 181 tp->t_cc[VSTOP] != _POSIX_VDISABLE) { 182 if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) { 183 tp->t_state |= TS_TBLOCK; 184 ttstart(tp); 185 } 186 } 187 } 188 189 /* 190 * 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 = ttysleep(tp, (caddr_t)&lbolt, 268 TTOPRI | PCATCH, 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 case OTIOCCONS: 550 return(ttcompat(tp, com, data, flag)); 551 #endif 552 553 default: 554 return (-1); 555 } 556 return (0); 557 } 558 559 ttnread(tp) 560 struct tty *tp; 561 { 562 int nread = 0; 563 564 if (tp->t_lflag & PENDIN) 565 ttypend(tp); 566 nread = tp->t_canq.c_cc; 567 if ((tp->t_lflag & ICANON) == 0) 568 nread += tp->t_rawq.c_cc; 569 return (nread); 570 } 571 572 ttselect(dev, rw) 573 dev_t dev; 574 int rw; 575 { 576 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 577 int nread; 578 int s = spltty(); 579 580 switch (rw) { 581 582 case FREAD: 583 nread = ttnread(tp); 584 if (nread > 0 || 585 ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0)) 586 goto win; 587 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 588 tp->t_state |= TS_RCOLL; 589 else 590 tp->t_rsel = u.u_procp; 591 break; 592 593 case FWRITE: 594 if (tp->t_outq.c_cc <= tp->t_lowat) 595 goto win; 596 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 597 tp->t_state |= TS_WCOLL; 598 else 599 tp->t_wsel = u.u_procp; 600 break; 601 } 602 splx(s); 603 return (0); 604 win: 605 splx(s); 606 return (1); 607 } 608 609 /* 610 * Initial open of tty, or (re)entry to line discipline. 611 */ 612 ttyopen(dev, tp) 613 dev_t dev; 614 register struct tty *tp; 615 { 616 617 tp->t_dev = dev; 618 619 tp->t_state &= ~TS_WOPEN; 620 if ((tp->t_state & TS_ISOPEN) == 0) { 621 tp->t_state |= TS_ISOPEN; 622 bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize)); 623 } 624 return (0); 625 } 626 627 /* 628 * "close" a line discipline 629 */ 630 ttylclose(tp) 631 register struct tty *tp; 632 { 633 634 ttywflush(tp); 635 } 636 637 /* 638 * clean tp on last close 639 */ 640 ttyclose(tp) 641 register struct tty *tp; 642 { 643 if (constty == tp) 644 constty = NULL; 645 ttyflush(tp, FREAD|FWRITE); 646 tp->t_session = NULL; 647 tp->t_pgrp = NULL; 648 tp->t_state = 0; 649 tp->t_gen++; 650 return (0); 651 } 652 653 /* 654 * Handle modem control transition on a tty. 655 * Flag indicates new state of carrier. 656 * Returns 0 if the line should be turned off, otherwise 1. 657 */ 658 ttymodem(tp, flag) 659 register struct tty *tp; 660 { 661 662 if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag&MDMBUF)) { 663 /* 664 * MDMBUF: do flow control according to carrier flag 665 */ 666 if (flag) { 667 tp->t_state &= ~TS_TTSTOP; 668 ttstart(tp); 669 } else if ((tp->t_state&TS_TTSTOP) == 0) { 670 tp->t_state |= TS_TTSTOP; 671 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 672 } 673 } else if (flag == 0) { 674 /* 675 * Lost carrier. 676 */ 677 tp->t_state &= ~TS_CARR_ON; 678 if (tp->t_state&TS_ISOPEN && (tp->t_cflag&CLOCAL) == 0) { 679 if (tp->t_session && tp->t_session->s_leader) 680 psignal(tp->t_session->s_leader, SIGHUP); 681 ttyflush(tp, FREAD|FWRITE); 682 return (0); 683 } 684 } else { 685 /* 686 * Carrier now on. 687 */ 688 tp->t_state |= TS_CARR_ON; 689 ttwakeup(tp); 690 } 691 return (1); 692 } 693 694 /* 695 * Default modem control routine (for other line disciplines). 696 * Return argument flag, to turn off device on carrier drop. 697 */ 698 nullmodem(tp, flag) 699 register struct tty *tp; 700 int flag; 701 { 702 703 if (flag) 704 tp->t_state |= TS_CARR_ON; 705 else { 706 tp->t_state &= ~TS_CARR_ON; 707 if ((tp->t_cflag&CLOCAL) == 0) { 708 if (tp->t_session && tp->t_session->s_leader) 709 psignal(tp->t_session->s_leader, SIGHUP); 710 return (0); 711 } 712 } 713 return (1); 714 } 715 716 /* 717 * reinput pending characters after state switch 718 * call at spltty(). 719 */ 720 ttypend(tp) 721 register struct tty *tp; 722 { 723 struct clist tq; 724 register c; 725 726 tp->t_lflag &= ~PENDIN; 727 tp->t_state |= TS_TYPEN; 728 tq = tp->t_rawq; 729 tp->t_rawq.c_cc = 0; 730 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 731 while ((c = getc(&tq)) >= 0) 732 ttyinput(c, tp); 733 tp->t_state &= ~TS_TYPEN; 734 } 735 736 /* 737 * 738 * Place a character on raw TTY input queue, 739 * putting in delimiters and waking up top 740 * half as needed. Also echo if required. 741 * The arguments are the character and the 742 * appropriate tty structure. 743 */ 744 ttyinput(c, tp) 745 register c; 746 register struct tty *tp; 747 { 748 register int iflag = tp->t_iflag; 749 register int lflag = tp->t_lflag; 750 register u_char *cc = tp->t_cc; 751 int i, err; 752 753 /* 754 * If input is pending take it first. 755 */ 756 if (lflag&PENDIN) 757 ttypend(tp); 758 /* 759 * Gather stats. 760 */ 761 tk_nin++; 762 if (lflag&ICANON) { 763 tk_cancc++; 764 tp->t_cancc++; 765 } else { 766 tk_rawcc++; 767 tp->t_rawcc++; 768 } 769 /* 770 * Handle exceptional conditions (break, parity, framing). 771 */ 772 if (err = (c&TTY_ERRORMASK)) { 773 c &= ~TTY_ERRORMASK; 774 if (err&TTY_FE && !c) { /* break */ 775 if (iflag&IGNBRK) 776 goto endcase; 777 else if (iflag&BRKINT && lflag&ISIG && 778 (cc[VINTR] != _POSIX_VDISABLE)) 779 c = cc[VINTR]; 780 else { 781 c = 0; 782 if (iflag&PARMRK) 783 goto parmrk; 784 } 785 } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) { 786 if (iflag&IGNPAR) 787 goto endcase; 788 else if (iflag&PARMRK) { 789 parmrk: 790 putc(0377|TTY_QUOTE, &tp->t_rawq); 791 putc(0|TTY_QUOTE, &tp->t_rawq); 792 putc(c|TTY_QUOTE, &tp->t_rawq); 793 goto endcase; 794 } else 795 c = 0; 796 } 797 } 798 /* 799 * In tandem mode, check high water mark. 800 */ 801 if (iflag&IXOFF) 802 ttyblock(tp); 803 if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP)) 804 c &= 0177; 805 if ((tp->t_lflag&EXTPROC) == 0) { 806 /* 807 * Check for literal nexting very first 808 */ 809 if (tp->t_state&TS_LNCH) { 810 c |= TTY_QUOTE; 811 tp->t_state &= ~TS_LNCH; 812 } 813 /* 814 * Scan for special characters. This code 815 * is really just a big case statement with 816 * non-constant cases. The bottom of the 817 * case statement is labeled ``endcase'', so goto 818 * it after a case match, or similar. 819 */ 820 /* 821 * Control chars which aren't controlled 822 * by ICANON, ISIG, or IXON. 823 */ 824 if (lflag&IEXTEN) { 825 if (CCEQ(cc[VLNEXT], c)) { 826 if (lflag&ECHO) { 827 if (lflag&ECHOE) 828 ttyoutstr("^\b", tp); 829 else 830 ttyecho(c, tp); 831 } 832 tp->t_state |= TS_LNCH; 833 goto endcase; 834 } 835 if (CCEQ(cc[VDISCARD], c)) { 836 if (lflag&FLUSHO) 837 tp->t_lflag &= ~FLUSHO; 838 else { 839 ttyflush(tp, FWRITE); 840 ttyecho(c, tp); 841 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 842 ttyretype(tp); 843 tp->t_lflag |= FLUSHO; 844 } 845 goto startoutput; 846 } 847 } 848 /* 849 * Signals. 850 */ 851 if (lflag&ISIG) { 852 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 853 if ((lflag&NOFLSH) == 0) 854 ttyflush(tp, FREAD|FWRITE); 855 ttyecho(c, tp); 856 pgsignal(tp->t_pgrp, 857 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1); 858 goto endcase; 859 } 860 if (CCEQ(cc[VSUSP], c)) { 861 if ((lflag&NOFLSH) == 0) 862 ttyflush(tp, FREAD); 863 ttyecho(c, tp); 864 pgsignal(tp->t_pgrp, SIGTSTP, 1); 865 goto endcase; 866 } 867 } 868 /* 869 * Handle start/stop characters. 870 */ 871 if (iflag&IXON) { 872 if (CCEQ(cc[VSTOP], c)) { 873 if ((tp->t_state&TS_TTSTOP) == 0) { 874 tp->t_state |= TS_TTSTOP; 875 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 876 return; 877 } 878 if (!CCEQ(cc[VSTART], c)) 879 return; 880 /* 881 * if VSTART == VSTOP then toggle 882 */ 883 goto endcase; 884 } 885 if (CCEQ(cc[VSTART], c)) 886 goto restartoutput; 887 } 888 /* 889 * IGNCR, ICRNL, & INLCR 890 */ 891 if (c == '\r') { 892 if (iflag&IGNCR) 893 goto endcase; 894 else if (iflag&ICRNL) 895 c = '\n'; 896 } 897 else if (c == '\n' && iflag&INLCR) 898 c = '\r'; 899 } 900 /* 901 * Non canonical mode; don't process line editing 902 * characters; check high water mark for wakeup. 903 * 904 */ 905 if ((lflag&ICANON) == 0) { 906 if (tp->t_rawq.c_cc > TTYHOG) { 907 if (iflag&IMAXBEL) { 908 if (tp->t_outq.c_cc < tp->t_hiwat) 909 (void) ttyoutput(CTRL('g'), tp); 910 } else 911 ttyflush(tp, FREAD | FWRITE); 912 } else { 913 if (putc(c, &tp->t_rawq) >= 0) { 914 ttwakeup(tp); 915 ttyecho(c, tp); 916 } 917 } 918 goto endcase; 919 } 920 if ((tp->t_lflag&EXTPROC) == 0) { 921 /* 922 * From here on down canonical mode character 923 * processing takes place. 924 */ 925 /* 926 * erase (^H / ^?) 927 */ 928 if ((c == cc[VERASE] || c == cc[VERASE2]) && c != _POSIX_VDISABLE && 929 cc[VERASE] != _POSIX_VDISABLE) { 930 if (tp->t_rawq.c_cc) 931 ttyrub(unputc(&tp->t_rawq), tp); 932 goto endcase; 933 } 934 /* 935 * kill (^U) 936 */ 937 if (CCEQ(cc[VKILL], c)) { 938 if (lflag&ECHOKE && tp->t_rawq.c_cc == tp->t_rocount && 939 (lflag&ECHOPRT) == 0) { 940 while (tp->t_rawq.c_cc) 941 ttyrub(unputc(&tp->t_rawq), tp); 942 } else { 943 ttyecho(c, tp); 944 if (lflag&ECHOK || lflag&ECHOKE) 945 ttyecho('\n', tp); 946 while (getc(&tp->t_rawq) > 0) 947 ; 948 tp->t_rocount = 0; 949 } 950 tp->t_state &= ~TS_LOCAL; 951 goto endcase; 952 } 953 /* 954 * word erase (^W) 955 */ 956 if (CCEQ(cc[VWERASE], c)) { 957 int ctype; 958 959 #define CTYPE(c) ((lflag&ALTWERASE) ? (partab[(c)&TTY_CHARMASK]&0100) : 0) 960 /* 961 * erase whitespace 962 */ 963 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t') 964 ttyrub(c, tp); 965 if (c == -1) 966 goto endcase; 967 /* 968 * special case last char of token 969 */ 970 ttyrub(c, tp); 971 c = unputc(&tp->t_rawq); 972 if (c == -1 || c == ' ' || c == '\t') { 973 if (c != -1) 974 (void) putc(c, &tp->t_rawq); 975 goto endcase; 976 } 977 /* 978 * erase rest of token 979 */ 980 ctype = CTYPE(c); 981 do { 982 ttyrub(c, tp); 983 c = unputc(&tp->t_rawq); 984 if (c == -1) 985 goto endcase; 986 } while (c != ' ' && c != '\t' && CTYPE(c) == ctype); 987 (void) putc(c, &tp->t_rawq); 988 goto endcase; 989 #undef CTYPE 990 } 991 /* 992 * reprint line (^R) 993 */ 994 if (CCEQ(cc[VREPRINT], c)) { 995 ttyretype(tp); 996 goto endcase; 997 } 998 /* 999 * ^T - kernel info and generate SIGINFO 1000 */ 1001 if (CCEQ(cc[VSTATUS], c)) { 1002 pgsignal(tp->t_pgrp, SIGINFO, 1); 1003 if ((lflag&NOKERNINFO) == 0) 1004 ttyinfo(tp); 1005 goto endcase; 1006 } 1007 } 1008 /* 1009 * Check for input buffer overflow 1010 */ 1011 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 1012 if (iflag&IMAXBEL) { 1013 if (tp->t_outq.c_cc < tp->t_hiwat) 1014 (void) ttyoutput(CTRL('g'), tp); 1015 } else 1016 ttyflush(tp, FREAD | FWRITE); 1017 goto endcase; 1018 } 1019 /* 1020 * Put data char in q for user and 1021 * wakeup on seeing a line delimiter. 1022 */ 1023 if (putc(c, &tp->t_rawq) >= 0) { 1024 if (ttbreakc(c)) { 1025 tp->t_rocount = 0; 1026 catq(&tp->t_rawq, &tp->t_canq); 1027 ttwakeup(tp); 1028 } else if (tp->t_rocount++ == 0) 1029 tp->t_rocol = tp->t_col; 1030 if (tp->t_state&TS_ERASE) { 1031 /* 1032 * end of prterase \.../ 1033 */ 1034 tp->t_state &= ~TS_ERASE; 1035 (void) ttyoutput('/', tp); 1036 } 1037 i = tp->t_col; 1038 ttyecho(c, tp); 1039 if (CCEQ(cc[VEOF], c) && lflag&ECHO) { 1040 /* 1041 * Place the cursor over the '^' of the ^D. 1042 */ 1043 i = MIN(2, tp->t_col - i); 1044 while (i > 0) { 1045 (void) ttyoutput('\b', tp); 1046 i--; 1047 } 1048 } 1049 } 1050 endcase: 1051 /* 1052 * IXANY means allow any character to restart output. 1053 */ 1054 if ((tp->t_state&TS_TTSTOP) && (iflag&IXANY) == 0 && 1055 cc[VSTART] != cc[VSTOP]) 1056 return; 1057 restartoutput: 1058 tp->t_state &= ~TS_TTSTOP; 1059 tp->t_lflag &= ~FLUSHO; 1060 startoutput: 1061 ttstart(tp); 1062 } 1063 1064 /* 1065 * Put character on TTY output queue, adding delays, 1066 * expanding tabs, and handling the CR/NL bit. 1067 * This is called both from the top half for output, 1068 * and from interrupt level for echoing. 1069 * The arguments are the character and the tty structure. 1070 * Returns < 0 if putc succeeds, otherwise returns char to resend 1071 * Must be recursive. 1072 */ 1073 ttyoutput(c, tp) 1074 register c; 1075 register struct tty *tp; 1076 { 1077 register char *colp; 1078 register ctype; 1079 register long oflag = tp->t_oflag; 1080 1081 if ((oflag&OPOST) == 0) { 1082 if (tp->t_lflag&FLUSHO) 1083 return (-1); 1084 if (putc(c, &tp->t_outq)) 1085 return (c); 1086 tk_nout++; 1087 tp->t_outcc++; 1088 return (-1); 1089 } 1090 c &= TTY_CHARMASK; 1091 /* 1092 * Turn tabs to spaces as required 1093 * 1094 * Special case if we have external processing, we don't 1095 * do the tab expansion because we'll probably get it 1096 * wrong. If tab expansion needs to be done, let it 1097 * happen externally. 1098 */ 1099 if ((tp->t_lflag&EXTPROC) == 0 && 1100 c == '\t' && oflag&OXTABS ) { 1101 register int s; 1102 1103 c = 8 - (tp->t_col&7); 1104 if ((tp->t_lflag&FLUSHO) == 0) { 1105 s = spltty(); /* don't interrupt tabs */ 1106 c -= b_to_q(" ", c, &tp->t_outq); 1107 tk_nout += c; 1108 tp->t_outcc += c; 1109 splx(s); 1110 } 1111 tp->t_col += c; 1112 return (c ? -1 : '\t'); 1113 } 1114 if (c == CEOT && oflag&ONOEOT) 1115 return(-1); 1116 tk_nout++; 1117 tp->t_outcc++; 1118 /* 1119 * turn <nl> to <cr><lf> if desired. 1120 */ 1121 if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0) 1122 return (c); 1123 if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq)) 1124 return (c); 1125 /* 1126 * Calculate delays. 1127 * The numbers here represent clock ticks 1128 * and are not necessarily optimal for all terminals. 1129 * 1130 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 1131 * 1132 * (actually, should THROW AWAY terminals which need delays) 1133 */ 1134 colp = &tp->t_col; 1135 ctype = partab[c]; 1136 c = 0; 1137 switch (ctype&077) { 1138 1139 case ORDINARY: 1140 (*colp)++; 1141 1142 case CONTROL: 1143 break; 1144 1145 case BACKSPACE: 1146 if (*colp) 1147 (*colp)--; 1148 break; 1149 1150 /* 1151 * This macro is close enough to the correct thing; 1152 * it should be replaced by real user settable delays 1153 * in any event... 1154 */ 1155 #define mstohz(ms) (((ms) * hz) >> 10) 1156 case NEWLINE: 1157 ctype = (tp->t_flags >> 8) & 03; 1158 if (ctype == 1) { /* tty 37 */ 1159 if (*colp > 0) { 1160 c = (((unsigned)*colp) >> 4) + 3; 1161 if ((unsigned)c > 6) 1162 c = 6; 1163 } 1164 } else if (ctype == 2) /* vt05 */ 1165 c = mstohz(100); 1166 *colp = 0; 1167 break; 1168 1169 case TAB: 1170 ctype = (tp->t_flags >> 10) & 03; 1171 if (ctype == 1) { /* tty 37 */ 1172 c = 1 - (*colp | ~07); 1173 if (c < 5) 1174 c = 0; 1175 } 1176 *colp |= 07; 1177 (*colp)++; 1178 break; 1179 1180 case VTAB: 1181 if (tp->t_flags&VTDELAY) /* tty 37 */ 1182 c = 0177; 1183 break; 1184 1185 case RETURN: 1186 ctype = (tp->t_flags >> 12) & 03; 1187 if (ctype == 1) /* tn 300 */ 1188 c = mstohz(83); 1189 else if (ctype == 2) /* ti 700 */ 1190 c = mstohz(166); 1191 else if (ctype == 3) { /* concept 100 */ 1192 int i; 1193 1194 if ((i = *colp) >= 0) 1195 for (; i < 9; i++) 1196 (void) putc(0177, &tp->t_outq); 1197 } 1198 *colp = 0; 1199 } 1200 if (c && (tp->t_lflag&FLUSHO) == 0) 1201 (void) putc(c|TTY_QUOTE, &tp->t_outq); 1202 return (-1); 1203 } 1204 #undef mstohz 1205 1206 /* 1207 * Called from device's read routine after it has 1208 * calculated the tty-structure given as argument. 1209 */ 1210 ttread(tp, uio, flag) 1211 register struct tty *tp; 1212 struct uio *uio; 1213 { 1214 register struct clist *qp; 1215 register int c; 1216 register long lflag; 1217 register u_char *cc = tp->t_cc; 1218 int s, first, error = 0; 1219 1220 loop: 1221 lflag = tp->t_lflag; 1222 s = spltty(); 1223 /* 1224 * take pending input first 1225 */ 1226 if (lflag&PENDIN) 1227 ttypend(tp); 1228 splx(s); 1229 1230 /* 1231 * Hang process if it's in the background. 1232 */ 1233 if (isbackground(u.u_procp, tp)) { 1234 if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 1235 (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || 1236 u.u_procp->p_flag&SVFORK || u.u_procp->p_pgrp->pg_jobc == 0) 1237 return (EIO); 1238 pgsignal(u.u_procp->p_pgrp, SIGTTIN, 1); 1239 if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH, 1240 ttybg, 0)) 1241 return (error); 1242 goto loop; 1243 } 1244 1245 /* 1246 * If canonical, use the canonical queue, 1247 * else use the raw queue. 1248 * 1249 * XXX - should get rid of canonical queue. 1250 * (actually, should get rid of clists...) 1251 */ 1252 qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq; 1253 1254 /* 1255 * If there is no input, sleep on rawq 1256 * awaiting hardware receipt and notification. 1257 * If we have data, we don't need to check for carrier. 1258 */ 1259 s = spltty(); 1260 if (qp->c_cc <= 0) { 1261 int carrier; 1262 1263 carrier = (tp->t_state&TS_CARR_ON) || (tp->t_cflag&CLOCAL); 1264 if (!carrier && tp->t_state&TS_ISOPEN) { 1265 splx(s); 1266 return (0); /* EOF */ 1267 } 1268 if (flag & IO_NDELAY) { 1269 splx(s); 1270 return (EWOULDBLOCK); 1271 } 1272 error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 1273 carrier ? ttyin : ttopen, 0); 1274 splx(s); 1275 if (error) 1276 return (error); 1277 goto loop; 1278 } 1279 splx(s); 1280 1281 /* 1282 * Input present, check for input mapping and processing. 1283 */ 1284 first = 1; 1285 while ((c = getc(qp)) >= 0) { 1286 /* 1287 * delayed suspend (^Y) 1288 */ 1289 if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) { 1290 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1291 if (first) { 1292 if (error = ttysleep(tp, (caddr_t)&lbolt, 1293 TTIPRI | PCATCH, ttybg, 0)) 1294 break; 1295 goto loop; 1296 } 1297 break; 1298 } 1299 /* 1300 * Interpret EOF only in canonical mode. 1301 */ 1302 if (CCEQ(cc[VEOF], c) && lflag&ICANON) 1303 break; 1304 /* 1305 * Give user character. 1306 */ 1307 error = ureadc(c, uio); 1308 if (error) 1309 break; 1310 if (uio->uio_resid == 0) 1311 break; 1312 /* 1313 * In canonical mode check for a "break character" 1314 * marking the end of a "line of input". 1315 */ 1316 if (lflag&ICANON && ttbreakc(c)) 1317 break; 1318 first = 0; 1319 } 1320 /* 1321 * Look to unblock output now that (presumably) 1322 * the input queue has gone down. 1323 */ 1324 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) { 1325 if (cc[VSTART] != _POSIX_VDISABLE 1326 && putc(cc[VSTART], &tp->t_outq) == 0) { 1327 tp->t_state &= ~TS_TBLOCK; 1328 ttstart(tp); 1329 } 1330 } 1331 return (error); 1332 } 1333 1334 /* 1335 * Check the output queue on tp for space for a kernel message 1336 * (from uprintf/tprintf). Allow some space over the normal 1337 * hiwater mark so we don't lose messages due to normal flow 1338 * control, but don't let the tty run amok. 1339 * Sleeps here are not interruptible, but we return prematurely 1340 * if new signals come in. 1341 */ 1342 ttycheckoutq(tp, wait) 1343 register struct tty *tp; 1344 int wait; 1345 { 1346 int hiwat, s, oldsig; 1347 1348 hiwat = tp->t_hiwat; 1349 s = spltty(); 1350 oldsig = u.u_procp->p_sig; 1351 if (tp->t_outq.c_cc > hiwat + 200) 1352 while (tp->t_outq.c_cc > hiwat) { 1353 ttstart(tp); 1354 if (wait == 0 || u.u_procp->p_sig != oldsig) { 1355 splx(s); 1356 return (0); 1357 } 1358 timeout(wakeup, (caddr_t)&tp->t_outq, hz); 1359 tp->t_state |= TS_ASLEEP; 1360 sleep((caddr_t)&tp->t_outq, PZERO - 1); 1361 } 1362 splx(s); 1363 return (1); 1364 } 1365 1366 /* 1367 * Called from the device's write routine after it has 1368 * calculated the tty-structure given as argument. 1369 */ 1370 ttwrite(tp, uio, flag) 1371 register struct tty *tp; 1372 register struct uio *uio; 1373 { 1374 register char *cp; 1375 register int cc = 0, ce; 1376 int i, hiwat, cnt, error, s; 1377 char obuf[OBUFSIZ]; 1378 1379 hiwat = tp->t_hiwat; 1380 cnt = uio->uio_resid; 1381 error = 0; 1382 loop: 1383 s = spltty(); 1384 if ((tp->t_state&TS_CARR_ON) == 0 && (tp->t_cflag&CLOCAL) == 0) { 1385 if (tp->t_state&TS_ISOPEN) { 1386 splx(s); 1387 return (EIO); 1388 } else if (flag & IO_NDELAY) { 1389 splx(s); 1390 error = EWOULDBLOCK; 1391 goto out; 1392 } else { 1393 /* 1394 * sleep awaiting carrier 1395 */ 1396 error = ttysleep(tp, (caddr_t)&tp->t_rawq, 1397 TTIPRI | PCATCH,ttopen, 0); 1398 splx(s); 1399 if (error) 1400 goto out; 1401 goto loop; 1402 } 1403 } 1404 splx(s); 1405 /* 1406 * Hang the process if it's in the background. 1407 */ 1408 if (isbackground(u.u_procp, tp) && 1409 (tp->t_lflag&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1410 (u.u_procp->p_sigignore & sigmask(SIGTTOU)) == 0 && 1411 (u.u_procp->p_sigmask & sigmask(SIGTTOU)) == 0 && 1412 u.u_procp->p_pgrp->pg_jobc) { 1413 pgsignal(u.u_procp->p_pgrp, SIGTTOU, 1); 1414 if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH, 1415 ttybg, 0)) 1416 goto out; 1417 goto loop; 1418 } 1419 /* 1420 * Process the user's data in at most OBUFSIZ 1421 * chunks. Perform any output translation. 1422 * Keep track of high water mark, sleep on overflow 1423 * awaiting device aid in acquiring new space. 1424 */ 1425 while (uio->uio_resid > 0 || cc > 0) { 1426 if (tp->t_lflag&FLUSHO) { 1427 uio->uio_resid = 0; 1428 return (0); 1429 } 1430 if (tp->t_outq.c_cc > hiwat) 1431 goto ovhiwat; 1432 /* 1433 * Grab a hunk of data from the user, 1434 * unless we have some leftover from last time. 1435 */ 1436 if (cc == 0) { 1437 cc = min(uio->uio_resid, OBUFSIZ); 1438 cp = obuf; 1439 error = uiomove(cp, cc, uio); 1440 if (error) { 1441 cc = 0; 1442 break; 1443 } 1444 } 1445 /* 1446 * If nothing fancy need be done, grab those characters we 1447 * can handle without any of ttyoutput's processing and 1448 * just transfer them to the output q. For those chars 1449 * which require special processing (as indicated by the 1450 * bits in partab), call ttyoutput. After processing 1451 * a hunk of data, look for FLUSHO so ^O's will take effect 1452 * immediately. 1453 */ 1454 while (cc > 0) { 1455 if ((tp->t_oflag&OPOST) == 0) 1456 ce = cc; 1457 else { 1458 ce = cc - scanc((unsigned)cc, (u_char *)cp, 1459 (u_char *)partab, 077); 1460 /* 1461 * If ce is zero, then we're processing 1462 * a special character through ttyoutput. 1463 */ 1464 if (ce == 0) { 1465 tp->t_rocount = 0; 1466 if (ttyoutput(*cp, tp) >= 0) { 1467 /* no c-lists, wait a bit */ 1468 ttstart(tp); 1469 if (error = ttysleep(tp, 1470 (caddr_t)&lbolt, 1471 TTOPRI | PCATCH, ttybuf, 0)) 1472 break; 1473 goto loop; 1474 } 1475 cp++, cc--; 1476 if ((tp->t_lflag&FLUSHO) || 1477 tp->t_outq.c_cc > hiwat) 1478 goto ovhiwat; 1479 continue; 1480 } 1481 } 1482 /* 1483 * A bunch of normal characters have been found, 1484 * transfer them en masse to the output queue and 1485 * continue processing at the top of the loop. 1486 * If there are any further characters in this 1487 * <= OBUFSIZ chunk, the first should be a character 1488 * requiring special handling by ttyoutput. 1489 */ 1490 tp->t_rocount = 0; 1491 i = b_to_q(cp, ce, &tp->t_outq); 1492 ce -= i; 1493 tp->t_col += ce; 1494 cp += ce, cc -= ce, tk_nout += ce; 1495 tp->t_outcc += ce; 1496 if (i > 0) { 1497 /* out of c-lists, wait a bit */ 1498 ttstart(tp); 1499 if (error = ttysleep(tp, (caddr_t)&lbolt, 1500 TTOPRI | PCATCH, ttybuf, 0)) 1501 break; 1502 goto loop; 1503 } 1504 if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat) 1505 break; 1506 } 1507 ttstart(tp); 1508 } 1509 out: 1510 /* 1511 * If cc is nonzero, we leave the uio structure inconsistent, 1512 * as the offset and iov pointers have moved forward, 1513 * but it doesn't matter (the call will either return short 1514 * or restart with a new uio). 1515 */ 1516 uio->uio_resid += cc; 1517 return (error); 1518 1519 ovhiwat: 1520 ttstart(tp); 1521 s = spltty(); 1522 /* 1523 * This can only occur if FLUSHO is set in t_lflag, 1524 * or if ttstart/oproc is synchronous (or very fast). 1525 */ 1526 if (tp->t_outq.c_cc <= hiwat) { 1527 splx(s); 1528 goto loop; 1529 } 1530 if (flag & IO_NDELAY) { 1531 splx(s); 1532 uio->uio_resid += cc; 1533 if (uio->uio_resid == cnt) 1534 return (EWOULDBLOCK); 1535 return (0); 1536 } 1537 tp->t_state |= TS_ASLEEP; 1538 error = ttysleep(tp, (caddr_t)&tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1539 splx(s); 1540 if (error) 1541 goto out; 1542 goto loop; 1543 } 1544 1545 /* 1546 * Rubout one character from the rawq of tp 1547 * as cleanly as possible. 1548 */ 1549 ttyrub(c, tp) 1550 register c; 1551 register struct tty *tp; 1552 { 1553 register char *cp; 1554 register int savecol; 1555 int s; 1556 char *nextc(); 1557 1558 if ((tp->t_lflag&ECHO) == 0 || (tp->t_lflag&EXTPROC)) 1559 return; 1560 tp->t_lflag &= ~FLUSHO; 1561 if (tp->t_lflag&ECHOE) { 1562 if (tp->t_rocount == 0) { 1563 /* 1564 * Screwed by ttwrite; retype 1565 */ 1566 ttyretype(tp); 1567 return; 1568 } 1569 if (c == ('\t'|TTY_QUOTE) || c == ('\n'|TTY_QUOTE)) 1570 ttyrubo(tp, 2); 1571 else switch (partab[c&=0377]&077) { 1572 1573 case ORDINARY: 1574 ttyrubo(tp, 1); 1575 break; 1576 1577 case VTAB: 1578 case BACKSPACE: 1579 case CONTROL: 1580 case RETURN: 1581 if (tp->t_lflag&ECHOCTL) 1582 ttyrubo(tp, 2); 1583 break; 1584 1585 case TAB: { 1586 int c; 1587 1588 if (tp->t_rocount < tp->t_rawq.c_cc) { 1589 ttyretype(tp); 1590 return; 1591 } 1592 s = spltty(); 1593 savecol = tp->t_col; 1594 tp->t_state |= TS_CNTTB; 1595 tp->t_lflag |= FLUSHO; 1596 tp->t_col = tp->t_rocol; 1597 cp = tp->t_rawq.c_cf; 1598 if (cp) 1599 c = *cp; /* XXX FIX NEXTC */ 1600 for (; cp; cp = nextc(&tp->t_rawq, cp, &c)) 1601 ttyecho(c, tp); 1602 tp->t_lflag &= ~FLUSHO; 1603 tp->t_state &= ~TS_CNTTB; 1604 splx(s); 1605 /* 1606 * savecol will now be length of the tab 1607 */ 1608 savecol -= tp->t_col; 1609 tp->t_col += savecol; 1610 if (savecol > 8) 1611 savecol = 8; /* overflow screw */ 1612 while (--savecol >= 0) 1613 (void) ttyoutput('\b', tp); 1614 break; 1615 } 1616 1617 default: 1618 /* XXX */ 1619 printf("ttyrub: would panic c = %d, val = %d\n", 1620 c, partab[c&=0377]&077); 1621 /*panic("ttyrub");*/ 1622 } 1623 } else if (tp->t_lflag&ECHOPRT) { 1624 if ((tp->t_state&TS_ERASE) == 0) { 1625 (void) ttyoutput('\\', tp); 1626 tp->t_state |= TS_ERASE; 1627 } 1628 ttyecho(c, tp); 1629 } else 1630 ttyecho(tp->t_cc[VERASE], tp); 1631 tp->t_rocount--; 1632 } 1633 1634 /* 1635 * Crt back over cnt chars perhaps 1636 * erasing them. 1637 */ 1638 ttyrubo(tp, cnt) 1639 register struct tty *tp; 1640 int cnt; 1641 { 1642 1643 while (--cnt >= 0) 1644 ttyoutstr("\b \b", tp); 1645 } 1646 1647 /* 1648 * Reprint the rawq line. 1649 * We assume c_cc has already been checked. 1650 */ 1651 ttyretype(tp) 1652 register struct tty *tp; 1653 { 1654 register char *cp; 1655 char *nextc(); 1656 int s, c; 1657 1658 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1659 ttyecho(tp->t_cc[VREPRINT], tp); 1660 (void) ttyoutput('\n', tp); 1661 s = spltty(); 1662 /*** XXX *** FIX *** NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1663 BIT OF FIRST CHAR ****/ 1664 for (cp = tp->t_canq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_canq, cp, &c)) { 1665 ttyecho(c, tp); 1666 } 1667 for (cp = tp->t_rawq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_rawq, cp, &c)) { 1668 ttyecho(c, tp); 1669 } 1670 tp->t_state &= ~TS_ERASE; 1671 splx(s); 1672 tp->t_rocount = tp->t_rawq.c_cc; 1673 tp->t_rocol = 0; 1674 } 1675 1676 /* 1677 * Echo a typed character to the terminal. 1678 */ 1679 ttyecho(c, tp) 1680 register c; 1681 register struct tty *tp; 1682 { 1683 if ((tp->t_state&TS_CNTTB) == 0) 1684 tp->t_lflag &= ~FLUSHO; 1685 if (((tp->t_lflag&ECHO) == 0 && ((tp->t_lflag&ECHONL) == 0 || 1686 c == '\n')) || (tp->t_lflag&EXTPROC)) 1687 return; 1688 if (tp->t_lflag&ECHOCTL) { 1689 if ((c&TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' || 1690 c == 0177) { 1691 (void) ttyoutput('^', tp); 1692 c &= TTY_CHARMASK; 1693 if (c == 0177) 1694 c = '?'; 1695 else 1696 c += 'A' - 1; 1697 } 1698 } 1699 (void) ttyoutput(c, tp); 1700 } 1701 1702 /* 1703 * send string cp to tp 1704 */ 1705 ttyoutstr(cp, tp) 1706 register char *cp; 1707 register struct tty *tp; 1708 { 1709 register char c; 1710 1711 while (c = *cp++) 1712 (void) ttyoutput(c, tp); 1713 } 1714 1715 ttwakeup(tp) 1716 struct tty *tp; 1717 { 1718 1719 if (tp->t_rsel) { 1720 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1721 tp->t_state &= ~TS_RCOLL; 1722 tp->t_rsel = 0; 1723 } 1724 if (tp->t_state & TS_ASYNC) 1725 pgsignal(tp->t_pgrp, SIGIO, 1); 1726 wakeup((caddr_t)&tp->t_rawq); 1727 } 1728 1729 /* 1730 * set tty hi and low water marks 1731 * 1732 * Try to arrange the dynamics so there's about one second 1733 * from hi to low water. 1734 * 1735 */ 1736 ttsetwater(tp) 1737 struct tty *tp; 1738 { 1739 register cps = tp->t_ospeed / 10; 1740 register x; 1741 1742 #define clamp(x, h, l) ((x)>h ? h : ((x)<l) ? l : (x)) 1743 tp->t_lowat = x = clamp(cps/2, TTMAXLOWAT, TTMINLOWAT); 1744 x += cps; 1745 x = clamp(x, TTMAXHIWAT, TTMINHIWAT); 1746 tp->t_hiwat = roundup(x, CBSIZE); 1747 #undef clamp 1748 } 1749 1750 ttspeedtab(speed, table) 1751 struct speedtab table[]; 1752 { 1753 register int i; 1754 1755 for (i = 0; table[i].sp_speed != -1; i++) 1756 if (table[i].sp_speed == speed) 1757 return(table[i].sp_code); 1758 return(-1); 1759 } 1760 1761 int ttyhostname = 0; 1762 /* 1763 * (^T) 1764 * Report on state of foreground process group. 1765 */ 1766 ttyinfo(tp) 1767 struct tty *tp; 1768 { 1769 register struct proc *p, *pick = NULL; 1770 register char *cp = hostname; 1771 int x, s; 1772 struct timeval utime, stime; 1773 #define pgtok(a) (((a)*NBPG)/1024) 1774 1775 if (ttycheckoutq(tp,0) == 0) 1776 return; 1777 /* 1778 * hostname 1779 */ 1780 if (ttyhostname) { 1781 if (*cp == '\0') 1782 ttyprintf(tp, "amnesia"); 1783 else 1784 while (*cp && *cp != '.') 1785 tputchar(*cp++, tp); 1786 tputchar(' '); 1787 } 1788 /* 1789 * load average 1790 */ 1791 x = (averunnable[0] * 100 + FSCALE/2) >> FSHIFT; 1792 ttyprintf(tp, "load: %d.", x/100); 1793 ttyoutint(x%100, 10, 2, tp); 1794 if (tp->t_session == NULL) 1795 ttyprintf(tp, " not a controlling terminal\n"); 1796 else if (tp->t_pgrp == NULL) 1797 ttyprintf(tp, " no foreground process group\n"); 1798 else if ((p = tp->t_pgrp->pg_mem) == NULL) 1799 ttyprintf(tp, " empty foreground process group\n"); 1800 else { 1801 /* pick interesting process */ 1802 for (; p != NULL; p = p->p_pgrpnxt) { 1803 if (proc_compare(pick, p)) 1804 pick = p; 1805 } 1806 ttyprintf(tp, " cmd: %s %d [%s] ", 1807 pick->p_comm, pick->p_pid, 1808 pick->p_wmesg ? pick->p_wmesg : "running"); 1809 /* 1810 * cpu time 1811 */ 1812 if (u.u_procp == pick) 1813 s = splclock(); 1814 utime = pick->p_utime; 1815 stime = pick->p_stime; 1816 if (u.u_procp == pick) 1817 splx(s); 1818 /* user time */ 1819 x = (utime.tv_usec + 5000) / 10000; /* scale to 100's */ 1820 ttyoutint(utime.tv_sec, 10, 1, tp); 1821 tputchar('.', tp); 1822 ttyoutint(x, 10, 2, tp); 1823 tputchar('u', tp); 1824 tputchar(' ', tp); 1825 /* system time */ 1826 x = (stime.tv_usec + 5000) / 10000; /* scale to 100's */ 1827 ttyoutint(stime.tv_sec, 10, 1, tp); 1828 tputchar('.', tp); 1829 ttyoutint(x, 10, 2, tp); 1830 tputchar('s', tp); 1831 tputchar(' ', tp); 1832 /* 1833 * pctcpu 1834 */ 1835 x = pick->p_pctcpu * 10000 + FSCALE/2 >> FSHIFT; 1836 ttyoutint(x/100, 10, 1, tp); 1837 #ifdef notdef /* do we really want this ??? */ 1838 tputchar('.', tp); 1839 ttyoutint(x%100, 10, 2, tp); 1840 #endif 1841 ttyprintf(tp, "%% %dk\n", pgtok(pick->p_ssize + pick->p_dsize)); 1842 } 1843 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 1844 } 1845 1846 ttyoutint(n, base, min, tp) 1847 register int n, base, min; 1848 register struct tty *tp; 1849 { 1850 char info[16]; 1851 register char *p = info; 1852 1853 while (--min >= 0 || n) { 1854 *p++ = "0123456789abcdef"[n%base]; 1855 n /= base; 1856 } 1857 while (p > info) 1858 ttyoutput(*--p, tp); 1859 } 1860 1861 /* 1862 * Returns 1 if p2 is "better" than p1 1863 * 1864 * The algorithm for picking the "interesting" process is thus: 1865 * 1866 * 1) (Only foreground processes are eligable - implied) 1867 * 2) Runnable processes are favored over anything 1868 * else. The runner with the highest cpu 1869 * utilization is picked (p_cpu). Ties are 1870 * broken by picking the highest pid. 1871 * 3 Next, the sleeper with the shortest sleep 1872 * time is favored. With ties, we pick out 1873 * just "short-term" sleepers (SSINTR == 0). 1874 * Further ties are broken by picking the highest 1875 * pid. 1876 * 1877 */ 1878 #define isrun(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 1879 proc_compare(p1, p2) 1880 register struct proc *p1, *p2; 1881 { 1882 1883 if (p1 == NULL) 1884 return (1); 1885 /* 1886 * see if at least one of them is runnable 1887 */ 1888 switch (isrun(p1)<<1 | isrun(p2)) { 1889 case 0x01: 1890 return (1); 1891 case 0x10: 1892 return (0); 1893 case 0x11: 1894 /* 1895 * tie - favor one with highest recent cpu utilization 1896 */ 1897 if (p2->p_cpu > p1->p_cpu) 1898 return (1); 1899 if (p1->p_cpu > p2->p_cpu) 1900 return (0); 1901 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1902 } 1903 /* 1904 * pick the one with the smallest sleep time 1905 */ 1906 if (p2->p_slptime > p1->p_slptime) 1907 return (0); 1908 if (p1->p_slptime > p2->p_slptime) 1909 return (1); 1910 /* 1911 * favor one sleeping in a non-interruptible sleep 1912 */ 1913 if (p1->p_flag&SSINTR && (p2->p_flag&SSINTR) == 0) 1914 return (1); 1915 if (p2->p_flag&SSINTR && (p1->p_flag&SSINTR) == 0) 1916 return (0); 1917 return(p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1918 } 1919 #define TOTTY 0x2 /* XXX should be in header */ 1920 /*VARARGS2*/ 1921 ttyprintf(tp, fmt, x1) 1922 struct tty *tp; 1923 char *fmt; 1924 unsigned x1; 1925 { 1926 prf(fmt, &x1, TOTTY, (caddr_t)tp); 1927 } 1928 1929 /* 1930 * Output char to tty; console putchar style. 1931 */ 1932 tputchar(c, tp) 1933 int c; 1934 struct tty *tp; 1935 { 1936 register s = spltty(); 1937 1938 if ((tp->t_state & (TS_CARR_ON | TS_ISOPEN)) 1939 == (TS_CARR_ON | TS_ISOPEN)) { 1940 if (c == '\n') 1941 (void) ttyoutput('\r', tp); 1942 (void) ttyoutput(c, tp); 1943 ttstart(tp); 1944 splx(s); 1945 return (0); 1946 } 1947 splx(s); 1948 return (-1); 1949 } 1950 1951 ttysleep(tp, chan, pri, wmesg, timo) 1952 struct tty *tp; 1953 caddr_t chan; 1954 int pri; 1955 char *wmesg; 1956 int timo; 1957 { 1958 int error; 1959 short gen = tp->t_gen; 1960 1961 if (error = tsleep(chan, pri, wmesg, timo)) 1962 return (error); 1963 if (tp->t_gen != gen) 1964 return (ERESTART); 1965 return (0); 1966 } 1967