1 /* $OpenBSD: tty.c,v 1.40 2000/06/05 11:02:51 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 SET(tp->t_state, TS_ASLEEP); 1559 tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", hz); 1560 } 1561 splx(s); 1562 return (1); 1563 } 1564 1565 /* 1566 * Process a write call on a tty device. 1567 */ 1568 int 1569 ttwrite(tp, uio, flag) 1570 register struct tty *tp; 1571 register struct uio *uio; 1572 int flag; 1573 { 1574 register u_char *cp = NULL; 1575 register int cc, ce; 1576 register struct proc *p; 1577 int i, hiwat, cnt, error, s; 1578 u_char obuf[OBUFSIZ]; 1579 1580 hiwat = tp->t_hiwat; 1581 cnt = uio->uio_resid; 1582 error = 0; 1583 cc = 0; 1584 loop: 1585 s = spltty(); 1586 if (!ISSET(tp->t_state, TS_CARR_ON) && 1587 !ISSET(tp->t_cflag, CLOCAL)) { 1588 if (ISSET(tp->t_state, TS_ISOPEN)) { 1589 splx(s); 1590 return (EIO); 1591 } else if (flag & IO_NDELAY) { 1592 splx(s); 1593 error = EWOULDBLOCK; 1594 goto out; 1595 } else { 1596 /* Sleep awaiting carrier. */ 1597 error = ttysleep(tp, 1598 &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0); 1599 splx(s); 1600 if (error) 1601 goto out; 1602 goto loop; 1603 } 1604 } 1605 splx(s); 1606 /* 1607 * Hang the process if it's in the background. 1608 */ 1609 p = curproc; 1610 if (isbackground(p, tp) && 1611 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 && 1612 (p->p_sigignore & sigmask(SIGTTOU)) == 0 && 1613 (p->p_sigmask & sigmask(SIGTTOU)) == 0) { 1614 if (p->p_pgrp->pg_jobc == 0) { 1615 error = EIO; 1616 goto out; 1617 } 1618 pgsignal(p->p_pgrp, SIGTTOU, 1); 1619 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1620 if (error) 1621 goto out; 1622 goto loop; 1623 } 1624 /* 1625 * Process the user's data in at most OBUFSIZ chunks. Perform any 1626 * output translation. Keep track of high water mark, sleep on 1627 * overflow awaiting device aid in acquiring new space. 1628 */ 1629 while (uio->uio_resid > 0 || cc > 0) { 1630 if (ISSET(tp->t_lflag, FLUSHO)) { 1631 uio->uio_resid = 0; 1632 return (0); 1633 } 1634 if (tp->t_outq.c_cc > hiwat) 1635 goto ovhiwat; 1636 /* 1637 * Grab a hunk of data from the user, unless we have some 1638 * leftover from last time. 1639 */ 1640 if (cc == 0) { 1641 cc = min(uio->uio_resid, OBUFSIZ); 1642 cp = obuf; 1643 error = uiomove(cp, cc, uio); 1644 if (error) { 1645 cc = 0; 1646 break; 1647 } 1648 } 1649 /* 1650 * If nothing fancy need be done, grab those characters we 1651 * can handle without any of ttyoutput's processing and 1652 * just transfer them to the output q. For those chars 1653 * which require special processing (as indicated by the 1654 * bits in char_type), call ttyoutput. After processing 1655 * a hunk of data, look for FLUSHO so ^O's will take effect 1656 * immediately. 1657 */ 1658 while (cc > 0) { 1659 if (!ISSET(tp->t_oflag, OPOST)) 1660 ce = cc; 1661 else { 1662 ce = cc - scanc((u_int)cc, cp, char_type, 1663 CCLASSMASK); 1664 /* 1665 * If ce is zero, then we're processing 1666 * a special character through ttyoutput. 1667 */ 1668 if (ce == 0) { 1669 tp->t_rocount = 0; 1670 if (ttyoutput(*cp, tp) >= 0) { 1671 #ifdef REAL_CLISTS 1672 /* No Clists, wait a bit. */ 1673 ttstart(tp); 1674 if (error = ttysleep(tp, &lbolt, 1675 TTOPRI | PCATCH, ttybuf, 0)) 1676 break; 1677 goto loop; 1678 #else 1679 /* out of space */ 1680 goto overfull; 1681 #endif 1682 } 1683 cp++; 1684 cc--; 1685 if (ISSET(tp->t_lflag, FLUSHO) || 1686 tp->t_outq.c_cc > hiwat) 1687 goto ovhiwat; 1688 continue; 1689 } 1690 } 1691 /* 1692 * A bunch of normal characters have been found. 1693 * Transfer them en masse to the output queue and 1694 * continue processing at the top of the loop. 1695 * If there are any further characters in this 1696 * <= OBUFSIZ chunk, the first should be a character 1697 * requiring special handling by ttyoutput. 1698 */ 1699 tp->t_rocount = 0; 1700 i = b_to_q(cp, ce, &tp->t_outq); 1701 ce -= i; 1702 tp->t_column += ce; 1703 cp += ce, cc -= ce, tk_nout += ce; 1704 tp->t_outcc += ce; 1705 if (i > 0) { 1706 #ifdef REAL_CLISTS 1707 /* No Clists, wait a bit. */ 1708 ttstart(tp); 1709 if (error = ttysleep(tp, 1710 &lbolt, TTOPRI | PCATCH, ttybuf, 0)) 1711 break; 1712 goto loop; 1713 #else 1714 /* out of space */ 1715 goto overfull; 1716 #endif 1717 } 1718 if (ISSET(tp->t_lflag, FLUSHO) || 1719 tp->t_outq.c_cc > hiwat) 1720 break; 1721 } 1722 ttstart(tp); 1723 } 1724 out: 1725 /* 1726 * If cc is nonzero, we leave the uio structure inconsistent, as the 1727 * offset and iov pointers have moved forward, but it doesn't matter 1728 * (the call will either return short or restart with a new uio). 1729 */ 1730 uio->uio_resid += cc; 1731 return (error); 1732 1733 #ifndef REAL_CLISTS 1734 overfull: 1735 /* 1736 * Since we are using ring buffers, if we can't insert any more into 1737 * the output queue, we can assume the ring is full and that someone 1738 * forgot to set the high water mark correctly. We set it and then 1739 * proceed as normal. 1740 */ 1741 hiwat = tp->t_outq.c_cc - 1; 1742 #endif 1743 1744 ovhiwat: 1745 ttstart(tp); 1746 s = spltty(); 1747 /* 1748 * This can only occur if FLUSHO is set in t_lflag, 1749 * or if ttstart/oproc is synchronous (or very fast). 1750 */ 1751 if (tp->t_outq.c_cc <= hiwat) { 1752 splx(s); 1753 goto loop; 1754 } 1755 if (flag & IO_NDELAY) { 1756 splx(s); 1757 uio->uio_resid += cc; 1758 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1759 } 1760 SET(tp->t_state, TS_ASLEEP); 1761 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1762 splx(s); 1763 if (error) 1764 goto out; 1765 goto loop; 1766 } 1767 1768 /* 1769 * Rubout one character from the rawq of tp 1770 * as cleanly as possible. 1771 */ 1772 void 1773 ttyrub(c, tp) 1774 int c; 1775 register struct tty *tp; 1776 { 1777 register u_char *cp; 1778 register int savecol; 1779 int tabc, s; 1780 1781 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1782 return; 1783 CLR(tp->t_lflag, FLUSHO); 1784 if (ISSET(tp->t_lflag, ECHOE)) { 1785 if (tp->t_rocount == 0) { 1786 /* 1787 * Screwed by ttwrite; retype 1788 */ 1789 ttyretype(tp); 1790 return; 1791 } 1792 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1793 ttyrubo(tp, 2); 1794 else { 1795 CLR(c, ~TTY_CHARMASK); 1796 switch (CCLASS(c)) { 1797 case ORDINARY: 1798 ttyrubo(tp, 1); 1799 break; 1800 case BACKSPACE: 1801 case CONTROL: 1802 case NEWLINE: 1803 case RETURN: 1804 case VTAB: 1805 if (ISSET(tp->t_lflag, ECHOCTL)) 1806 ttyrubo(tp, 2); 1807 break; 1808 case TAB: 1809 if (tp->t_rocount < tp->t_rawq.c_cc) { 1810 ttyretype(tp); 1811 return; 1812 } 1813 s = spltty(); 1814 savecol = tp->t_column; 1815 SET(tp->t_state, TS_CNTTB); 1816 SET(tp->t_lflag, FLUSHO); 1817 tp->t_column = tp->t_rocol; 1818 for (cp = firstc(&tp->t_rawq, &tabc); cp; 1819 cp = nextc(&tp->t_rawq, cp, &tabc)) 1820 ttyecho(tabc, tp); 1821 CLR(tp->t_lflag, FLUSHO); 1822 CLR(tp->t_state, TS_CNTTB); 1823 splx(s); 1824 1825 /* savecol will now be length of the tab. */ 1826 savecol -= tp->t_column; 1827 tp->t_column += savecol; 1828 if (savecol > 8) 1829 savecol = 8; /* overflow screw */ 1830 while (--savecol >= 0) 1831 (void)ttyoutput('\b', tp); 1832 break; 1833 default: /* XXX */ 1834 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1835 (void)printf(PANICSTR, c, CCLASS(c)); 1836 #ifdef notdef 1837 panic(PANICSTR, c, CCLASS(c)); 1838 #endif 1839 } 1840 } 1841 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1842 if (!ISSET(tp->t_state, TS_ERASE)) { 1843 SET(tp->t_state, TS_ERASE); 1844 (void)ttyoutput('\\', tp); 1845 } 1846 ttyecho(c, tp); 1847 } else 1848 ttyecho(tp->t_cc[VERASE], tp); 1849 --tp->t_rocount; 1850 } 1851 1852 /* 1853 * Back over cnt characters, erasing them. 1854 */ 1855 static void 1856 ttyrubo(tp, cnt) 1857 register struct tty *tp; 1858 int cnt; 1859 { 1860 1861 while (cnt-- > 0) { 1862 (void)ttyoutput('\b', tp); 1863 (void)ttyoutput(' ', tp); 1864 (void)ttyoutput('\b', tp); 1865 } 1866 } 1867 1868 /* 1869 * ttyretype -- 1870 * Reprint the rawq line. Note, it is assumed that c_cc has already 1871 * been checked. 1872 */ 1873 void 1874 ttyretype(tp) 1875 register struct tty *tp; 1876 { 1877 register u_char *cp; 1878 int s, c; 1879 1880 /* Echo the reprint character. */ 1881 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1882 ttyecho(tp->t_cc[VREPRINT], tp); 1883 1884 (void)ttyoutput('\n', tp); 1885 1886 s = spltty(); 1887 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c)) 1888 ttyecho(c, tp); 1889 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c)) 1890 ttyecho(c, tp); 1891 CLR(tp->t_state, TS_ERASE); 1892 splx(s); 1893 1894 tp->t_rocount = tp->t_rawq.c_cc; 1895 tp->t_rocol = 0; 1896 } 1897 1898 /* 1899 * Echo a typed character to the terminal. 1900 */ 1901 static void 1902 ttyecho(c, tp) 1903 register int c; 1904 register struct tty *tp; 1905 { 1906 1907 if (!ISSET(tp->t_state, TS_CNTTB)) 1908 CLR(tp->t_lflag, FLUSHO); 1909 if ((!ISSET(tp->t_lflag, ECHO) && 1910 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) || 1911 ISSET(tp->t_lflag, EXTPROC)) 1912 return; 1913 if (((ISSET(tp->t_lflag, ECHOCTL) && 1914 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) || 1915 ISSET(c, TTY_CHARMASK) == 0177)) { 1916 (void)ttyoutput('^', tp); 1917 CLR(c, ~TTY_CHARMASK); 1918 if (c == 0177) 1919 c = '?'; 1920 else 1921 c += 'A' - 1; 1922 } 1923 (void)ttyoutput(c, tp); 1924 } 1925 1926 /* 1927 * Wake up any readers on a tty. 1928 */ 1929 void 1930 ttwakeup(tp) 1931 register struct tty *tp; 1932 { 1933 1934 selwakeup(&tp->t_rsel); 1935 if (ISSET(tp->t_state, TS_ASYNC)) 1936 pgsignal(tp->t_pgrp, SIGIO, 1); 1937 wakeup((caddr_t)&tp->t_rawq); 1938 } 1939 1940 /* 1941 * Look up a code for a specified speed in a conversion table; 1942 * used by drivers to map software speed values to hardware parameters. 1943 */ 1944 int 1945 ttspeedtab(speed, table) 1946 int speed; 1947 register struct speedtab *table; 1948 { 1949 1950 for ( ; table->sp_speed != -1; table++) 1951 if (table->sp_speed == speed) 1952 return (table->sp_code); 1953 return (-1); 1954 } 1955 1956 /* 1957 * Set tty hi and low water marks. 1958 * 1959 * Try to arrange the dynamics so there's about one second 1960 * from hi to low water. 1961 */ 1962 void 1963 ttsetwater(tp) 1964 struct tty *tp; 1965 { 1966 register int cps, x; 1967 1968 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 1969 1970 cps = tp->t_ospeed / 10; 1971 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 1972 x += cps; 1973 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 1974 tp->t_hiwat = roundup(x, CBSIZE); 1975 #undef CLAMP 1976 } 1977 1978 /* 1979 * Report on state of foreground process group. 1980 */ 1981 void 1982 ttyinfo(tp) 1983 register struct tty *tp; 1984 { 1985 register struct proc *p, *pick; 1986 struct timeval utime, stime; 1987 int tmp; 1988 1989 if (ttycheckoutq(tp,0) == 0) 1990 return; 1991 1992 /* Print load average. */ 1993 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 1994 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 1995 1996 if (tp->t_session == NULL) 1997 ttyprintf(tp, "not a controlling terminal\n"); 1998 else if (tp->t_pgrp == NULL) 1999 ttyprintf(tp, "no foreground process group\n"); 2000 else if ((p = tp->t_pgrp->pg_members.lh_first) == 0) 2001 ttyprintf(tp, "empty foreground process group\n"); 2002 else { 2003 /* Pick interesting process. */ 2004 for (pick = NULL; p != 0; p = p->p_pglist.le_next) 2005 if (proc_compare(pick, p)) 2006 pick = p; 2007 2008 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 2009 pick->p_stat == SRUN ? "running" : 2010 pick->p_wmesg ? pick->p_wmesg : "iowait"); 2011 2012 calcru(pick, &utime, &stime, NULL); 2013 2014 /* Round up and print user time. */ 2015 utime.tv_usec += 5000; 2016 if (utime.tv_usec >= 1000000) { 2017 utime.tv_sec += 1; 2018 utime.tv_usec -= 1000000; 2019 } 2020 ttyprintf(tp, "%ld.%02ldu ", utime.tv_sec, 2021 utime.tv_usec / 10000); 2022 2023 /* Round up and print system time. */ 2024 stime.tv_usec += 5000; 2025 if (stime.tv_usec >= 1000000) { 2026 stime.tv_sec += 1; 2027 stime.tv_usec -= 1000000; 2028 } 2029 ttyprintf(tp, "%ld.%02lds ", stime.tv_sec, 2030 stime.tv_usec / 10000); 2031 2032 #define pgtok(a) (((u_long) ((a) * PAGE_SIZE) / 1024)) 2033 /* Print percentage cpu, resident set size. */ 2034 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT; 2035 ttyprintf(tp, "%d%% %ldk\n", 2036 tmp / 100, 2037 pick->p_stat == SIDL || P_ZOMBIE(pick) ? 0 : 2038 vm_resident_count(pick->p_vmspace)); 2039 } 2040 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2041 } 2042 2043 /* 2044 * Returns 1 if p2 is "better" than p1 2045 * 2046 * The algorithm for picking the "interesting" process is thus: 2047 * 2048 * 1) Only foreground processes are eligible - implied. 2049 * 2) Runnable processes are favored over anything else. The runner 2050 * with the highest cpu utilization is picked (p_estcpu). Ties are 2051 * broken by picking the highest pid. 2052 * 3) The sleeper with the shortest sleep time is next. With ties, 2053 * we pick out just "short-term" sleepers (P_SINTR == 0). 2054 * 4) Further ties are broken by picking the highest pid. 2055 */ 2056 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 2057 #define TESTAB(a, b) ((a)<<1 | (b)) 2058 #define ONLYA 2 2059 #define ONLYB 1 2060 #define BOTH 3 2061 2062 static int 2063 proc_compare(p1, p2) 2064 register struct proc *p1, *p2; 2065 { 2066 2067 if (p1 == NULL) 2068 return (1); 2069 /* 2070 * see if at least one of them is runnable 2071 */ 2072 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 2073 case ONLYA: 2074 return (0); 2075 case ONLYB: 2076 return (1); 2077 case BOTH: 2078 /* 2079 * tie - favor one with highest recent cpu utilization 2080 */ 2081 if (p2->p_estcpu > p1->p_estcpu) 2082 return (1); 2083 if (p1->p_estcpu > p2->p_estcpu) 2084 return (0); 2085 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2086 } 2087 /* 2088 * weed out zombies 2089 */ 2090 switch (TESTAB(P_ZOMBIE(p1), P_ZOMBIE(p2))) { 2091 case ONLYA: 2092 return (1); 2093 case ONLYB: 2094 return (0); 2095 case BOTH: 2096 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2097 } 2098 /* 2099 * pick the one with the smallest sleep time 2100 */ 2101 if (p2->p_slptime > p1->p_slptime) 2102 return (0); 2103 if (p1->p_slptime > p2->p_slptime) 2104 return (1); 2105 /* 2106 * favor one sleeping in a non-interruptible sleep 2107 */ 2108 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 2109 return (1); 2110 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 2111 return (0); 2112 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2113 } 2114 2115 /* 2116 * Output char to tty; console putchar style. 2117 */ 2118 int 2119 tputchar(c, tp) 2120 int c; 2121 struct tty *tp; 2122 { 2123 register int s; 2124 2125 s = spltty(); 2126 if (ISSET(tp->t_state, 2127 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) { 2128 splx(s); 2129 return (-1); 2130 } 2131 if (c == '\n') 2132 (void)ttyoutput('\r', tp); 2133 (void)ttyoutput(c, tp); 2134 ttstart(tp); 2135 splx(s); 2136 return (0); 2137 } 2138 2139 /* 2140 * Sleep on chan, returning ERESTART if tty changed while we napped and 2141 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 2142 * the tty is revoked, restarting a pending call will redo validation done 2143 * at the start of the call. 2144 */ 2145 int 2146 ttysleep(tp, chan, pri, wmesg, timo) 2147 struct tty *tp; 2148 void *chan; 2149 int pri, timo; 2150 char *wmesg; 2151 { 2152 int error; 2153 short gen; 2154 2155 gen = tp->t_gen; 2156 if ((error = tsleep(chan, pri, wmesg, timo)) != 0) 2157 return (error); 2158 return (tp->t_gen == gen ? 0 : ERESTART); 2159 } 2160 2161 /* 2162 * Initialise the global tty list. 2163 */ 2164 void 2165 tty_init() 2166 { 2167 2168 TAILQ_INIT(&ttylist); 2169 tty_count = 0; 2170 } 2171 2172 /* 2173 * Attach a tty to the tty list. 2174 * 2175 * This should be called ONLY once per real tty (including pty's). 2176 * eg, on the sparc, the keyboard and mouse have struct tty's that are 2177 * distinctly NOT usable as tty's, and thus should not be attached to 2178 * the ttylist. This is why this call is not done from ttymalloc(). 2179 * 2180 * Device drivers should attach tty's at a similar time that they are 2181 * ttymalloc()'ed, or, for the case of statically allocated struct tty's 2182 * either in the attach or (first) open routine. 2183 */ 2184 void 2185 tty_attach(tp) 2186 struct tty *tp; 2187 { 2188 2189 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link); 2190 ++tty_count; 2191 } 2192 2193 /* 2194 * Remove a tty from the tty list. 2195 */ 2196 void 2197 tty_detach(tp) 2198 struct tty *tp; 2199 { 2200 2201 --tty_count; 2202 #ifdef DIAGNOSTIC 2203 if (tty_count < 0) 2204 panic("tty_detach: tty_count < 0"); 2205 #endif 2206 TAILQ_REMOVE(&ttylist, tp, tty_link); 2207 } 2208 2209 /* 2210 * Allocate a tty structure and its associated buffers. 2211 */ 2212 struct tty * 2213 ttymalloc() 2214 { 2215 struct tty *tp; 2216 2217 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK); 2218 bzero(tp, sizeof *tp); 2219 /* XXX: default to 1024 chars for now */ 2220 clalloc(&tp->t_rawq, 1024, 1); 2221 clalloc(&tp->t_canq, 1024, 1); 2222 /* output queue doesn't need quoting */ 2223 clalloc(&tp->t_outq, 1024, 0); 2224 return(tp); 2225 } 2226 2227 /* 2228 * Free a tty structure and its buffers. 2229 * 2230 * Be sure to call tty_detach() for any tty that has been 2231 * tty_attach()ed. 2232 */ 2233 void 2234 ttyfree(tp) 2235 struct tty *tp; 2236 { 2237 2238 clfree(&tp->t_rawq); 2239 clfree(&tp->t_canq); 2240 clfree(&tp->t_outq); 2241 FREE(tp, M_TTYS); 2242 } 2243