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