tty.c revision 6712
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.31 1995/02/24 02:36:01 ache 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 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 ttyselect(). 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 */ 253int 254ttyinput(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)) { 300parmrk: (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) || ISSET(tp->t_cflag, CRTS_IFLOW)) 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 } 554endcase: 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); 561restartoutput: 562 CLR(tp->t_lflag, FLUSHO); 563 CLR(tp->t_state, TS_TTSTOP); 564startoutput: 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 */ 574int 575ttyoutput(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 */ 659int 660ttioctl(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 958int 959ttyselect(tp, rw, p) 960 struct tty *tp; 961 int rw; 962 struct proc *p; 963{ 964 int nread, s; 965 966 if (tp == NULL) 967 return (ENXIO); 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) { 980win: 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 */ 994int 995ttnread(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 */ 1014int 1015ttywait(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 */ 1044int 1045ttywflush(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 */ 1058void 1059ttyflush(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 if ((rw & FREAD) && 1087 ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { 1088 if (ISSET(tp->t_iflag, IXOFF) && 1089 tp->t_cc[VSTART] != _POSIX_VDISABLE && 1090 putc(tp->t_cc[VSTART], &tp->t_outq) == 0 || 1091 ISSET(tp->t_cflag, CRTS_IFLOW)) { 1092 CLR(tp->t_state, TS_TBLOCK); 1093 ttstart(tp); 1094 } 1095 } 1096 splx(s); 1097} 1098 1099/* 1100 * Copy in the default termios characters. 1101 */ 1102void 1103ttychars(tp) 1104 struct tty *tp; 1105{ 1106 1107 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 1108} 1109 1110/* 1111 * Send stop character on input overflow. 1112 */ 1113static void 1114ttyblock(tp) 1115 register struct tty *tp; 1116{ 1117 register int total; 1118 1119 total = tp->t_rawq.c_cc + tp->t_canq.c_cc; 1120 /* 1121 * Block further input iff: current input > threshold 1122 * AND input is available to user program. 1123 */ 1124 if (total >= TTYHOG / 2 && 1125 !ISSET(tp->t_state, TS_TBLOCK) && 1126 (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) { 1127 if (ISSET(tp->t_iflag, IXOFF) && 1128 tp->t_cc[VSTOP] != _POSIX_VDISABLE && 1129 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0 || 1130 ISSET(tp->t_cflag, CRTS_IFLOW)) { 1131 SET(tp->t_state, TS_TBLOCK); 1132 ttstart(tp); 1133 } 1134 } 1135} 1136 1137void 1138ttrstrt(tp_arg) 1139 void *tp_arg; 1140{ 1141 struct tty *tp; 1142 int s; 1143 1144#ifdef DIAGNOSTIC 1145 if (tp_arg == NULL) 1146 panic("ttrstrt"); 1147#endif 1148 tp = tp_arg; 1149 s = spltty(); 1150 1151 CLR(tp->t_state, TS_TIMEOUT); 1152 ttstart(tp); 1153 1154 splx(s); 1155} 1156 1157int 1158ttstart(tp) 1159 struct tty *tp; 1160{ 1161 1162 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1163 (*tp->t_oproc)(tp); 1164 return (0); 1165} 1166 1167/* 1168 * "close" a line discipline 1169 */ 1170int 1171ttylclose(tp, flag) 1172 struct tty *tp; 1173 int flag; 1174{ 1175 1176 if ((flag & IO_NDELAY) || ttywflush(tp)) 1177 ttyflush(tp, FREAD | FWRITE); 1178 return (0); 1179} 1180 1181/* 1182 * Handle modem control transition on a tty. 1183 * Flag indicates new state of carrier. 1184 * Returns 0 if the line should be turned off, otherwise 1. 1185 */ 1186int 1187ttymodem(tp, flag) 1188 register struct tty *tp; 1189 int flag; 1190{ 1191 1192 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) { 1193 /* 1194 * MDMBUF: do flow control according to carrier flag 1195 */ 1196 if (flag) { 1197 CLR(tp->t_state, TS_TTSTOP); 1198 ttstart(tp); 1199 } else if (!ISSET(tp->t_state, TS_TTSTOP)) { 1200 SET(tp->t_state, TS_TTSTOP); 1201#ifdef sun4c /* XXX */ 1202 (*tp->t_stop)(tp, 0); 1203#else 1204 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 1205#endif 1206 } 1207 } else if (flag == 0) { 1208 /* 1209 * Lost carrier. 1210 */ 1211 CLR(tp->t_state, TS_CARR_ON); 1212 if (ISSET(tp->t_state, TS_ISOPEN) && 1213 !ISSET(tp->t_cflag, CLOCAL)) { 1214 if (tp->t_session && tp->t_session->s_leader) 1215 psignal(tp->t_session->s_leader, SIGHUP); 1216 ttyflush(tp, FREAD | FWRITE); 1217 return (0); 1218 } 1219 } else { 1220 /* 1221 * Carrier now on. 1222 */ 1223 SET(tp->t_state, TS_CARR_ON); 1224 ttwakeup(tp); 1225 } 1226 return (1); 1227} 1228 1229/* 1230 * Default modem control routine (for other line disciplines). 1231 * Return argument flag, to turn off device on carrier drop. 1232 */ 1233int 1234nullmodem(tp, flag) 1235 register struct tty *tp; 1236 int flag; 1237{ 1238 1239 if (flag) 1240 SET(tp->t_state, TS_CARR_ON); 1241 else { 1242 CLR(tp->t_state, TS_CARR_ON); 1243 if (!ISSET(tp->t_cflag, CLOCAL)) { 1244 if (tp->t_session && tp->t_session->s_leader) 1245 psignal(tp->t_session->s_leader, SIGHUP); 1246 return (0); 1247 } 1248 } 1249 return (1); 1250} 1251 1252/* 1253 * Reinput pending characters after state switch 1254 * call at spltty(). 1255 */ 1256void 1257ttypend(tp) 1258 register struct tty *tp; 1259{ 1260 struct clist tq; 1261 register c; 1262 1263 CLR(tp->t_lflag, PENDIN); 1264 SET(tp->t_state, TS_TYPEN); 1265 /* 1266 * XXX this assumes too much about clist internals. It may even 1267 * fail if the cblock slush pool is empty. We can't allocate more 1268 * cblocks here because we are called from an interrupt handler 1269 * and clist_alloc_cblocks() can wait. 1270 */ 1271 tq = tp->t_rawq; 1272 bzero(&tp->t_rawq, sizeof tp->t_rawq); 1273 tp->t_rawq.c_cbmax = tq.c_cbmax; 1274 tp->t_rawq.c_cbreserved = tq.c_cbreserved; 1275 while ((c = getc(&tq)) >= 0) 1276 ttyinput(c, tp); 1277 CLR(tp->t_state, TS_TYPEN); 1278} 1279 1280/* 1281 * Process a read call on a tty device. 1282 */ 1283int 1284ttread(tp, uio, flag) 1285 register struct tty *tp; 1286 struct uio *uio; 1287 int flag; 1288{ 1289 register struct clist *qp; 1290 register int c; 1291 register tcflag_t lflag; 1292 register cc_t *cc = tp->t_cc; 1293 register struct proc *p = curproc; 1294 int s, first, error = 0, carrier; 1295 int has_stime = 0, last_cc = 0; 1296 long slp = 0; /* XXX this should be renamed `timo'. */ 1297 1298loop: 1299 s = spltty(); 1300 lflag = tp->t_lflag; 1301 /* 1302 * take pending input first 1303 */ 1304 if (ISSET(lflag, PENDIN)) { 1305 ttypend(tp); 1306 splx(s); /* reduce latency */ 1307 s = spltty(); 1308 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1309 } 1310 1311 /* 1312 * Hang process if it's in the background. 1313 */ 1314 if (isbackground(p, tp)) { 1315 splx(s); 1316 if ((p->p_sigignore & sigmask(SIGTTIN)) || 1317 (p->p_sigmask & sigmask(SIGTTIN)) || 1318 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) 1319 return (EIO); 1320 pgsignal(p->p_pgrp, SIGTTIN, 1); 1321 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1322 if (error) 1323 return (error); 1324 goto loop; 1325 } 1326 1327 /* 1328 * If canonical, use the canonical queue, 1329 * else use the raw queue. 1330 * 1331 * (should get rid of clists...) 1332 */ 1333 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq; 1334 1335 if (flag & IO_NDELAY) { 1336 if (qp->c_cc > 0) 1337 goto read; 1338 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1339 ISSET(tp->t_cflag, CLOCAL); 1340 if ((!carrier && ISSET(tp->t_state, TS_ISOPEN)) || 1341 !ISSET(lflag, ICANON) && cc[VMIN] == 0) { 1342 splx(s); 1343 return (0); 1344 } 1345 splx(s); 1346 return (EWOULDBLOCK); 1347 } 1348 if (!ISSET(lflag, ICANON)) { 1349 int m = cc[VMIN]; 1350 long t = cc[VTIME]; 1351 struct timeval stime, timecopy; 1352 int x; 1353 1354 /* 1355 * Check each of the four combinations. 1356 * (m > 0 && t == 0) is the normal read case. 1357 * It should be fairly efficient, so we check that and its 1358 * companion case (m == 0 && t == 0) first. 1359 * For the other two cases, we compute the target sleep time 1360 * into slp. 1361 */ 1362 if (t == 0) { 1363 if (qp->c_cc < m) 1364 goto sleep; 1365 if (qp->c_cc > 0) 1366 goto read; 1367 1368 /* m, t and qp->c_cc are all 0. 0 is enough input. */ 1369 splx(s); 1370 return (0); 1371 } 1372 t *= 100000; /* time in us */ 1373#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \ 1374 ((t1).tv_usec - (t2).tv_usec)) 1375 if (m > 0) { 1376 if (qp->c_cc <= 0) 1377 goto sleep; 1378 if (qp->c_cc >= m) 1379 goto read; 1380 x = splclock(); 1381 timecopy = time; 1382 splx(x); 1383 if (!has_stime) { 1384 /* first character, start timer */ 1385 has_stime = 1; 1386 stime = timecopy; 1387 slp = t; 1388 } else if (qp->c_cc > last_cc) { 1389 /* got a character, restart timer */ 1390 stime = timecopy; 1391 slp = t; 1392 } else { 1393 /* nothing, check expiration */ 1394 slp = t - diff(timecopy, stime); 1395 if (slp <= 0) 1396 goto read; 1397 } 1398 last_cc = qp->c_cc; 1399 } else { /* m == 0 */ 1400 if (qp->c_cc > 0) 1401 goto read; 1402 x = splclock(); 1403 timecopy = time; 1404 splx(x); 1405 if (!has_stime) { 1406 has_stime = 1; 1407 stime = timecopy; 1408 slp = t; 1409 } else { 1410 slp = t - diff(timecopy, stime); 1411 if (slp <= 0) { 1412 /* Timed out, but 0 is enough input. */ 1413 splx(s); 1414 return (0); 1415 } 1416 } 1417 } 1418#undef diff 1419 /* 1420 * Rounding down may make us wake up just short 1421 * of the target, so we round up. 1422 * The formula is ceiling(slp * hz/1000000). 1423 * 32-bit arithmetic is enough for hz < 169. 1424 * XXX see hzto() for how to avoid overflow if hz 1425 * is large (divide by `tick' and/or arrange to 1426 * use hzto() if hz is large). 1427 */ 1428 slp = (long) (((u_long)slp * hz) + 999999) / 1000000; 1429 goto sleep; 1430 } 1431 1432 /* 1433 * If there is no input, sleep on rawq 1434 * awaiting hardware receipt and notification. 1435 * If we have data, we don't need to check for carrier. 1436 */ 1437 if (qp->c_cc <= 0) { 1438sleep: 1439 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1440 ISSET(tp->t_cflag, CLOCAL); 1441 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) { 1442 splx(s); 1443 return (0); /* EOF */ 1444 } 1445 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 1446 carrier ? ttyin : ttopen, (int)slp); 1447 splx(s); 1448 if (error == EWOULDBLOCK) 1449 error = 0; 1450 else if (error) 1451 return (error); 1452 /* 1453 * XXX what happens if another process eats some input 1454 * while we are asleep (not just here)? It would be 1455 * safest to detect changes and reset our state variables 1456 * (has_stime and last_cc). 1457 */ 1458 slp = 0; 1459 goto loop; 1460 } 1461read: 1462 splx(s); 1463 /* 1464 * Input present, check for input mapping and processing. 1465 */ 1466 first = 1; 1467 while ((c = getc(qp)) >= 0) { 1468 /* 1469 * delayed suspend (^Y) 1470 */ 1471 if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) { 1472 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1473 if (first) { 1474 error = ttysleep(tp, 1475 &lbolt, TTIPRI | PCATCH, ttybg, 0); 1476 if (error) 1477 break; 1478 goto loop; 1479 } 1480 break; 1481 } 1482 /* 1483 * Interpret EOF only in canonical mode. 1484 */ 1485 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1486 break; 1487 /* 1488 * Give user character. 1489 */ 1490 error = ureadc(c, uio); 1491 if (error) 1492 break; 1493 if (uio->uio_resid == 0) 1494 break; 1495 /* 1496 * In canonical mode check for a "break character" 1497 * marking the end of a "line of input". 1498 */ 1499 if (ISSET(lflag, ICANON) && TTBREAKC(c)) 1500 break; 1501 first = 0; 1502 } 1503 /* 1504 * Look to unblock output now that (presumably) 1505 * the input queue has gone down. 1506 */ 1507 s = spltty(); 1508 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { 1509 if (ISSET(tp->t_iflag, IXOFF) && 1510 cc[VSTART] != _POSIX_VDISABLE && 1511 putc(cc[VSTART], &tp->t_outq) == 0 || 1512 ISSET(tp->t_cflag, CRTS_IFLOW)) { 1513 CLR(tp->t_state, TS_TBLOCK); 1514 ttstart(tp); 1515 } 1516 } 1517 splx(s); 1518 return (error); 1519} 1520 1521/* 1522 * Check the output queue on tp for space for a kernel message (from uprintf 1523 * or tprintf). Allow some space over the normal hiwater mark so we don't 1524 * lose messages due to normal flow control, but don't let the tty run amok. 1525 * Sleeps here are not interruptible, but we return prematurely if new signals 1526 * arrive. 1527 */ 1528int 1529ttycheckoutq(tp, wait) 1530 register struct tty *tp; 1531 int wait; 1532{ 1533 int hiwat, s, oldsig; 1534 1535 hiwat = tp->t_hiwat; 1536 s = spltty(); 1537 oldsig = wait ? curproc->p_siglist : 0; 1538 if (tp->t_outq.c_cc > hiwat + 200) 1539 while (tp->t_outq.c_cc > hiwat) { 1540 ttstart(tp); 1541 if (wait == 0 || curproc->p_siglist != oldsig) { 1542 splx(s); 1543 return (0); 1544 } 1545 timeout((void (*)__P((void *)))wakeup, 1546 (void *)&tp->t_outq, hz); 1547 SET(tp->t_state, TS_ASLEEP); 1548 (void) tsleep((caddr_t)&tp->t_outq, PZERO - 1, "ttoutq", 0); 1549 } 1550 splx(s); 1551 return (1); 1552} 1553 1554/* 1555 * Process a write call on a tty device. 1556 */ 1557int 1558ttwrite(tp, uio, flag) 1559 register struct tty *tp; 1560 register struct uio *uio; 1561 int flag; 1562{ 1563 register char *cp = 0; 1564 register int cc, ce; 1565 register struct proc *p; 1566 int i, hiwat, cnt, error, s; 1567 char obuf[OBUFSIZ]; 1568 1569 hiwat = tp->t_hiwat; 1570 cnt = uio->uio_resid; 1571 error = 0; 1572 cc = 0; 1573loop: 1574 s = spltty(); 1575 if (!ISSET(tp->t_state, TS_CARR_ON) && 1576 !ISSET(tp->t_cflag, CLOCAL)) { 1577 if (ISSET(tp->t_state, TS_ISOPEN)) { 1578 splx(s); 1579 return (EIO); 1580 } else if (flag & IO_NDELAY) { 1581 splx(s); 1582 error = EWOULDBLOCK; 1583 goto out; 1584 } else { 1585 /* Sleep awaiting carrier. */ 1586 error = ttysleep(tp, 1587 &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0); 1588 splx(s); 1589 if (error) 1590 goto out; 1591 goto loop; 1592 } 1593 } 1594 splx(s); 1595 /* 1596 * Hang the process if it's in the background. 1597 */ 1598 p = curproc; 1599 if (isbackground(p, tp) && 1600 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 && 1601 (p->p_sigignore & sigmask(SIGTTOU)) == 0 && 1602 (p->p_sigmask & sigmask(SIGTTOU)) == 0 && 1603 p->p_pgrp->pg_jobc) { 1604 pgsignal(p->p_pgrp, SIGTTOU, 1); 1605 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1606 if (error) 1607 goto out; 1608 goto loop; 1609 } 1610 /* 1611 * Process the user's data in at most OBUFSIZ chunks. Perform any 1612 * output translation. Keep track of high water mark, sleep on 1613 * overflow awaiting device aid in acquiring new space. 1614 */ 1615 while (uio->uio_resid > 0 || cc > 0) { 1616 if (ISSET(tp->t_lflag, FLUSHO)) { 1617 uio->uio_resid = 0; 1618 return (0); 1619 } 1620 if (tp->t_outq.c_cc > hiwat) 1621 goto ovhiwat; 1622 /* 1623 * Grab a hunk of data from the user, unless we have some 1624 * leftover from last time. 1625 */ 1626 if (cc == 0) { 1627 cc = min(uio->uio_resid, OBUFSIZ); 1628 cp = obuf; 1629 error = uiomove(cp, cc, uio); 1630 if (error) { 1631 cc = 0; 1632 break; 1633 } 1634#if NSNP > 0 1635 if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL) 1636 snpin((struct snoop *)tp->t_sc, cp, cc); 1637#endif 1638 } 1639 /* 1640 * If nothing fancy need be done, grab those characters we 1641 * can handle without any of ttyoutput's processing and 1642 * just transfer them to the output q. For those chars 1643 * which require special processing (as indicated by the 1644 * bits in char_type), call ttyoutput. After processing 1645 * a hunk of data, look for FLUSHO so ^O's will take effect 1646 * immediately. 1647 */ 1648 while (cc > 0) { 1649 if (!ISSET(tp->t_oflag, OPOST)) 1650 ce = cc; 1651 else { 1652 ce = cc - scanc((u_int)cc, (u_char *)cp, 1653 (u_char *)char_type, CCLASSMASK); 1654 /* 1655 * If ce is zero, then we're processing 1656 * a special character through ttyoutput. 1657 */ 1658 if (ce == 0) { 1659 tp->t_rocount = 0; 1660 if (ttyoutput(*cp, tp) >= 0) { 1661 /* No Clists, wait a bit. */ 1662 ttstart(tp); 1663 if (flag & IO_NDELAY) { 1664 error = EWOULDBLOCK; 1665 goto out; 1666 } 1667 error = ttysleep(tp, &lbolt, 1668 TTOPRI | PCATCH, ttybuf, 0); 1669 if (error) 1670 goto out; 1671 goto loop; 1672 } 1673 cp++; 1674 cc--; 1675 if (ISSET(tp->t_lflag, FLUSHO) || 1676 tp->t_outq.c_cc > hiwat) 1677 goto ovhiwat; 1678 continue; 1679 } 1680 } 1681 /* 1682 * A bunch of normal characters have been found. 1683 * Transfer them en masse to the output queue and 1684 * continue processing at the top of the loop. 1685 * If there are any further characters in this 1686 * <= OBUFSIZ chunk, the first should be a character 1687 * requiring special handling by ttyoutput. 1688 */ 1689 tp->t_rocount = 0; 1690 i = b_to_q(cp, ce, &tp->t_outq); 1691 ce -= i; 1692 tp->t_column += ce; 1693 cp += ce, cc -= ce, tk_nout += ce; 1694 tp->t_outcc += ce; 1695 if (i > 0) { 1696 /* No Clists, wait a bit. */ 1697 ttstart(tp); 1698 if (flag & IO_NDELAY) { 1699 error = EWOULDBLOCK; 1700 goto out; 1701 } 1702 error = ttysleep(tp, 1703 &lbolt, TTOPRI | PCATCH, ttybuf, 0); 1704 if (error) 1705 goto out; 1706 goto loop; 1707 } 1708 if (ISSET(tp->t_lflag, FLUSHO) || 1709 tp->t_outq.c_cc > hiwat) 1710 break; 1711 } 1712 ttstart(tp); 1713 } 1714out: 1715 /* 1716 * If cc is nonzero, we leave the uio structure inconsistent, as the 1717 * offset and iov pointers have moved forward, but it doesn't matter 1718 * (the call will either return short or restart with a new uio). 1719 */ 1720 uio->uio_resid += cc; 1721 return (error); 1722 1723ovhiwat: 1724 ttstart(tp); 1725 s = spltty(); 1726 /* 1727 * This can only occur if FLUSHO is set in t_lflag, 1728 * or if ttstart/oproc is synchronous (or very fast). 1729 */ 1730 if (tp->t_outq.c_cc <= hiwat) { 1731 splx(s); 1732 goto loop; 1733 } 1734 if (flag & IO_NDELAY) { 1735 splx(s); 1736 uio->uio_resid += cc; 1737 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1738 } 1739 SET(tp->t_state, TS_ASLEEP); 1740 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1741 splx(s); 1742 if (error) 1743 goto out; 1744 goto loop; 1745} 1746 1747/* 1748 * Rubout one character from the rawq of tp 1749 * as cleanly as possible. 1750 */ 1751void 1752ttyrub(c, tp) 1753 register int c; 1754 register struct tty *tp; 1755{ 1756 register char *cp; 1757 register int savecol; 1758 int tabc, s; 1759 1760 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1761 return; 1762 CLR(tp->t_lflag, FLUSHO); 1763 if (ISSET(tp->t_lflag, ECHOE)) { 1764 if (tp->t_rocount == 0) { 1765 /* 1766 * Screwed by ttwrite; retype 1767 */ 1768 ttyretype(tp); 1769 return; 1770 } 1771 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1772 ttyrubo(tp, 2); 1773 else { 1774 CLR(c, ~TTY_CHARMASK); 1775 switch (CCLASS(c)) { 1776 case ORDINARY: 1777 ttyrubo(tp, 1); 1778 break; 1779 case BACKSPACE: 1780 case CONTROL: 1781 case NEWLINE: 1782 case RETURN: 1783 case VTAB: 1784 if (ISSET(tp->t_lflag, ECHOCTL)) 1785 ttyrubo(tp, 2); 1786 break; 1787 case TAB: 1788 if (tp->t_rocount < tp->t_rawq.c_cc) { 1789 ttyretype(tp); 1790 return; 1791 } 1792 s = spltty(); 1793 savecol = tp->t_column; 1794 SET(tp->t_state, TS_CNTTB); 1795 SET(tp->t_lflag, FLUSHO); 1796 tp->t_column = tp->t_rocol; 1797 cp = tp->t_rawq.c_cf; 1798 if (cp) 1799 tabc = *cp; /* XXX FIX NEXTC */ 1800 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 1801 ttyecho(tabc, tp); 1802 CLR(tp->t_lflag, FLUSHO); 1803 CLR(tp->t_state, TS_CNTTB); 1804 splx(s); 1805 1806 /* savecol will now be length of the tab. */ 1807 savecol -= tp->t_column; 1808 tp->t_column += savecol; 1809 if (savecol > 8) 1810 savecol = 8; /* overflow screw */ 1811 while (--savecol >= 0) 1812 (void)ttyoutput('\b', tp); 1813 break; 1814 default: /* XXX */ 1815#define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1816 (void)printf(PANICSTR, c, CCLASS(c)); 1817#ifdef notdef 1818 panic(PANICSTR, c, CCLASS(c)); 1819#endif 1820 } 1821 } 1822 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1823 if (!ISSET(tp->t_state, TS_ERASE)) { 1824 SET(tp->t_state, TS_ERASE); 1825 (void)ttyoutput('\\', tp); 1826 } 1827 ttyecho(c, tp); 1828 } else 1829 ttyecho(tp->t_cc[VERASE], tp); 1830 --tp->t_rocount; 1831} 1832 1833/* 1834 * Back over cnt characters, erasing them. 1835 */ 1836static void 1837ttyrubo(tp, cnt) 1838 register struct tty *tp; 1839 int cnt; 1840{ 1841 1842 while (cnt-- > 0) { 1843 (void)ttyoutput('\b', tp); 1844 (void)ttyoutput(' ', tp); 1845 (void)ttyoutput('\b', tp); 1846 } 1847} 1848 1849/* 1850 * ttyretype -- 1851 * Reprint the rawq line. Note, it is assumed that c_cc has already 1852 * been checked. 1853 */ 1854void 1855ttyretype(tp) 1856 register struct tty *tp; 1857{ 1858 register char *cp; 1859 int s, c; 1860 1861 /* Echo the reprint character. */ 1862 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1863 ttyecho(tp->t_cc[VREPRINT], tp); 1864 1865 (void)ttyoutput('\n', tp); 1866 1867 /* 1868 * XXX 1869 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1870 * BIT OF FIRST CHAR. 1871 */ 1872 s = spltty(); 1873 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 1874 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 1875 ttyecho(c, tp); 1876 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 1877 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 1878 ttyecho(c, tp); 1879 CLR(tp->t_state, TS_ERASE); 1880 splx(s); 1881 1882 tp->t_rocount = tp->t_rawq.c_cc; 1883 tp->t_rocol = 0; 1884} 1885 1886/* 1887 * Echo a typed character to the terminal. 1888 */ 1889static void 1890ttyecho(c, tp) 1891 register int c; 1892 register struct tty *tp; 1893{ 1894 1895 if (!ISSET(tp->t_state, TS_CNTTB)) 1896 CLR(tp->t_lflag, FLUSHO); 1897 if ((!ISSET(tp->t_lflag, ECHO) && 1898 (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) || 1899 ISSET(tp->t_lflag, EXTPROC)) 1900 return; 1901 if (ISSET(tp->t_lflag, ECHOCTL) && 1902 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') || 1903 ISSET(c, TTY_CHARMASK) == 0177)) { 1904 (void)ttyoutput('^', tp); 1905 CLR(c, ~TTY_CHARMASK); 1906 if (c == 0177) 1907 c = '?'; 1908 else 1909 c += 'A' - 1; 1910 } 1911 (void)ttyoutput(c, tp); 1912} 1913 1914/* 1915 * Wake up any readers on a tty. 1916 */ 1917void 1918ttwakeup(tp) 1919 register struct tty *tp; 1920{ 1921 1922 selwakeup(&tp->t_rsel); 1923 if (ISSET(tp->t_state, TS_ASYNC)) 1924 pgsignal(tp->t_pgrp, SIGIO, 1); 1925 wakeup((caddr_t)&tp->t_rawq); 1926} 1927 1928/* 1929 * Look up a code for a specified speed in a conversion table; 1930 * used by drivers to map software speed values to hardware parameters. 1931 */ 1932int 1933ttspeedtab(speed, table) 1934 int speed; 1935 register struct speedtab *table; 1936{ 1937 1938 for ( ; table->sp_speed != -1; table++) 1939 if (table->sp_speed == speed) 1940 return (table->sp_code); 1941 return (-1); 1942} 1943 1944/* 1945 * Set tty hi and low water marks. 1946 * 1947 * Try to arrange the dynamics so there's about one second 1948 * from hi to low water. 1949 * 1950 */ 1951void 1952ttsetwater(tp) 1953 struct tty *tp; 1954{ 1955 register int cps, x; 1956 1957#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 1958 1959 cps = tp->t_ospeed / 10; 1960 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 1961 x += cps; 1962 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 1963 tp->t_hiwat = roundup(x, CBSIZE); 1964#undef CLAMP 1965} 1966 1967/* 1968 * Report on state of foreground process group. 1969 */ 1970void 1971ttyinfo(tp) 1972 register struct tty *tp; 1973{ 1974 register struct proc *p, *pick; 1975 struct timeval utime, stime; 1976 int tmp; 1977 1978 if (ttycheckoutq(tp,0) == 0) 1979 return; 1980 1981 /* Print load average. */ 1982 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 1983 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 1984 1985 if (tp->t_session == NULL) 1986 ttyprintf(tp, "not a controlling terminal\n"); 1987 else if (tp->t_pgrp == NULL) 1988 ttyprintf(tp, "no foreground process group\n"); 1989 else if ((p = tp->t_pgrp->pg_mem) == NULL) 1990 ttyprintf(tp, "empty foreground process group\n"); 1991 else { 1992 /* Pick interesting process. */ 1993 for (pick = NULL; p != NULL; p = p->p_pgrpnxt) 1994 if (proc_compare(pick, p)) 1995 pick = p; 1996 1997 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 1998 pick->p_stat == SRUN ? "running" : 1999 pick->p_wmesg ? pick->p_wmesg : "iowait"); 2000 2001 calcru(pick, &utime, &stime, NULL); 2002 2003 /* Print user time. */ 2004 ttyprintf(tp, "%d.%02du ", 2005 utime.tv_sec, utime.tv_usec / 10000); 2006 2007 /* Print system time. */ 2008 ttyprintf(tp, "%d.%02ds ", 2009 stime.tv_sec, stime.tv_usec / 10000); 2010 2011#define pgtok(a) (((a) * NBPG) / 1024) 2012 /* Print percentage cpu, resident set size. */ 2013 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT; 2014 ttyprintf(tp, "%d%% %dk\n", 2015 tmp / 100, 2016 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 : 2017#ifdef pmap_resident_count 2018 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap)) 2019#else 2020 pgtok(pick->p_vmspace->vm_rssize) 2021#endif 2022 ); 2023 } 2024 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2025} 2026 2027/* 2028 * Returns 1 if p2 is "better" than p1 2029 * 2030 * The algorithm for picking the "interesting" process is thus: 2031 * 2032 * 1) Only foreground processes are eligible - implied. 2033 * 2) Runnable processes are favored over anything else. The runner 2034 * with the highest cpu utilization is picked (p_estcpu). Ties are 2035 * broken by picking the highest pid. 2036 * 3) The sleeper with the shortest sleep time is next. With ties, 2037 * we pick out just "short-term" sleepers (P_SINTR == 0). 2038 * 4) Further ties are broken by picking the highest pid. 2039 */ 2040#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 2041#define TESTAB(a, b) ((a)<<1 | (b)) 2042#define ONLYA 2 2043#define ONLYB 1 2044#define BOTH 3 2045 2046static int 2047proc_compare(p1, p2) 2048 register struct proc *p1, *p2; 2049{ 2050 2051 if (p1 == NULL) 2052 return (1); 2053 /* 2054 * see if at least one of them is runnable 2055 */ 2056 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 2057 case ONLYA: 2058 return (0); 2059 case ONLYB: 2060 return (1); 2061 case BOTH: 2062 /* 2063 * tie - favor one with highest recent cpu utilization 2064 */ 2065 if (p2->p_estcpu > p1->p_estcpu) 2066 return (1); 2067 if (p1->p_estcpu > p2->p_estcpu) 2068 return (0); 2069 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2070 } 2071 /* 2072 * weed out zombies 2073 */ 2074 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 2075 case ONLYA: 2076 return (1); 2077 case ONLYB: 2078 return (0); 2079 case BOTH: 2080 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2081 } 2082 /* 2083 * pick the one with the smallest sleep time 2084 */ 2085 if (p2->p_slptime > p1->p_slptime) 2086 return (0); 2087 if (p1->p_slptime > p2->p_slptime) 2088 return (1); 2089 /* 2090 * favor one sleeping in a non-interruptible sleep 2091 */ 2092 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 2093 return (1); 2094 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 2095 return (0); 2096 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2097} 2098 2099/* 2100 * Output char to tty; console putchar style. 2101 */ 2102int 2103tputchar(c, tp) 2104 int c; 2105 struct tty *tp; 2106{ 2107 register int s; 2108 2109 s = spltty(); 2110 if (ISSET(tp->t_state, 2111 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) { 2112 splx(s); 2113 return (-1); 2114 } 2115 if (c == '\n') 2116 (void)ttyoutput('\r', tp); 2117 (void)ttyoutput(c, tp); 2118 ttstart(tp); 2119 splx(s); 2120 return (0); 2121} 2122 2123/* 2124 * Sleep on chan, returning ERESTART if tty changed while we napped and 2125 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 2126 * the tty is revoked, restarting a pending call will redo validation done 2127 * at the start of the call. 2128 */ 2129int 2130ttysleep(tp, chan, pri, wmesg, timo) 2131 struct tty *tp; 2132 void *chan; 2133 int pri, timo; 2134 char *wmesg; 2135{ 2136 int error; 2137 short gen; 2138 2139 gen = tp->t_gen; 2140 error = tsleep(chan, pri, wmesg, timo); 2141 if (error) 2142 return (error); 2143 return (tp->t_gen == gen ? 0 : ERESTART); 2144} 2145 2146/* 2147 * XXX this is usable not useful or used. Most tty drivers have 2148 * ifdefs for using ttymalloc() but assume a different interface. 2149 */ 2150/* 2151 * Allocate a tty struct. Clists in the struct will be allocated by 2152 * ttyopen(). 2153 */ 2154struct tty * 2155ttymalloc() 2156{ 2157 struct tty *tp; 2158 2159 tp = malloc(sizeof *tp, M_TTYS, M_WAITOK); 2160 bzero(tp, sizeof *tp); 2161 return (tp); 2162} 2163 2164#if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */ 2165/* 2166 * Free a tty struct. Clists in the struct should have been freed by 2167 * ttyclose(). 2168 */ 2169void 2170ttyfree(tp) 2171 struct tty *tp; 2172{ 2173 free(tp, M_TTYS); 2174} 2175#endif /* 0 */ 2176