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