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