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