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