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