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