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