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