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