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.5 (Berkeley) 11/15/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 = (ISSET(c, TTY_ERRORMASK))) { 209 CLR(c, TTY_ERRORMASK); 210 if (ISSET(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 (ISSET(err, TTY_PE) && 220 ISSET(iflag, INPCK) || ISSET(err, TTY_FE)) { 221 if (ISSET(iflag, IGNPAR)) 222 goto endcase; 223 else if (ISSET(iflag, PARMRK)) { 224 parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 225 (void)putc(0 | TTY_QUOTE, &tp->t_rawq); 226 (void)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 CLR(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 SET(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 (void)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_column; 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_column; 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_column - 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 CLR(c, ~TTY_CHARMASK); 523 if (c == '\t' && 524 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { 525 c = 8 - (tp->t_column & 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_column += c; 534 return (c ? -1 : '\t'); 535 } 536 if (c == CEOT && ISSET(oflag, ONOEOT)) 537 return (-1); 538 539 /* 540 * Newline translation: if ONLCR is set, 541 * translate newline into "\r\n". 542 */ 543 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { 544 tk_nout++; 545 tp->t_outcc++; 546 if (putc('\r', &tp->t_outq)) 547 return (c); 548 } 549 tk_nout++; 550 tp->t_outcc++; 551 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 552 return (c); 553 554 col = tp->t_column; 555 switch (CCLASS(c)) { 556 case BACKSPACE: 557 if (col > 0) 558 --col; 559 break; 560 case CONTROL: 561 break; 562 case NEWLINE: 563 case RETURN: 564 col = 0; 565 break; 566 case ORDINARY: 567 ++col; 568 break; 569 case TAB: 570 col = (col + 8) & ~7; 571 break; 572 } 573 tp->t_column = col; 574 return (-1); 575 } 576 577 /* 578 * Ioctls for all tty devices. Called after line-discipline specific ioctl 579 * has been called to do discipline-specific functions and/or reject any 580 * of these ioctl commands. 581 */ 582 /* ARGSUSED */ 583 int 584 ttioctl(tp, cmd, data, flag) 585 register struct tty *tp; 586 int cmd, flag; 587 void *data; 588 { 589 extern struct tty *constty; /* Temporary virtual console. */ 590 extern int nlinesw; 591 register struct proc *p; 592 int s, error; 593 594 p = curproc; /* XXX */ 595 596 /* If the ioctl involves modification, hang if in the background. */ 597 switch (cmd) { 598 case TIOCFLUSH: 599 case TIOCSETA: 600 case TIOCSETD: 601 case TIOCSETAF: 602 case TIOCSETAW: 603 #ifdef notdef 604 case TIOCSPGRP: 605 #endif 606 case TIOCSTI: 607 case TIOCSWINSZ: 608 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 609 case TIOCLBIC: 610 case TIOCLBIS: 611 case TIOCLSET: 612 case TIOCSETC: 613 case OTIOCSETD: 614 case TIOCSETN: 615 case TIOCSETP: 616 case TIOCSLTC: 617 #endif 618 while (isbackground(curproc, tp) && 619 p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 && 620 (p->p_sigignore & sigmask(SIGTTOU)) == 0 && 621 (p->p_sigmask & sigmask(SIGTTOU)) == 0) { 622 pgsignal(p->p_pgrp, SIGTTOU, 1); 623 if (error = ttysleep(tp, 624 &lbolt, TTOPRI | PCATCH, ttybg, 0)) 625 return (error); 626 } 627 break; 628 } 629 630 switch (cmd) { /* Process the ioctl. */ 631 case FIOASYNC: /* set/clear async i/o */ 632 s = spltty(); 633 if (*(int *)data) 634 SET(tp->t_state, TS_ASYNC); 635 else 636 CLR(tp->t_state, TS_ASYNC); 637 splx(s); 638 break; 639 case FIONBIO: /* set/clear non-blocking i/o */ 640 break; /* XXX: delete. */ 641 case FIONREAD: /* get # bytes to read */ 642 *(int *)data = ttnread(tp); 643 break; 644 case TIOCEXCL: /* set exclusive use of tty */ 645 s = spltty(); 646 SET(tp->t_state, TS_XCLUDE); 647 splx(s); 648 break; 649 case TIOCFLUSH: { /* flush buffers */ 650 register int flags = *(int *)data; 651 652 if (flags == 0) 653 flags = FREAD | FWRITE; 654 else 655 flags &= FREAD | FWRITE; 656 ttyflush(tp, flags); 657 break; 658 } 659 case TIOCCONS: /* become virtual console */ 660 if (*(int *)data) { 661 if (constty && constty != tp && 662 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) == 663 (TS_CARR_ON | TS_ISOPEN)) 664 return (EBUSY); 665 #ifndef UCONSOLE 666 if (error = suser(p->p_ucred, &p->p_acflag)) 667 return (error); 668 #endif 669 constty = tp; 670 } else if (tp == constty) 671 constty = NULL; 672 break; 673 case TIOCDRAIN: /* wait till output drained */ 674 if (error = ttywait(tp)) 675 return (error); 676 break; 677 case TIOCGETA: { /* get termios struct */ 678 struct termios *t = (struct termios *)data; 679 680 bcopy(&tp->t_termios, t, sizeof(struct termios)); 681 break; 682 } 683 case TIOCGETD: /* get line discipline */ 684 *(int *)data = tp->t_line; 685 break; 686 case TIOCGWINSZ: /* get window size */ 687 *(struct winsize *)data = tp->t_winsize; 688 break; 689 case TIOCGPGRP: /* get pgrp of tty */ 690 if (!isctty(p, tp)) 691 return (ENOTTY); 692 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 693 break; 694 #ifdef TIOCHPCL 695 case TIOCHPCL: /* hang up on last close */ 696 s = spltty(); 697 SET(tp->t_cflag, HUPCL); 698 splx(s); 699 break; 700 #endif 701 case TIOCNXCL: /* reset exclusive use of tty */ 702 s = spltty(); 703 CLR(tp->t_state, TS_XCLUDE); 704 splx(s); 705 break; 706 case TIOCOUTQ: /* output queue size */ 707 *(int *)data = tp->t_outq.c_cc; 708 break; 709 case TIOCSETA: /* set termios struct */ 710 case TIOCSETAW: /* drain output, set */ 711 case TIOCSETAF: { /* drn out, fls in, set */ 712 register struct termios *t = (struct termios *)data; 713 714 s = spltty(); 715 if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 716 if (error = ttywait(tp)) { 717 splx(s); 718 return (error); 719 } 720 if (cmd == TIOCSETAF) 721 ttyflush(tp, FREAD); 722 } 723 if (!ISSET(t->c_cflag, CIGNORE)) { 724 /* 725 * Set device hardware. 726 */ 727 if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 728 splx(s); 729 return (error); 730 } else { 731 if (!ISSET(tp->t_state, TS_CARR_ON) && 732 ISSET(tp->t_cflag, CLOCAL) && 733 !ISSET(t->c_cflag, CLOCAL)) { 734 CLR(tp->t_state, TS_ISOPEN); 735 SET(tp->t_state, TS_WOPEN); 736 ttwakeup(tp); 737 } 738 tp->t_cflag = t->c_cflag; 739 tp->t_ispeed = t->c_ispeed; 740 tp->t_ospeed = t->c_ospeed; 741 } 742 ttsetwater(tp); 743 } 744 if (cmd != TIOCSETAF) { 745 if (ISSET(t->c_lflag, ICANON) != 746 ISSET(tp->t_lflag, ICANON)) 747 if (ISSET(t->c_lflag, ICANON)) { 748 SET(tp->t_lflag, PENDIN); 749 ttwakeup(tp); 750 } else { 751 struct clist tq; 752 753 catq(&tp->t_rawq, &tp->t_canq); 754 tq = tp->t_rawq; 755 tp->t_rawq = tp->t_canq; 756 tp->t_canq = tq; 757 } 758 } 759 tp->t_iflag = t->c_iflag; 760 tp->t_oflag = t->c_oflag; 761 /* 762 * Make the EXTPROC bit read only. 763 */ 764 if (ISSET(tp->t_lflag, EXTPROC)) 765 SET(t->c_lflag, EXTPROC); 766 else 767 CLR(t->c_lflag, EXTPROC); 768 tp->t_lflag = t->c_lflag; 769 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 770 splx(s); 771 break; 772 } 773 case TIOCSETD: { /* set line discipline */ 774 register int t = *(int *)data; 775 dev_t device = tp->t_dev; 776 777 if ((u_int)t >= nlinesw) 778 return (ENXIO); 779 if (t != tp->t_line) { 780 s = spltty(); 781 (*linesw[tp->t_line].l_close)(tp, flag); 782 error = (*linesw[t].l_open)(device, tp); 783 if (error) { 784 (void)(*linesw[tp->t_line].l_open)(device, tp); 785 splx(s); 786 return (error); 787 } 788 tp->t_line = t; 789 splx(s); 790 } 791 break; 792 } 793 case TIOCSTART: /* start output, like ^Q */ 794 s = spltty(); 795 if (ISSET(tp->t_state, TS_TTSTOP) || 796 ISSET(tp->t_lflag, FLUSHO)) { 797 CLR(tp->t_lflag, FLUSHO); 798 CLR(tp->t_state, TS_TTSTOP); 799 ttstart(tp); 800 } 801 splx(s); 802 break; 803 case TIOCSTI: /* simulate terminal input */ 804 if (p->p_ucred->cr_uid && (flag & FREAD) == 0) 805 return (EPERM); 806 if (p->p_ucred->cr_uid && !isctty(p, tp)) 807 return (EACCES); 808 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp); 809 break; 810 case TIOCSTOP: /* stop output, like ^S */ 811 s = spltty(); 812 if (!ISSET(tp->t_state, TS_TTSTOP)) { 813 SET(tp->t_state, TS_TTSTOP); 814 #ifdef sun4c /* XXX */ 815 (*tp->t_stop)(tp, 0); 816 #else 817 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 818 #endif 819 } 820 splx(s); 821 break; 822 case TIOCSCTTY: /* become controlling tty */ 823 /* Session ctty vnode pointer set in vnode layer. */ 824 if (!SESS_LEADER(p) || 825 (p->p_session->s_ttyvp || tp->t_session) && 826 (tp->t_session != p->p_session)) 827 return (EPERM); 828 tp->t_session = p->p_session; 829 tp->t_pgrp = p->p_pgrp; 830 p->p_session->s_ttyp = tp; 831 p->p_flag |= P_CONTROLT; 832 break; 833 case TIOCSPGRP: { /* set pgrp of tty */ 834 register struct pgrp *pgrp = pgfind(*(int *)data); 835 836 if (!isctty(p, tp)) 837 return (ENOTTY); 838 else if (pgrp == NULL || pgrp->pg_session != p->p_session) 839 return (EPERM); 840 tp->t_pgrp = pgrp; 841 break; 842 } 843 case TIOCSWINSZ: /* set window size */ 844 if (bcmp((caddr_t)&tp->t_winsize, data, 845 sizeof (struct winsize))) { 846 tp->t_winsize = *(struct winsize *)data; 847 pgsignal(tp->t_pgrp, SIGWINCH, 1); 848 } 849 break; 850 default: 851 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 852 return (ttcompat(tp, cmd, data, flag)); 853 #else 854 return (-1); 855 #endif 856 } 857 return (0); 858 } 859 860 int 861 ttselect(device, rw, p) 862 dev_t device; 863 int rw; 864 struct proc *p; 865 { 866 register struct tty *tp; 867 int nread, s; 868 869 tp = &cdevsw[major(device)].d_ttys[minor(device)]; 870 871 s = spltty(); 872 switch (rw) { 873 case FREAD: 874 nread = ttnread(tp); 875 if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) && 876 !ISSET(tp->t_state, TS_CARR_ON)) 877 goto win; 878 selrecord(p, &tp->t_rsel); 879 break; 880 case FWRITE: 881 if (tp->t_outq.c_cc <= tp->t_lowat) { 882 win: splx(s); 883 return (1); 884 } 885 selrecord(p, &tp->t_wsel); 886 break; 887 } 888 splx(s); 889 return (0); 890 } 891 892 static int 893 ttnread(tp) 894 struct tty *tp; 895 { 896 int nread; 897 898 if (ISSET(tp->t_lflag, PENDIN)) 899 ttypend(tp); 900 nread = tp->t_canq.c_cc; 901 if (!ISSET(tp->t_lflag, ICANON)) 902 nread += tp->t_rawq.c_cc; 903 return (nread); 904 } 905 906 /* 907 * Wait for output to drain. 908 */ 909 int 910 ttywait(tp) 911 register struct tty *tp; 912 { 913 int error, s; 914 915 error = 0; 916 s = spltty(); 917 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 918 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) 919 && tp->t_oproc) { 920 (*tp->t_oproc)(tp); 921 SET(tp->t_state, TS_ASLEEP); 922 if (error = ttysleep(tp, 923 &tp->t_outq, TTOPRI | PCATCH, ttyout, 0)) 924 break; 925 } 926 splx(s); 927 return (error); 928 } 929 930 /* 931 * Flush if successfully wait. 932 */ 933 int 934 ttywflush(tp) 935 struct tty *tp; 936 { 937 int error; 938 939 if ((error = ttywait(tp)) == 0) 940 ttyflush(tp, FREAD); 941 return (error); 942 } 943 944 /* 945 * Flush tty read and/or write queues, notifying anyone waiting. 946 */ 947 void 948 ttyflush(tp, rw) 949 register struct tty *tp; 950 int rw; 951 { 952 register int s; 953 954 s = spltty(); 955 if (rw & FREAD) { 956 FLUSHQ(&tp->t_canq); 957 FLUSHQ(&tp->t_rawq); 958 tp->t_rocount = 0; 959 tp->t_rocol = 0; 960 CLR(tp->t_state, TS_LOCAL); 961 ttwakeup(tp); 962 } 963 if (rw & FWRITE) { 964 CLR(tp->t_state, TS_TTSTOP); 965 #ifdef sun4c /* XXX */ 966 (*tp->t_stop)(tp, rw); 967 #else 968 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 969 #endif 970 FLUSHQ(&tp->t_outq); 971 wakeup((caddr_t)&tp->t_outq); 972 selwakeup(&tp->t_wsel); 973 } 974 splx(s); 975 } 976 977 /* 978 * Copy in the default termios characters. 979 */ 980 void 981 ttychars(tp) 982 struct tty *tp; 983 { 984 985 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 986 } 987 988 /* 989 * Send stop character on input overflow. 990 */ 991 static void 992 ttyblock(tp) 993 register struct tty *tp; 994 { 995 register int total; 996 997 total = tp->t_rawq.c_cc + tp->t_canq.c_cc; 998 if (tp->t_rawq.c_cc > TTYHOG) { 999 ttyflush(tp, FREAD | FWRITE); 1000 CLR(tp->t_state, TS_TBLOCK); 1001 } 1002 /* 1003 * Block further input iff: current input > threshold 1004 * AND input is available to user program. 1005 */ 1006 if (total >= TTYHOG / 2 && 1007 !ISSET(tp->t_state, TS_TBLOCK) && 1008 !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0 && 1009 tp->t_cc[VSTOP] != _POSIX_VDISABLE) { 1010 if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) { 1011 SET(tp->t_state, TS_TBLOCK); 1012 ttstart(tp); 1013 } 1014 } 1015 } 1016 1017 void 1018 ttrstrt(tp_arg) 1019 void *tp_arg; 1020 { 1021 struct tty *tp; 1022 int s; 1023 1024 #ifdef DIAGNOSTIC 1025 if (tp_arg == NULL) 1026 panic("ttrstrt"); 1027 #endif 1028 tp = tp_arg; 1029 s = spltty(); 1030 1031 CLR(tp->t_state, TS_TIMEOUT); 1032 ttstart(tp); 1033 1034 splx(s); 1035 } 1036 1037 int 1038 ttstart(tp) 1039 struct tty *tp; 1040 { 1041 1042 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1043 (*tp->t_oproc)(tp); 1044 return (0); 1045 } 1046 1047 /* 1048 * "close" a line discipline 1049 */ 1050 int 1051 ttylclose(tp, flag) 1052 struct tty *tp; 1053 int flag; 1054 { 1055 1056 if (flag & IO_NDELAY) 1057 ttyflush(tp, FREAD | FWRITE); 1058 else 1059 ttywflush(tp); 1060 return (0); 1061 } 1062 1063 /* 1064 * Handle modem control transition on a tty. 1065 * Flag indicates new state of carrier. 1066 * Returns 0 if the line should be turned off, otherwise 1. 1067 */ 1068 int 1069 ttymodem(tp, flag) 1070 register struct tty *tp; 1071 int flag; 1072 { 1073 1074 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) { 1075 /* 1076 * MDMBUF: do flow control according to carrier flag 1077 */ 1078 if (flag) { 1079 CLR(tp->t_state, TS_TTSTOP); 1080 ttstart(tp); 1081 } else if (!ISSET(tp->t_state, TS_TTSTOP)) { 1082 SET(tp->t_state, TS_TTSTOP); 1083 #ifdef sun4c /* XXX */ 1084 (*tp->t_stop)(tp, 0); 1085 #else 1086 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 1087 #endif 1088 } 1089 } else if (flag == 0) { 1090 /* 1091 * Lost carrier. 1092 */ 1093 CLR(tp->t_state, TS_CARR_ON); 1094 if (ISSET(tp->t_state, TS_ISOPEN) && 1095 !ISSET(tp->t_cflag, CLOCAL)) { 1096 if (tp->t_session && tp->t_session->s_leader) 1097 psignal(tp->t_session->s_leader, SIGHUP); 1098 ttyflush(tp, FREAD | FWRITE); 1099 return (0); 1100 } 1101 } else { 1102 /* 1103 * Carrier now on. 1104 */ 1105 SET(tp->t_state, TS_CARR_ON); 1106 ttwakeup(tp); 1107 } 1108 return (1); 1109 } 1110 1111 /* 1112 * Default modem control routine (for other line disciplines). 1113 * Return argument flag, to turn off device on carrier drop. 1114 */ 1115 int 1116 nullmodem(tp, flag) 1117 register struct tty *tp; 1118 int flag; 1119 { 1120 1121 if (flag) 1122 SET(tp->t_state, TS_CARR_ON); 1123 else { 1124 CLR(tp->t_state, TS_CARR_ON); 1125 if (!ISSET(tp->t_cflag, CLOCAL)) { 1126 if (tp->t_session && tp->t_session->s_leader) 1127 psignal(tp->t_session->s_leader, SIGHUP); 1128 return (0); 1129 } 1130 } 1131 return (1); 1132 } 1133 1134 /* 1135 * Reinput pending characters after state switch 1136 * call at spltty(). 1137 */ 1138 void 1139 ttypend(tp) 1140 register struct tty *tp; 1141 { 1142 struct clist tq; 1143 register c; 1144 1145 CLR(tp->t_lflag, PENDIN); 1146 SET(tp->t_state, TS_TYPEN); 1147 tq = tp->t_rawq; 1148 tp->t_rawq.c_cc = 0; 1149 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 1150 while ((c = getc(&tq)) >= 0) 1151 ttyinput(c, tp); 1152 CLR(tp->t_state, TS_TYPEN); 1153 } 1154 1155 /* 1156 * Process a read call on a tty device. 1157 */ 1158 int 1159 ttread(tp, uio, flag) 1160 register struct tty *tp; 1161 struct uio *uio; 1162 int flag; 1163 { 1164 register struct clist *qp; 1165 register int c; 1166 register long lflag; 1167 register u_char *cc = tp->t_cc; 1168 register struct proc *p = curproc; 1169 int s, first, error = 0; 1170 1171 loop: lflag = tp->t_lflag; 1172 s = spltty(); 1173 /* 1174 * take pending input first 1175 */ 1176 if (ISSET(lflag, PENDIN)) 1177 ttypend(tp); 1178 splx(s); 1179 1180 /* 1181 * Hang process if it's in the background. 1182 */ 1183 if (isbackground(p, tp)) { 1184 if ((p->p_sigignore & sigmask(SIGTTIN)) || 1185 (p->p_sigmask & sigmask(SIGTTIN)) || 1186 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) 1187 return (EIO); 1188 pgsignal(p->p_pgrp, SIGTTIN, 1); 1189 if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0)) 1190 return (error); 1191 goto loop; 1192 } 1193 1194 /* 1195 * If canonical, use the canonical queue, 1196 * else use the raw queue. 1197 * 1198 * (should get rid of clists...) 1199 */ 1200 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq; 1201 1202 /* 1203 * If there is no input, sleep on rawq 1204 * awaiting hardware receipt and notification. 1205 * If we have data, we don't need to check for carrier. 1206 */ 1207 s = spltty(); 1208 if (qp->c_cc <= 0) { 1209 int carrier; 1210 1211 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1212 ISSET(tp->t_cflag, CLOCAL); 1213 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) { 1214 splx(s); 1215 return (0); /* EOF */ 1216 } 1217 if (flag & IO_NDELAY) { 1218 splx(s); 1219 return (EWOULDBLOCK); 1220 } 1221 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 1222 carrier ? ttyin : ttopen, 0); 1223 splx(s); 1224 if (error) 1225 return (error); 1226 goto loop; 1227 } 1228 splx(s); 1229 1230 /* 1231 * Input present, check for input mapping and processing. 1232 */ 1233 first = 1; 1234 while ((c = getc(qp)) >= 0) { 1235 /* 1236 * delayed suspend (^Y) 1237 */ 1238 if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) { 1239 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1240 if (first) { 1241 if (error = ttysleep(tp, 1242 &lbolt, TTIPRI | PCATCH, ttybg, 0)) 1243 break; 1244 goto loop; 1245 } 1246 break; 1247 } 1248 /* 1249 * Interpret EOF only in canonical mode. 1250 */ 1251 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1252 break; 1253 /* 1254 * Give user character. 1255 */ 1256 error = ureadc(c, uio); 1257 if (error) 1258 break; 1259 if (uio->uio_resid == 0) 1260 break; 1261 /* 1262 * In canonical mode check for a "break character" 1263 * marking the end of a "line of input". 1264 */ 1265 if (ISSET(lflag, ICANON) && TTBREAKC(c)) 1266 break; 1267 first = 0; 1268 } 1269 /* 1270 * Look to unblock output now that (presumably) 1271 * the input queue has gone down. 1272 */ 1273 s = spltty(); 1274 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { 1275 if (cc[VSTART] != _POSIX_VDISABLE && 1276 putc(cc[VSTART], &tp->t_outq) == 0) { 1277 CLR(tp->t_state, TS_TBLOCK); 1278 ttstart(tp); 1279 } 1280 } 1281 splx(s); 1282 return (error); 1283 } 1284 1285 /* 1286 * Check the output queue on tp for space for a kernel message (from uprintf 1287 * or tprintf). Allow some space over the normal hiwater mark so we don't 1288 * lose messages due to normal flow control, but don't let the tty run amok. 1289 * Sleeps here are not interruptible, but we return prematurely if new signals 1290 * arrive. 1291 */ 1292 int 1293 ttycheckoutq(tp, wait) 1294 register struct tty *tp; 1295 int wait; 1296 { 1297 int hiwat, s, oldsig; 1298 1299 hiwat = tp->t_hiwat; 1300 s = spltty(); 1301 oldsig = wait ? curproc->p_siglist : 0; 1302 if (tp->t_outq.c_cc > hiwat + 200) 1303 while (tp->t_outq.c_cc > hiwat) { 1304 ttstart(tp); 1305 if (wait == 0 || curproc->p_siglist != oldsig) { 1306 splx(s); 1307 return (0); 1308 } 1309 timeout((void (*)__P((void *)))wakeup, 1310 (void *)&tp->t_outq, hz); 1311 SET(tp->t_state, TS_ASLEEP); 1312 sleep((caddr_t)&tp->t_outq, PZERO - 1); 1313 } 1314 splx(s); 1315 return (1); 1316 } 1317 1318 /* 1319 * Process a write call on a tty device. 1320 */ 1321 int 1322 ttwrite(tp, uio, flag) 1323 register struct tty *tp; 1324 register struct uio *uio; 1325 int flag; 1326 { 1327 register char *cp; 1328 register int cc, ce; 1329 register struct proc *p; 1330 int i, hiwat, cnt, error, s; 1331 char obuf[OBUFSIZ]; 1332 1333 hiwat = tp->t_hiwat; 1334 cnt = uio->uio_resid; 1335 error = 0; 1336 cc = 0; 1337 loop: 1338 s = spltty(); 1339 if (!ISSET(tp->t_state, TS_CARR_ON) && 1340 !ISSET(tp->t_cflag, CLOCAL)) { 1341 if (ISSET(tp->t_state, TS_ISOPEN)) { 1342 splx(s); 1343 return (EIO); 1344 } else if (flag & IO_NDELAY) { 1345 splx(s); 1346 error = EWOULDBLOCK; 1347 goto out; 1348 } else { 1349 /* Sleep awaiting carrier. */ 1350 error = ttysleep(tp, 1351 &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0); 1352 splx(s); 1353 if (error) 1354 goto out; 1355 goto loop; 1356 } 1357 } 1358 splx(s); 1359 /* 1360 * Hang the process if it's in the background. 1361 */ 1362 p = curproc; 1363 if (isbackground(p, tp) && 1364 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 && 1365 (p->p_sigignore & sigmask(SIGTTOU)) == 0 && 1366 (p->p_sigmask & sigmask(SIGTTOU)) == 0 && 1367 p->p_pgrp->pg_jobc) { 1368 pgsignal(p->p_pgrp, SIGTTOU, 1); 1369 if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0)) 1370 goto out; 1371 goto loop; 1372 } 1373 /* 1374 * Process the user's data in at most OBUFSIZ chunks. Perform any 1375 * output translation. Keep track of high water mark, sleep on 1376 * overflow awaiting device aid in acquiring new space. 1377 */ 1378 while (uio->uio_resid > 0 || cc > 0) { 1379 if (ISSET(tp->t_lflag, FLUSHO)) { 1380 uio->uio_resid = 0; 1381 return (0); 1382 } 1383 if (tp->t_outq.c_cc > hiwat) 1384 goto ovhiwat; 1385 /* 1386 * Grab a hunk of data from the user, unless we have some 1387 * leftover from last time. 1388 */ 1389 if (cc == 0) { 1390 cc = min(uio->uio_resid, OBUFSIZ); 1391 cp = obuf; 1392 error = uiomove(cp, cc, uio); 1393 if (error) { 1394 cc = 0; 1395 break; 1396 } 1397 } 1398 /* 1399 * If nothing fancy need be done, grab those characters we 1400 * can handle without any of ttyoutput's processing and 1401 * just transfer them to the output q. For those chars 1402 * which require special processing (as indicated by the 1403 * bits in char_type), call ttyoutput. After processing 1404 * a hunk of data, look for FLUSHO so ^O's will take effect 1405 * immediately. 1406 */ 1407 while (cc > 0) { 1408 if (!ISSET(tp->t_oflag, OPOST)) 1409 ce = cc; 1410 else { 1411 ce = cc - scanc((u_int)cc, (u_char *)cp, 1412 (u_char *)char_type, CCLASSMASK); 1413 /* 1414 * If ce is zero, then we're processing 1415 * a special character through ttyoutput. 1416 */ 1417 if (ce == 0) { 1418 tp->t_rocount = 0; 1419 if (ttyoutput(*cp, tp) >= 0) { 1420 /* No Clists, wait a bit. */ 1421 ttstart(tp); 1422 if (error = ttysleep(tp, &lbolt, 1423 TTOPRI | PCATCH, ttybuf, 0)) 1424 break; 1425 goto loop; 1426 } 1427 cp++; 1428 cc--; 1429 if (ISSET(tp->t_lflag, FLUSHO) || 1430 tp->t_outq.c_cc > hiwat) 1431 goto ovhiwat; 1432 continue; 1433 } 1434 } 1435 /* 1436 * A bunch of normal characters have been found. 1437 * Transfer them en masse to the output queue and 1438 * continue processing at the top of the loop. 1439 * If there are any further characters in this 1440 * <= OBUFSIZ chunk, the first should be a character 1441 * requiring special handling by ttyoutput. 1442 */ 1443 tp->t_rocount = 0; 1444 i = b_to_q(cp, ce, &tp->t_outq); 1445 ce -= i; 1446 tp->t_column += ce; 1447 cp += ce, cc -= ce, tk_nout += ce; 1448 tp->t_outcc += ce; 1449 if (i > 0) { 1450 /* No Clists, wait a bit. */ 1451 ttstart(tp); 1452 if (error = ttysleep(tp, 1453 &lbolt, TTOPRI | PCATCH, ttybuf, 0)) 1454 break; 1455 goto loop; 1456 } 1457 if (ISSET(tp->t_lflag, FLUSHO) || 1458 tp->t_outq.c_cc > hiwat) 1459 break; 1460 } 1461 ttstart(tp); 1462 } 1463 out: 1464 /* 1465 * If cc is nonzero, we leave the uio structure inconsistent, as the 1466 * offset and iov pointers have moved forward, but it doesn't matter 1467 * (the call will either return short or restart with a new uio). 1468 */ 1469 uio->uio_resid += cc; 1470 return (error); 1471 1472 ovhiwat: 1473 ttstart(tp); 1474 s = spltty(); 1475 /* 1476 * This can only occur if FLUSHO is set in t_lflag, 1477 * or if ttstart/oproc is synchronous (or very fast). 1478 */ 1479 if (tp->t_outq.c_cc <= hiwat) { 1480 splx(s); 1481 goto loop; 1482 } 1483 if (flag & IO_NDELAY) { 1484 splx(s); 1485 uio->uio_resid += cc; 1486 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1487 } 1488 SET(tp->t_state, TS_ASLEEP); 1489 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1490 splx(s); 1491 if (error) 1492 goto out; 1493 goto loop; 1494 } 1495 1496 /* 1497 * Rubout one character from the rawq of tp 1498 * as cleanly as possible. 1499 */ 1500 void 1501 ttyrub(c, tp) 1502 register int c; 1503 register struct tty *tp; 1504 { 1505 register char *cp; 1506 register int savecol; 1507 int tabc, s; 1508 1509 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1510 return; 1511 CLR(tp->t_lflag, FLUSHO); 1512 if (ISSET(tp->t_lflag, ECHOE)) { 1513 if (tp->t_rocount == 0) { 1514 /* 1515 * Screwed by ttwrite; retype 1516 */ 1517 ttyretype(tp); 1518 return; 1519 } 1520 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1521 ttyrubo(tp, 2); 1522 else { 1523 CLR(c, ~TTY_CHARMASK); 1524 switch (CCLASS(c)) { 1525 case ORDINARY: 1526 ttyrubo(tp, 1); 1527 break; 1528 case BACKSPACE: 1529 case CONTROL: 1530 case NEWLINE: 1531 case RETURN: 1532 case VTAB: 1533 if (ISSET(tp->t_lflag, ECHOCTL)) 1534 ttyrubo(tp, 2); 1535 break; 1536 case TAB: 1537 if (tp->t_rocount < tp->t_rawq.c_cc) { 1538 ttyretype(tp); 1539 return; 1540 } 1541 s = spltty(); 1542 savecol = tp->t_column; 1543 SET(tp->t_state, TS_CNTTB); 1544 SET(tp->t_lflag, FLUSHO); 1545 tp->t_column = tp->t_rocol; 1546 cp = tp->t_rawq.c_cf; 1547 if (cp) 1548 tabc = *cp; /* XXX FIX NEXTC */ 1549 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 1550 ttyecho(tabc, tp); 1551 CLR(tp->t_lflag, FLUSHO); 1552 CLR(tp->t_state, TS_CNTTB); 1553 splx(s); 1554 1555 /* savecol will now be length of the tab. */ 1556 savecol -= tp->t_column; 1557 tp->t_column += savecol; 1558 if (savecol > 8) 1559 savecol = 8; /* overflow screw */ 1560 while (--savecol >= 0) 1561 (void)ttyoutput('\b', tp); 1562 break; 1563 default: /* XXX */ 1564 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1565 (void)printf(PANICSTR, c, CCLASS(c)); 1566 #ifdef notdef 1567 panic(PANICSTR, c, CCLASS(c)); 1568 #endif 1569 } 1570 } 1571 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1572 if (!ISSET(tp->t_state, TS_ERASE)) { 1573 SET(tp->t_state, TS_ERASE); 1574 (void)ttyoutput('\\', tp); 1575 } 1576 ttyecho(c, tp); 1577 } else 1578 ttyecho(tp->t_cc[VERASE], tp); 1579 --tp->t_rocount; 1580 } 1581 1582 /* 1583 * Back over cnt characters, erasing them. 1584 */ 1585 static void 1586 ttyrubo(tp, cnt) 1587 register struct tty *tp; 1588 int cnt; 1589 { 1590 1591 while (cnt-- > 0) { 1592 (void)ttyoutput('\b', tp); 1593 (void)ttyoutput(' ', tp); 1594 (void)ttyoutput('\b', tp); 1595 } 1596 } 1597 1598 /* 1599 * ttyretype -- 1600 * Reprint the rawq line. Note, it is assumed that c_cc has already 1601 * been checked. 1602 */ 1603 void 1604 ttyretype(tp) 1605 register struct tty *tp; 1606 { 1607 register char *cp; 1608 int s, c; 1609 1610 /* Echo the reprint character. */ 1611 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1612 ttyecho(tp->t_cc[VREPRINT], tp); 1613 1614 (void)ttyoutput('\n', tp); 1615 1616 /* 1617 * XXX 1618 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1619 * BIT OF FIRST CHAR. 1620 */ 1621 s = spltty(); 1622 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 1623 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 1624 ttyecho(c, tp); 1625 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 1626 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 1627 ttyecho(c, tp); 1628 CLR(tp->t_state, TS_ERASE); 1629 splx(s); 1630 1631 tp->t_rocount = tp->t_rawq.c_cc; 1632 tp->t_rocol = 0; 1633 } 1634 1635 /* 1636 * Echo a typed character to the terminal. 1637 */ 1638 static void 1639 ttyecho(c, tp) 1640 register int c; 1641 register struct tty *tp; 1642 { 1643 1644 if (!ISSET(tp->t_state, TS_CNTTB)) 1645 CLR(tp->t_lflag, FLUSHO); 1646 if ((!ISSET(tp->t_lflag, ECHO) && 1647 (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) || 1648 ISSET(tp->t_lflag, EXTPROC)) 1649 return; 1650 if (ISSET(tp->t_lflag, ECHOCTL) && 1651 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' || 1652 ISSET(c, TTY_CHARMASK) == 0177)) { 1653 (void)ttyoutput('^', tp); 1654 CLR(c, ~TTY_CHARMASK); 1655 if (c == 0177) 1656 c = '?'; 1657 else 1658 c += 'A' - 1; 1659 } 1660 (void)ttyoutput(c, tp); 1661 } 1662 1663 /* 1664 * Wake up any readers on a tty. 1665 */ 1666 void 1667 ttwakeup(tp) 1668 register struct tty *tp; 1669 { 1670 1671 selwakeup(&tp->t_rsel); 1672 if (ISSET(tp->t_state, TS_ASYNC)) 1673 pgsignal(tp->t_pgrp, SIGIO, 1); 1674 wakeup((caddr_t)&tp->t_rawq); 1675 } 1676 1677 /* 1678 * Look up a code for a specified speed in a conversion table; 1679 * used by drivers to map software speed values to hardware parameters. 1680 */ 1681 int 1682 ttspeedtab(speed, table) 1683 int speed; 1684 register struct speedtab *table; 1685 { 1686 1687 for ( ; table->sp_speed != -1; table++) 1688 if (table->sp_speed == speed) 1689 return (table->sp_code); 1690 return (-1); 1691 } 1692 1693 /* 1694 * Set tty hi and low water marks. 1695 * 1696 * Try to arrange the dynamics so there's about one second 1697 * from hi to low water. 1698 * 1699 */ 1700 void 1701 ttsetwater(tp) 1702 struct tty *tp; 1703 { 1704 register int cps, x; 1705 1706 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 1707 1708 cps = tp->t_ospeed / 10; 1709 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 1710 x += cps; 1711 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 1712 tp->t_hiwat = roundup(x, CBSIZE); 1713 #undef CLAMP 1714 } 1715 1716 /* 1717 * Report on state of foreground process group. 1718 */ 1719 void 1720 ttyinfo(tp) 1721 register struct tty *tp; 1722 { 1723 register struct proc *p, *pick; 1724 struct timeval utime, stime; 1725 int tmp; 1726 1727 if (ttycheckoutq(tp,0) == 0) 1728 return; 1729 1730 /* Print load average. */ 1731 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 1732 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 1733 1734 if (tp->t_session == NULL) 1735 ttyprintf(tp, "not a controlling terminal\n"); 1736 else if (tp->t_pgrp == NULL) 1737 ttyprintf(tp, "no foreground process group\n"); 1738 else if ((p = tp->t_pgrp->pg_mem) == NULL) 1739 ttyprintf(tp, "empty foreground process group\n"); 1740 else { 1741 /* Pick interesting process. */ 1742 for (pick = NULL; p != NULL; p = p->p_pgrpnxt) 1743 if (proc_compare(pick, p)) 1744 pick = p; 1745 1746 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 1747 pick->p_stat == SRUN ? "running" : 1748 pick->p_wmesg ? pick->p_wmesg : "iowait"); 1749 1750 calcru(pick, &utime, &stime, NULL); 1751 1752 /* Print user time. */ 1753 ttyprintf(tp, "%d.%02du ", 1754 utime.tv_sec, (utime.tv_usec + 5000) / 10000); 1755 1756 /* Print system time. */ 1757 ttyprintf(tp, "%d.%02ds ", 1758 stime.tv_sec, (stime.tv_usec + 5000) / 10000); 1759 1760 #define pgtok(a) (((a) * NBPG) / 1024) 1761 /* Print percentage cpu, resident set size. */ 1762 tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT; 1763 ttyprintf(tp, "%d%% %dk\n", 1764 tmp / 100, 1765 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 : 1766 pgtok(pick->p_vmspace->vm_rssize)); 1767 } 1768 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 1769 } 1770 1771 /* 1772 * Returns 1 if p2 is "better" than p1 1773 * 1774 * The algorithm for picking the "interesting" process is thus: 1775 * 1776 * 1) Only foreground processes are eligible - implied. 1777 * 2) Runnable processes are favored over anything else. The runner 1778 * with the highest cpu utilization is picked (p_estcpu). Ties are 1779 * broken by picking the highest pid. 1780 * 3) The sleeper with the shortest sleep time is next. With ties, 1781 * we pick out just "short-term" sleepers (P_SINTR == 0). 1782 * 4) Further ties are broken by picking the highest pid. 1783 */ 1784 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 1785 #define TESTAB(a, b) ((a)<<1 | (b)) 1786 #define ONLYA 2 1787 #define ONLYB 1 1788 #define BOTH 3 1789 1790 static int 1791 proc_compare(p1, p2) 1792 register struct proc *p1, *p2; 1793 { 1794 1795 if (p1 == NULL) 1796 return (1); 1797 /* 1798 * see if at least one of them is runnable 1799 */ 1800 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 1801 case ONLYA: 1802 return (0); 1803 case ONLYB: 1804 return (1); 1805 case BOTH: 1806 /* 1807 * tie - favor one with highest recent cpu utilization 1808 */ 1809 if (p2->p_estcpu > p1->p_estcpu) 1810 return (1); 1811 if (p1->p_estcpu > p2->p_estcpu) 1812 return (0); 1813 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1814 } 1815 /* 1816 * weed out zombies 1817 */ 1818 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 1819 case ONLYA: 1820 return (1); 1821 case ONLYB: 1822 return (0); 1823 case BOTH: 1824 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1825 } 1826 /* 1827 * pick the one with the smallest sleep time 1828 */ 1829 if (p2->p_slptime > p1->p_slptime) 1830 return (0); 1831 if (p1->p_slptime > p2->p_slptime) 1832 return (1); 1833 /* 1834 * favor one sleeping in a non-interruptible sleep 1835 */ 1836 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 1837 return (1); 1838 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 1839 return (0); 1840 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1841 } 1842 1843 /* 1844 * Output char to tty; console putchar style. 1845 */ 1846 int 1847 tputchar(c, tp) 1848 int c; 1849 struct tty *tp; 1850 { 1851 register int s; 1852 1853 s = spltty(); 1854 if (ISSET(tp->t_state, 1855 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) { 1856 splx(s); 1857 return (-1); 1858 } 1859 if (c == '\n') 1860 (void)ttyoutput('\r', tp); 1861 (void)ttyoutput(c, tp); 1862 ttstart(tp); 1863 splx(s); 1864 return (0); 1865 } 1866 1867 /* 1868 * Sleep on chan, returning ERESTART if tty changed while we napped and 1869 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 1870 * the tty is revoked, restarting a pending call will redo validation done 1871 * at the start of the call. 1872 */ 1873 int 1874 ttysleep(tp, chan, pri, wmesg, timo) 1875 struct tty *tp; 1876 void *chan; 1877 int pri, timo; 1878 char *wmesg; 1879 { 1880 int error; 1881 short gen; 1882 1883 gen = tp->t_gen; 1884 if (error = tsleep(chan, pri, wmesg, timo)) 1885 return (error); 1886 return (tp->t_gen == gen ? 0 : ERESTART); 1887 } 1888