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