1 /* $OpenBSD: tty.c,v 1.113 2014/07/13 15:29:04 tedu Exp $ */ 2 /* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1982, 1986, 1990, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * (c) UNIX System Laboratories, Inc. 8 * All or some portions of this file are derived from material licensed 9 * to the University of California by American Telephone and Telegraph 10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 11 * the permission of UNIX System Laboratories, Inc. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)tty.c 8.8 (Berkeley) 1/21/94 38 */ 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/ioctl.h> 43 #include <sys/proc.h> 44 #define TTYDEFCHARS 45 #include <sys/tty.h> 46 #undef TTYDEFCHARS 47 #include <sys/file.h> 48 #include <sys/conf.h> 49 #include <sys/dkstat.h> 50 #include <sys/uio.h> 51 #include <sys/kernel.h> 52 #include <sys/vnode.h> 53 #include <sys/syslog.h> 54 #include <sys/malloc.h> 55 #include <sys/signalvar.h> 56 #include <sys/resourcevar.h> 57 #include <sys/sysctl.h> 58 #include <sys/pool.h> 59 #include <sys/poll.h> 60 61 #include <sys/namei.h> 62 63 #include <dev/rndvar.h> 64 65 #include "pty.h" 66 67 static int ttnread(struct tty *); 68 static void ttyblock(struct tty *); 69 void ttyunblock(struct tty *); 70 static void ttyecho(int, struct tty *); 71 static void ttyrubo(struct tty *, int); 72 void ttkqflush(struct klist *klist); 73 int filt_ttyread(struct knote *kn, long hint); 74 void filt_ttyrdetach(struct knote *kn); 75 int filt_ttywrite(struct knote *kn, long hint); 76 void filt_ttywdetach(struct knote *kn); 77 void ttystats_init(struct itty **); 78 79 /* Symbolic sleep message strings. */ 80 char ttclos[] = "ttycls"; 81 char ttopen[] = "ttyopn"; 82 char ttybg[] = "ttybg"; 83 char ttyin[] = "ttyin"; 84 char ttyout[] = "ttyout"; 85 86 /* 87 * Table with character classes and parity. The 8th bit indicates parity, 88 * the 7th bit indicates the character is an alphameric or underscore (for 89 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits 90 * are 0 then the character needs no special processing on output; classes 91 * other than 0 might be translated or (not currently) require delays. 92 */ 93 #define E 0x00 /* Even parity. */ 94 #define O 0x80 /* Odd parity. */ 95 #define PARITY(c) (char_type[c] & O) 96 97 #define ALPHA 0x40 /* Alpha or underscore. */ 98 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA) 99 100 #define CCLASSMASK 0x3f 101 #define CCLASS(c) (char_type[c] & CCLASSMASK) 102 103 #define BS BACKSPACE 104 #define CC CONTROL 105 #define CR RETURN 106 #define NA ORDINARY | ALPHA 107 #define NL NEWLINE 108 #define NO ORDINARY 109 #define TB TAB 110 #define VT VTAB 111 112 u_char const char_type[] = { 113 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */ 114 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */ 115 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */ 116 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */ 117 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */ 118 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */ 119 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */ 120 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */ 121 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */ 122 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */ 123 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */ 124 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */ 125 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */ 126 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */ 127 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */ 128 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */ 129 /* 130 * Meta chars; should be settable per character set; 131 * for now, treat them all as normal characters. 132 */ 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 NA, NA, NA, NA, NA, NA, NA, NA, 146 NA, NA, NA, NA, NA, NA, NA, NA, 147 NA, NA, NA, NA, NA, NA, NA, NA, 148 NA, NA, NA, NA, NA, NA, NA, NA, 149 }; 150 #undef BS 151 #undef CC 152 #undef CR 153 #undef NA 154 #undef NL 155 #undef NO 156 #undef TB 157 #undef VT 158 159 #define islower(c) ((c) >= 'a' && (c) <= 'z') 160 #define isupper(c) ((c) >= 'A' && (c) <= 'Z') 161 162 #define tolower(c) ((c) - 'A' + 'a') 163 #define toupper(c) ((c) - 'a' + 'A') 164 165 struct ttylist_head ttylist; /* TAILQ_HEAD */ 166 int tty_count; 167 168 int64_t tk_cancc, tk_nin, tk_nout, tk_rawcc; 169 170 /* 171 * Initial open of tty, or (re)entry to standard tty line discipline. 172 */ 173 int 174 ttyopen(dev_t device, struct tty *tp, struct proc *p) 175 { 176 int s; 177 178 s = spltty(); 179 tp->t_dev = device; 180 if (!ISSET(tp->t_state, TS_ISOPEN)) { 181 SET(tp->t_state, TS_ISOPEN); 182 memset(&tp->t_winsize, 0, sizeof(tp->t_winsize)); 183 tp->t_column = 0; 184 } 185 CLR(tp->t_state, TS_WOPEN); 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 */ 195 int 196 ttyclose(struct tty *tp) 197 { 198 extern struct tty *constty; /* Temporary virtual console. */ 199 200 if (constty == tp) 201 constty = NULL; 202 203 ttyflush(tp, FREAD | FWRITE); 204 205 tp->t_gen++; 206 tp->t_pgrp = NULL; 207 if (tp->t_session) 208 SESSRELE(tp->t_session); 209 tp->t_session = NULL; 210 tp->t_state = 0; 211 return (0); 212 } 213 214 #define FLUSHQ(q) { \ 215 if ((q)->c_cc) \ 216 ndflush(q, (q)->c_cc); \ 217 } 218 219 /* Is 'c' a line delimiter ("break" character)? */ 220 #define TTBREAKC(c, lflag) \ 221 ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] || \ 222 ((c) == cc[VEOL2] && (lflag & IEXTEN))) && (c) != _POSIX_VDISABLE)) 223 224 225 /* 226 * Process input of a single character received on a tty. 227 */ 228 int 229 ttyinput(int c, struct tty *tp) 230 { 231 int iflag, lflag; 232 u_char *cc; 233 int i, error; 234 int s; 235 236 add_tty_randomness(tp->t_dev << 8 | c); 237 /* 238 * If receiver is not enabled, drop it. 239 */ 240 if (!ISSET(tp->t_cflag, CREAD)) 241 return (0); 242 243 /* 244 * If input is pending take it first. 245 */ 246 lflag = tp->t_lflag; 247 s = spltty(); 248 if (ISSET(lflag, PENDIN)) 249 ttypend(tp); 250 splx(s); 251 /* 252 * Gather stats. 253 */ 254 if (ISSET(lflag, ICANON)) { 255 ++tk_cancc; 256 ++tp->t_cancc; 257 } else { 258 ++tk_rawcc; 259 ++tp->t_rawcc; 260 } 261 ++tk_nin; 262 263 /* Handle exceptional conditions (break, parity, framing). */ 264 cc = tp->t_cc; 265 iflag = tp->t_iflag; 266 if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) { 267 CLR(c, TTY_ERRORMASK); 268 if (ISSET(error, TTY_FE) && !c) { /* Break. */ 269 if (ISSET(iflag, IGNBRK)) 270 return (0); 271 ttyflush(tp, FREAD | FWRITE); 272 if (ISSET(iflag, BRKINT)) { 273 pgsignal(tp->t_pgrp, SIGINT, 1); 274 goto endcase; 275 } 276 else if (ISSET(iflag, PARMRK)) 277 goto parmrk; 278 } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) || 279 ISSET(error, TTY_FE)) { 280 if (ISSET(iflag, IGNPAR)) 281 goto endcase; 282 else if (ISSET(iflag, PARMRK)) { 283 parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 284 if (ISSET(iflag, ISTRIP) || c != 0377) 285 (void)putc(0 | TTY_QUOTE, &tp->t_rawq); 286 (void)putc(c | TTY_QUOTE, &tp->t_rawq); 287 goto endcase; 288 } else 289 c = 0; 290 } 291 } 292 if (c == 0377 && !ISSET(iflag, ISTRIP) && ISSET(iflag, PARMRK)) 293 goto parmrk; 294 295 /* 296 * In tandem mode, check high water mark. 297 */ 298 if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW)) 299 ttyblock(tp); 300 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP)) 301 CLR(c, 0x80); 302 if (!ISSET(lflag, EXTPROC)) { 303 /* 304 * Check for literal nexting very first 305 */ 306 if (ISSET(tp->t_state, TS_LNCH)) { 307 SET(c, TTY_QUOTE); 308 CLR(tp->t_state, TS_LNCH); 309 } 310 /* 311 * Scan for special characters. This code 312 * is really just a big case statement with 313 * non-constant cases. The bottom of the 314 * case statement is labeled ``endcase'', so goto 315 * it after a case match, or similar. 316 */ 317 318 /* 319 * Control chars which aren't controlled 320 * by ICANON, ISIG, or IXON. 321 */ 322 if (ISSET(lflag, IEXTEN)) { 323 if (CCEQ(cc[VLNEXT], c)) { 324 if (ISSET(lflag, ECHO)) { 325 if (ISSET(lflag, ECHOE)) { 326 (void)ttyoutput('^', tp); 327 (void)ttyoutput('\b', tp); 328 } else 329 ttyecho(c, tp); 330 } 331 SET(tp->t_state, TS_LNCH); 332 goto endcase; 333 } 334 if (CCEQ(cc[VDISCARD], c)) { 335 if (ISSET(lflag, FLUSHO)) 336 CLR(tp->t_lflag, FLUSHO); 337 else { 338 ttyflush(tp, FWRITE); 339 ttyecho(c, tp); 340 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 341 ttyretype(tp); 342 SET(tp->t_lflag, FLUSHO); 343 } 344 goto startoutput; 345 } 346 } 347 /* 348 * Signals. 349 */ 350 if (ISSET(lflag, ISIG)) { 351 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 352 if (!ISSET(lflag, NOFLSH)) 353 ttyflush(tp, FREAD | FWRITE); 354 ttyecho(c, tp); 355 pgsignal(tp->t_pgrp, 356 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1); 357 goto endcase; 358 } 359 if (CCEQ(cc[VSUSP], c)) { 360 if (!ISSET(lflag, NOFLSH)) 361 ttyflush(tp, FREAD); 362 ttyecho(c, tp); 363 pgsignal(tp->t_pgrp, SIGTSTP, 1); 364 goto endcase; 365 } 366 } 367 /* 368 * Handle start/stop characters. 369 */ 370 if (ISSET(iflag, IXON)) { 371 if (CCEQ(cc[VSTOP], c)) { 372 if (!ISSET(tp->t_state, TS_TTSTOP)) { 373 SET(tp->t_state, TS_TTSTOP); 374 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 375 0); 376 return (0); 377 } 378 if (!CCEQ(cc[VSTART], c)) 379 return (0); 380 /* 381 * if VSTART == VSTOP then toggle 382 */ 383 goto endcase; 384 } 385 if (CCEQ(cc[VSTART], c)) 386 goto restartoutput; 387 } 388 /* 389 * IGNCR, ICRNL, & INLCR 390 */ 391 if (c == '\r') { 392 if (ISSET(iflag, IGNCR)) 393 goto endcase; 394 else if (ISSET(iflag, ICRNL)) 395 c = '\n'; 396 } else if (c == '\n' && ISSET(iflag, INLCR)) 397 c = '\r'; 398 } 399 if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) { 400 /* 401 * From here on down canonical mode character 402 * processing takes place. 403 */ 404 /* 405 * upper case or specials with IUCLC and XCASE 406 */ 407 if (ISSET(lflag, XCASE) && ISSET(iflag, IUCLC)) { 408 if (ISSET(tp->t_state, TS_BKSL)) { 409 CLR(tp->t_state, TS_BKSL); 410 switch (c) { 411 case '\'': 412 c = '`'; 413 break; 414 case '!': 415 c = '|'; 416 break; 417 case '^': 418 c = '~'; 419 break; 420 case '(': 421 c = '{'; 422 break; 423 case ')': 424 c = '}'; 425 break; 426 } 427 } 428 else if (c == '\\') { 429 SET(tp->t_state, TS_BKSL); 430 goto endcase; 431 } 432 else if (isupper(c)) 433 c = tolower(c); 434 } 435 else if (ISSET(iflag, IUCLC) && isupper(c)) 436 c = tolower(c); 437 /* 438 * erase (^H / ^?) 439 */ 440 if (CCEQ(cc[VERASE], c)) { 441 if (tp->t_rawq.c_cc) 442 ttyrub(unputc(&tp->t_rawq), tp); 443 goto endcase; 444 } 445 /* 446 * kill (^U) 447 */ 448 if (CCEQ(cc[VKILL], c)) { 449 if (ISSET(lflag, ECHOKE) && 450 tp->t_rawq.c_cc == tp->t_rocount && 451 !ISSET(lflag, ECHOPRT)) 452 while (tp->t_rawq.c_cc) 453 ttyrub(unputc(&tp->t_rawq), tp); 454 else { 455 ttyecho(c, tp); 456 if (ISSET(lflag, ECHOK) || 457 ISSET(lflag, ECHOKE)) 458 ttyecho('\n', tp); 459 FLUSHQ(&tp->t_rawq); 460 tp->t_rocount = 0; 461 } 462 CLR(tp->t_state, TS_LOCAL); 463 goto endcase; 464 } 465 /* 466 * word erase (^W) 467 */ 468 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) { 469 int alt = ISSET(lflag, ALTWERASE); 470 int ctype; 471 472 /* 473 * erase whitespace 474 */ 475 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t') 476 ttyrub(c, tp); 477 if (c == -1) 478 goto endcase; 479 /* 480 * erase last char of word and remember the 481 * next chars type (for ALTWERASE) 482 */ 483 ttyrub(c, tp); 484 c = unputc(&tp->t_rawq); 485 if (c == -1) 486 goto endcase; 487 if (c == ' ' || c == '\t') { 488 (void)putc(c, &tp->t_rawq); 489 goto endcase; 490 } 491 ctype = ISALPHA(c); 492 /* 493 * erase rest of word 494 */ 495 do { 496 ttyrub(c, tp); 497 c = unputc(&tp->t_rawq); 498 if (c == -1) 499 goto endcase; 500 } while (c != ' ' && c != '\t' && 501 (alt == 0 || ISALPHA(c) == ctype)); 502 (void)putc(c, &tp->t_rawq); 503 goto endcase; 504 } 505 /* 506 * reprint line (^R) 507 */ 508 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) { 509 ttyretype(tp); 510 goto endcase; 511 } 512 /* 513 * ^T - kernel info and generate SIGINFO 514 */ 515 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) { 516 if (ISSET(lflag, ISIG)) 517 pgsignal(tp->t_pgrp, SIGINFO, 1); 518 if (!ISSET(lflag, NOKERNINFO)) 519 ttyinfo(tp); 520 goto endcase; 521 } 522 } 523 /* 524 * Check for input buffer overflow 525 */ 526 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG(tp)) { 527 if (ISSET(iflag, IMAXBEL)) { 528 if (tp->t_outq.c_cc < tp->t_hiwat) 529 (void)ttyoutput(CTRL('g'), tp); 530 } else 531 ttyflush(tp, FREAD | FWRITE); 532 goto endcase; 533 } 534 /* 535 * Put data char in q for user and 536 * wakeup on seeing a line delimiter. 537 */ 538 if (putc(c, &tp->t_rawq) >= 0) { 539 if (!ISSET(lflag, ICANON)) { 540 ttwakeup(tp); 541 ttyecho(c, tp); 542 goto endcase; 543 } 544 if (TTBREAKC(c, lflag)) { 545 tp->t_rocount = 0; 546 catq(&tp->t_rawq, &tp->t_canq); 547 ttwakeup(tp); 548 } else if (tp->t_rocount++ == 0) 549 tp->t_rocol = tp->t_column; 550 if (ISSET(tp->t_state, TS_ERASE)) { 551 /* 552 * end of prterase \.../ 553 */ 554 CLR(tp->t_state, TS_ERASE); 555 (void)ttyoutput('/', tp); 556 } 557 i = tp->t_column; 558 ttyecho(c, tp); 559 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) { 560 /* 561 * Place the cursor over the '^' of the ^D. 562 */ 563 i = min(2, tp->t_column - i); 564 while (i > 0) { 565 (void)ttyoutput('\b', tp); 566 i--; 567 } 568 } 569 } 570 endcase: 571 /* 572 * IXANY means allow any character to restart output. 573 */ 574 if (ISSET(tp->t_state, TS_TTSTOP) && 575 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) 576 return (0); 577 restartoutput: 578 CLR(tp->t_lflag, FLUSHO); 579 CLR(tp->t_state, TS_TTSTOP); 580 startoutput: 581 return (ttstart(tp)); 582 } 583 584 /* 585 * Output a single character on a tty, doing output processing 586 * as needed (expanding tabs, newline processing, etc.). 587 * Returns < 0 if succeeds, otherwise returns char to resend. 588 * Must be recursive. 589 */ 590 int 591 ttyoutput(int c, struct tty *tp) 592 { 593 long oflag; 594 int col, notout, s, c2; 595 596 oflag = tp->t_oflag; 597 if (!ISSET(oflag, OPOST)) { 598 tk_nout++; 599 tp->t_outcc++; 600 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 601 return (c); 602 return (-1); 603 } 604 /* 605 * Do tab expansion if OXTABS is set. Special case if we external 606 * processing, we don't do the tab expansion because we'll probably 607 * get it wrong. If tab expansion needs to be done, let it happen 608 * externally. 609 */ 610 CLR(c, ~TTY_CHARMASK); 611 if (c == '\t' && 612 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { 613 c = 8 - (tp->t_column & 7); 614 if (ISSET(tp->t_lflag, FLUSHO)) { 615 notout = 0; 616 } else { 617 s = spltty(); /* Don't interrupt tabs. */ 618 notout = b_to_q(" ", c, &tp->t_outq); 619 c -= notout; 620 tk_nout += c; 621 tp->t_outcc += c; 622 splx(s); 623 } 624 tp->t_column += c; 625 return (notout ? '\t' : -1); 626 } 627 if (c == CEOT && ISSET(oflag, ONOEOT)) 628 return (-1); 629 630 /* 631 * Newline translation: if ONLCR is set, 632 * translate newline into "\r\n". If OCRNL 633 * is set, translate '\r' into '\n'. 634 */ 635 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { 636 tk_nout++; 637 tp->t_outcc++; 638 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq)) 639 return (c); 640 tp->t_column = 0; 641 } 642 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL)) 643 c = '\n'; 644 645 if (ISSET(tp->t_oflag, OLCUC) && islower(c)) 646 c = toupper(c); 647 else if (ISSET(tp->t_oflag, OLCUC) && ISSET(tp->t_lflag, XCASE)) { 648 c2 = c; 649 switch (c) { 650 case '`': 651 c2 = '\''; 652 break; 653 case '|': 654 c2 = '!'; 655 break; 656 case '~': 657 c2 = '^'; 658 break; 659 case '{': 660 c2 = '('; 661 break; 662 case '}': 663 c2 = ')'; 664 break; 665 } 666 if (c == '\\' || isupper(c) || c != c2) { 667 tk_nout++; 668 tp->t_outcc++; 669 if (putc('\\', &tp->t_outq)) 670 return (c); 671 c = c2; 672 } 673 } 674 if (ISSET(tp->t_oflag, ONOCR) && c == '\r' && tp->t_column == 0) 675 return (-1); 676 677 tk_nout++; 678 tp->t_outcc++; 679 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 680 return (c); 681 682 col = tp->t_column; 683 switch (CCLASS(c)) { 684 case BACKSPACE: 685 if (col > 0) 686 --col; 687 break; 688 case CONTROL: 689 break; 690 case NEWLINE: 691 if (ISSET(tp->t_oflag, ONLRET) || ISSET(tp->t_oflag, OCRNL)) 692 col = 0; 693 break; 694 case RETURN: 695 col = 0; 696 break; 697 case ORDINARY: 698 ++col; 699 break; 700 case TAB: 701 col = (col + 8) & ~7; 702 break; 703 } 704 tp->t_column = col; 705 return (-1); 706 } 707 708 /* 709 * Ioctls for all tty devices. Called after line-discipline specific ioctl 710 * has been called to do discipline-specific functions and/or reject any 711 * of these ioctl commands. 712 */ 713 /* ARGSUSED */ 714 int 715 ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) 716 { 717 extern struct tty *constty; /* Temporary virtual console. */ 718 extern int nlinesw; 719 struct process *pr = p->p_p; 720 int s, error; 721 722 /* If the ioctl involves modification, hang if in the background. */ 723 switch (cmd) { 724 case TIOCFLUSH: 725 case TIOCDRAIN: 726 case TIOCSBRK: 727 case TIOCCBRK: 728 case TIOCSETA: 729 case TIOCSETD: 730 case TIOCSETAF: 731 case TIOCSETAW: 732 #ifdef notdef 733 case TIOCSPGRP: 734 #endif 735 case TIOCSTAT: 736 case TIOCSTI: 737 case TIOCSWINSZ: 738 while (isbackground(pr, tp) && 739 (pr->ps_flags & PS_PPWAIT) == 0 && 740 (pr->ps_sigacts->ps_sigignore & sigmask(SIGTTOU)) == 0 && 741 (p->p_sigmask & sigmask(SIGTTOU)) == 0) { 742 if (pr->ps_pgrp->pg_jobc == 0) 743 return (EIO); 744 pgsignal(pr->ps_pgrp, SIGTTOU, 1); 745 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, 746 ttybg, 0); 747 if (error) 748 return (error); 749 } 750 break; 751 } 752 753 switch (cmd) { /* Process the ioctl. */ 754 case FIOASYNC: /* set/clear async i/o */ 755 s = spltty(); 756 if (*(int *)data) 757 SET(tp->t_state, TS_ASYNC); 758 else 759 CLR(tp->t_state, TS_ASYNC); 760 splx(s); 761 break; 762 case FIONBIO: /* set/clear non-blocking i/o */ 763 break; /* XXX: delete. */ 764 case FIONREAD: /* get # bytes to read */ 765 s = spltty(); 766 *(int *)data = ttnread(tp); 767 splx(s); 768 break; 769 case TIOCEXCL: /* set exclusive use of tty */ 770 s = spltty(); 771 SET(tp->t_state, TS_XCLUDE); 772 splx(s); 773 break; 774 case TIOCFLUSH: { /* flush buffers */ 775 int flags = *(int *)data; 776 777 if (flags == 0) 778 flags = FREAD | FWRITE; 779 else 780 flags &= FREAD | FWRITE; 781 ttyflush(tp, flags); 782 break; 783 } 784 case TIOCCONS: { /* become virtual console */ 785 if (*(int *)data) { 786 struct nameidata nid; 787 788 if (constty != NULL && constty != tp && 789 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) == 790 (TS_CARR_ON | TS_ISOPEN)) 791 return (EBUSY); 792 793 /* ensure user can open the real console */ 794 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p); 795 error = namei(&nid); 796 if (error) 797 return (error); 798 vn_lock(nid.ni_vp, LK_EXCLUSIVE | LK_RETRY, p); 799 error = VOP_ACCESS(nid.ni_vp, VREAD, p->p_ucred, p); 800 VOP_UNLOCK(nid.ni_vp, 0, p); 801 vrele(nid.ni_vp); 802 if (error) 803 return (error); 804 805 constty = tp; 806 } else if (tp == constty) 807 constty = NULL; 808 break; 809 } 810 case TIOCDRAIN: /* wait till output drained */ 811 if ((error = ttywait(tp)) != 0) 812 return (error); 813 break; 814 case TIOCGETA: { /* get termios struct */ 815 struct termios *t = (struct termios *)data; 816 817 bcopy(&tp->t_termios, t, sizeof(struct termios)); 818 break; 819 } 820 case TIOCGETD: /* get line discipline */ 821 *(int *)data = tp->t_line; 822 break; 823 case TIOCGWINSZ: /* get window size */ 824 *(struct winsize *)data = tp->t_winsize; 825 break; 826 case TIOCGTSTAMP: 827 s = spltty(); 828 *(struct timeval *)data = tp->t_tv; 829 splx(s); 830 break; 831 case TIOCGPGRP: /* get pgrp of tty */ 832 if (!isctty(pr, tp) && suser(p, 0)) 833 return (ENOTTY); 834 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 835 break; 836 case TIOCGSID: /* get sid of tty */ 837 if (!isctty(pr, tp)) 838 return (ENOTTY); 839 *(int *)data = tp->t_session->s_leader->ps_pid; 840 break; 841 #ifdef TIOCHPCL 842 case TIOCHPCL: /* hang up on last close */ 843 s = spltty(); 844 SET(tp->t_cflag, HUPCL); 845 splx(s); 846 break; 847 #endif 848 case TIOCNXCL: /* reset exclusive use of tty */ 849 s = spltty(); 850 CLR(tp->t_state, TS_XCLUDE); 851 splx(s); 852 break; 853 case TIOCOUTQ: /* output queue size */ 854 *(int *)data = tp->t_outq.c_cc; 855 break; 856 case TIOCSETA: /* set termios struct */ 857 case TIOCSETAW: /* drain output, set */ 858 case TIOCSETAF: { /* drn out, fls in, set */ 859 struct termios *t = (struct termios *)data; 860 861 s = spltty(); 862 if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 863 if ((error = ttywait(tp)) != 0) { 864 splx(s); 865 return (error); 866 } 867 if (cmd == TIOCSETAF) 868 ttyflush(tp, FREAD); 869 } 870 if (!ISSET(t->c_cflag, CIGNORE)) { 871 /* 872 * Some minor validation is necessary. 873 */ 874 if (t->c_ispeed < 0 || t->c_ospeed < 0) { 875 splx(s); 876 return (EINVAL); 877 } 878 /* 879 * Set device hardware. 880 */ 881 if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 882 splx(s); 883 return (error); 884 } else { 885 if (!ISSET(tp->t_state, TS_CARR_ON) && 886 ISSET(tp->t_cflag, CLOCAL) && 887 !ISSET(t->c_cflag, CLOCAL)) { 888 CLR(tp->t_state, TS_ISOPEN); 889 SET(tp->t_state, TS_WOPEN); 890 ttwakeup(tp); 891 } 892 tp->t_cflag = t->c_cflag; 893 tp->t_ispeed = t->c_ispeed; 894 tp->t_ospeed = t->c_ospeed; 895 if (t->c_ospeed == 0 && tp->t_session && 896 tp->t_session->s_leader) 897 prsignal(tp->t_session->s_leader, 898 SIGHUP); 899 } 900 ttsetwater(tp); 901 } 902 if (cmd != TIOCSETAF) { 903 if (ISSET(t->c_lflag, ICANON) != 904 ISSET(tp->t_lflag, ICANON)) { 905 if (ISSET(t->c_lflag, ICANON)) { 906 SET(tp->t_lflag, PENDIN); 907 ttwakeup(tp); 908 } else { 909 struct clist tq; 910 911 catq(&tp->t_rawq, &tp->t_canq); 912 tq = tp->t_rawq; 913 tp->t_rawq = tp->t_canq; 914 tp->t_canq = tq; 915 CLR(tp->t_lflag, PENDIN); 916 } 917 } 918 } 919 tp->t_iflag = t->c_iflag; 920 tp->t_oflag = t->c_oflag; 921 /* 922 * Make the EXTPROC bit read only. 923 */ 924 if (ISSET(tp->t_lflag, EXTPROC)) 925 SET(t->c_lflag, EXTPROC); 926 else 927 CLR(t->c_lflag, EXTPROC); 928 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN); 929 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 930 splx(s); 931 break; 932 } 933 case TIOCSETD: { /* set line discipline */ 934 int t = *(int *)data; 935 dev_t device = tp->t_dev; 936 937 if ((u_int)t >= nlinesw) 938 return (ENXIO); 939 if (t != tp->t_line) { 940 s = spltty(); 941 (*linesw[tp->t_line].l_close)(tp, flag, p); 942 error = (*linesw[t].l_open)(device, tp, p); 943 if (error) { 944 (*linesw[tp->t_line].l_open)(device, tp, p); 945 splx(s); 946 return (error); 947 } 948 tp->t_line = t; 949 splx(s); 950 } 951 break; 952 } 953 case TIOCSTART: /* start output, like ^Q */ 954 s = spltty(); 955 if (ISSET(tp->t_state, TS_TTSTOP) || 956 ISSET(tp->t_lflag, FLUSHO)) { 957 CLR(tp->t_lflag, FLUSHO); 958 CLR(tp->t_state, TS_TTSTOP); 959 ttstart(tp); 960 } 961 splx(s); 962 break; 963 case TIOCSTI: /* simulate terminal input */ 964 if (p->p_ucred->cr_uid && (flag & FREAD) == 0) 965 return (EPERM); 966 if (p->p_ucred->cr_uid && !isctty(pr, tp)) 967 return (EACCES); 968 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp); 969 break; 970 case TIOCSTOP: /* stop output, like ^S */ 971 s = spltty(); 972 if (!ISSET(tp->t_state, TS_TTSTOP)) { 973 SET(tp->t_state, TS_TTSTOP); 974 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 975 } 976 splx(s); 977 break; 978 case TIOCSCTTY: /* become controlling tty */ 979 /* Session ctty vnode pointer set in vnode layer. */ 980 if (!SESS_LEADER(pr) || 981 ((pr->ps_session->s_ttyvp || tp->t_session) && 982 (tp->t_session != pr->ps_session))) 983 return (EPERM); 984 if (tp->t_session) 985 SESSRELE(tp->t_session); 986 SESSHOLD(pr->ps_session); 987 tp->t_session = pr->ps_session; 988 tp->t_pgrp = pr->ps_pgrp; 989 pr->ps_session->s_ttyp = tp; 990 atomic_setbits_int(&pr->ps_flags, PS_CONTROLT); 991 break; 992 case TIOCSPGRP: { /* set pgrp of tty */ 993 struct pgrp *pgrp = pgfind(*(int *)data); 994 995 if (!isctty(pr, tp)) 996 return (ENOTTY); 997 else if (pgrp == NULL) 998 return (EINVAL); 999 else if (pgrp->pg_session != pr->ps_session) 1000 return (EPERM); 1001 tp->t_pgrp = pgrp; 1002 break; 1003 } 1004 case TIOCSTAT: /* get load avg stats */ 1005 ttyinfo(tp); 1006 break; 1007 case TIOCSWINSZ: /* set window size */ 1008 if (bcmp((caddr_t)&tp->t_winsize, data, 1009 sizeof (struct winsize))) { 1010 tp->t_winsize = *(struct winsize *)data; 1011 pgsignal(tp->t_pgrp, SIGWINCH, 1); 1012 } 1013 break; 1014 case TIOCSTSTAMP: { 1015 struct tstamps *ts = (struct tstamps *)data; 1016 1017 s = spltty(); 1018 CLR(tp->t_flags, TS_TSTAMPDCDSET); 1019 CLR(tp->t_flags, TS_TSTAMPCTSSET); 1020 CLR(tp->t_flags, TS_TSTAMPDCDCLR); 1021 CLR(tp->t_flags, TS_TSTAMPCTSCLR); 1022 if (ISSET(ts->ts_set, TIOCM_CAR)) 1023 SET(tp->t_flags, TS_TSTAMPDCDSET); 1024 if (ISSET(ts->ts_set, TIOCM_CTS)) 1025 SET(tp->t_flags, TS_TSTAMPCTSSET); 1026 if (ISSET(ts->ts_clr, TIOCM_CAR)) 1027 SET(tp->t_flags, TS_TSTAMPDCDCLR); 1028 if (ISSET(ts->ts_clr, TIOCM_CTS)) 1029 SET(tp->t_flags, TS_TSTAMPCTSCLR); 1030 splx(s); 1031 break; 1032 } 1033 default: 1034 return (-1); 1035 } 1036 return (0); 1037 } 1038 1039 int 1040 ttpoll(dev_t device, int events, struct proc *p) 1041 { 1042 struct tty *tp; 1043 int revents, s; 1044 1045 tp = (*cdevsw[major(device)].d_tty)(device); 1046 1047 revents = 0; 1048 s = spltty(); 1049 if (events & (POLLIN | POLLRDNORM)) { 1050 if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) && 1051 !ISSET(tp->t_state, TS_CARR_ON))) 1052 revents |= events & (POLLIN | POLLRDNORM); 1053 } 1054 /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */ 1055 if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { 1056 revents |= POLLHUP; 1057 } else if (events & (POLLOUT | POLLWRNORM)) { 1058 if (tp->t_outq.c_cc <= tp->t_lowat) 1059 revents |= events & (POLLOUT | POLLWRNORM); 1060 } 1061 if (revents == 0) { 1062 if (events & (POLLIN | POLLRDNORM)) 1063 selrecord(p, &tp->t_rsel); 1064 if (events & (POLLOUT | POLLWRNORM)) 1065 selrecord(p, &tp->t_wsel); 1066 } 1067 splx(s); 1068 return (revents); 1069 } 1070 1071 struct filterops ttyread_filtops = 1072 { 1, NULL, filt_ttyrdetach, filt_ttyread }; 1073 struct filterops ttywrite_filtops = 1074 { 1, NULL, filt_ttywdetach, filt_ttywrite }; 1075 1076 int 1077 ttkqfilter(dev_t dev, struct knote *kn) 1078 { 1079 struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev); 1080 struct klist *klist; 1081 int s; 1082 1083 switch (kn->kn_filter) { 1084 case EVFILT_READ: 1085 klist = &tp->t_rsel.si_note; 1086 kn->kn_fop = &ttyread_filtops; 1087 break; 1088 case EVFILT_WRITE: 1089 klist = &tp->t_wsel.si_note; 1090 kn->kn_fop = &ttywrite_filtops; 1091 break; 1092 default: 1093 return (EINVAL); 1094 } 1095 1096 kn->kn_hook = (caddr_t)((u_long)dev); 1097 1098 s = spltty(); 1099 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1100 splx(s); 1101 1102 return (0); 1103 } 1104 1105 void 1106 ttkqflush(struct klist *klist) 1107 { 1108 struct knote *kn, *kn1; 1109 1110 SLIST_FOREACH_SAFE(kn, klist, kn_selnext, kn1) { 1111 SLIST_REMOVE(klist, kn, knote, kn_selnext); 1112 kn->kn_hook = (caddr_t)((u_long)NODEV); 1113 kn->kn_flags |= EV_EOF; 1114 knote_activate(kn); 1115 } 1116 } 1117 1118 void 1119 filt_ttyrdetach(struct knote *kn) 1120 { 1121 dev_t dev = (dev_t)((u_long)kn->kn_hook); 1122 struct tty *tp; 1123 int s; 1124 1125 if (dev == NODEV) 1126 return; 1127 tp = (*cdevsw[major(dev)].d_tty)(dev); 1128 1129 s = spltty(); 1130 SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext); 1131 splx(s); 1132 } 1133 1134 int 1135 filt_ttyread(struct knote *kn, long hint) 1136 { 1137 dev_t dev = (dev_t)((u_long)kn->kn_hook); 1138 struct tty *tp; 1139 int s; 1140 1141 if (dev == NODEV) { 1142 kn->kn_flags |= EV_EOF; 1143 return (1); 1144 } 1145 tp = (*cdevsw[major(dev)].d_tty)(dev); 1146 1147 s = spltty(); 1148 kn->kn_data = ttnread(tp); 1149 splx(s); 1150 if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { 1151 kn->kn_flags |= EV_EOF; 1152 return (1); 1153 } 1154 return (kn->kn_data > 0); 1155 } 1156 1157 void 1158 filt_ttywdetach(struct knote *kn) 1159 { 1160 dev_t dev = (dev_t)((u_long)kn->kn_hook); 1161 struct tty *tp; 1162 int s; 1163 1164 if (dev == NODEV) 1165 return; 1166 tp = (*cdevsw[major(dev)].d_tty)(dev); 1167 1168 s = spltty(); 1169 SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext); 1170 splx(s); 1171 } 1172 1173 int 1174 filt_ttywrite(struct knote *kn, long hint) 1175 { 1176 dev_t dev = (dev_t)((u_long)kn->kn_hook); 1177 struct tty *tp; 1178 int canwrite, s; 1179 1180 if (dev == NODEV) { 1181 kn->kn_flags |= EV_EOF; 1182 return (1); 1183 } 1184 tp = (*cdevsw[major(dev)].d_tty)(dev); 1185 1186 s = spltty(); 1187 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc; 1188 canwrite = (tp->t_outq.c_cc <= tp->t_lowat); 1189 splx(s); 1190 return (canwrite); 1191 } 1192 1193 static int 1194 ttnread(struct tty *tp) 1195 { 1196 int nread; 1197 1198 splassert(IPL_TTY); 1199 1200 if (ISSET(tp->t_lflag, PENDIN)) 1201 ttypend(tp); 1202 nread = tp->t_canq.c_cc; 1203 if (!ISSET(tp->t_lflag, ICANON)) { 1204 nread += tp->t_rawq.c_cc; 1205 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME]) 1206 nread = 0; 1207 } 1208 return (nread); 1209 } 1210 1211 /* 1212 * Wait for output to drain. 1213 */ 1214 int 1215 ttywait(struct tty *tp) 1216 { 1217 int error, s; 1218 1219 error = 0; 1220 s = spltty(); 1221 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1222 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) && 1223 tp->t_oproc) { 1224 (*tp->t_oproc)(tp); 1225 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1226 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) 1227 && tp->t_oproc) { 1228 SET(tp->t_state, TS_ASLEEP); 1229 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1230 if (error) 1231 break; 1232 } else 1233 break; 1234 } 1235 splx(s); 1236 return (error); 1237 } 1238 1239 /* 1240 * Flush if successfully wait. 1241 */ 1242 int 1243 ttywflush(struct tty *tp) 1244 { 1245 int error; 1246 1247 if ((error = ttywait(tp)) == 0) 1248 ttyflush(tp, FREAD); 1249 return (error); 1250 } 1251 1252 /* 1253 * Flush tty read and/or write queues, notifying anyone waiting. 1254 */ 1255 void 1256 ttyflush(struct tty *tp, int rw) 1257 { 1258 int s; 1259 1260 s = spltty(); 1261 if (rw & FREAD) { 1262 FLUSHQ(&tp->t_canq); 1263 FLUSHQ(&tp->t_rawq); 1264 tp->t_rocount = 0; 1265 tp->t_rocol = 0; 1266 CLR(tp->t_state, TS_LOCAL); 1267 ttyunblock(tp); 1268 ttwakeup(tp); 1269 } 1270 if (rw & FWRITE) { 1271 CLR(tp->t_state, TS_TTSTOP); 1272 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 1273 FLUSHQ(&tp->t_outq); 1274 wakeup((caddr_t)&tp->t_outq); 1275 selwakeup(&tp->t_wsel); 1276 } 1277 splx(s); 1278 } 1279 1280 /* 1281 * Copy in the default termios characters. 1282 */ 1283 void 1284 ttychars(struct tty *tp) 1285 { 1286 1287 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 1288 } 1289 1290 /* 1291 * Send stop character on input overflow. 1292 */ 1293 static void 1294 ttyblock(struct tty *tp) 1295 { 1296 int total; 1297 1298 total = tp->t_rawq.c_cc + tp->t_canq.c_cc; 1299 if (tp->t_rawq.c_cc > TTYHOG(tp)) { 1300 ttyflush(tp, FREAD | FWRITE); 1301 CLR(tp->t_state, TS_TBLOCK); 1302 } 1303 /* 1304 * Block further input iff: current input > threshold 1305 * AND input is available to user program. 1306 */ 1307 if ((total >= TTYHOG(tp) / 2 && 1308 !ISSET(tp->t_state, TS_TBLOCK) && 1309 !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) { 1310 if (ISSET(tp->t_iflag, IXOFF) && 1311 tp->t_cc[VSTOP] != _POSIX_VDISABLE && 1312 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) { 1313 SET(tp->t_state, TS_TBLOCK); 1314 ttstart(tp); 1315 } 1316 /* Try to block remote output via hardware flow control. */ 1317 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow && 1318 (*tp->t_hwiflow)(tp, 1) != 0) 1319 SET(tp->t_state, TS_TBLOCK); 1320 } 1321 } 1322 1323 void 1324 ttrstrt(void *tp_arg) 1325 { 1326 struct tty *tp; 1327 int s; 1328 1329 #ifdef DIAGNOSTIC 1330 if (tp_arg == NULL) 1331 panic("ttrstrt"); 1332 #endif 1333 tp = tp_arg; 1334 s = spltty(); 1335 1336 CLR(tp->t_state, TS_TIMEOUT); 1337 ttstart(tp); 1338 1339 splx(s); 1340 } 1341 1342 int 1343 ttstart(struct tty *tp) 1344 { 1345 1346 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1347 (*tp->t_oproc)(tp); 1348 return (0); 1349 } 1350 1351 /* 1352 * "close" a line discipline 1353 */ 1354 int 1355 ttylclose(struct tty *tp, int flag, struct proc *p) 1356 { 1357 1358 if (flag & FNONBLOCK) 1359 ttyflush(tp, FREAD | FWRITE); 1360 else 1361 ttywflush(tp); 1362 return (0); 1363 } 1364 1365 /* 1366 * Handle modem control transition on a tty. 1367 * Flag indicates new state of carrier. 1368 * Returns 0 if the line should be turned off, otherwise 1. 1369 */ 1370 int 1371 ttymodem(struct tty *tp, int flag) 1372 { 1373 1374 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) { 1375 /* 1376 * MDMBUF: do flow control according to carrier flag 1377 */ 1378 if (flag) { 1379 CLR(tp->t_state, TS_TTSTOP); 1380 ttstart(tp); 1381 } else if (!ISSET(tp->t_state, TS_TTSTOP)) { 1382 SET(tp->t_state, TS_TTSTOP); 1383 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 1384 } 1385 } else if (flag == 0) { 1386 /* 1387 * Lost carrier. 1388 */ 1389 CLR(tp->t_state, TS_CARR_ON); 1390 if (ISSET(tp->t_state, TS_ISOPEN) && 1391 !ISSET(tp->t_cflag, CLOCAL)) { 1392 if (tp->t_session && tp->t_session->s_leader) 1393 prsignal(tp->t_session->s_leader, SIGHUP); 1394 ttyflush(tp, FREAD | FWRITE); 1395 return (0); 1396 } 1397 } else { 1398 /* 1399 * Carrier now on. 1400 */ 1401 SET(tp->t_state, TS_CARR_ON); 1402 ttwakeup(tp); 1403 } 1404 return (1); 1405 } 1406 1407 /* 1408 * Default modem control routine (for other line disciplines). 1409 * Return argument flag, to turn off device on carrier drop. 1410 */ 1411 int 1412 nullmodem(struct tty *tp, int flag) 1413 { 1414 1415 if (flag) 1416 SET(tp->t_state, TS_CARR_ON); 1417 else { 1418 CLR(tp->t_state, TS_CARR_ON); 1419 if (ISSET(tp->t_state, TS_ISOPEN) && 1420 !ISSET(tp->t_cflag, CLOCAL)) { 1421 if (tp->t_session && tp->t_session->s_leader) 1422 prsignal(tp->t_session->s_leader, SIGHUP); 1423 ttyflush(tp, FREAD | FWRITE); 1424 return (0); 1425 } 1426 } 1427 return (1); 1428 } 1429 1430 /* 1431 * Reinput pending characters after state switch 1432 * call at spltty(). 1433 */ 1434 void 1435 ttypend(struct tty *tp) 1436 { 1437 struct clist tq; 1438 int c; 1439 1440 splassert(IPL_TTY); 1441 1442 CLR(tp->t_lflag, PENDIN); 1443 SET(tp->t_state, TS_TYPEN); 1444 tq = tp->t_rawq; 1445 tp->t_rawq.c_cc = 0; 1446 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 1447 while ((c = getc(&tq)) >= 0) 1448 ttyinput(c, tp); 1449 CLR(tp->t_state, TS_TYPEN); 1450 } 1451 1452 void ttvtimeout(void *); 1453 1454 void 1455 ttvtimeout(void *arg) 1456 { 1457 struct tty *tp = (struct tty *)arg; 1458 1459 wakeup(&tp->t_rawq); 1460 } 1461 1462 /* 1463 * Process a read call on a tty device. 1464 */ 1465 int 1466 ttread(struct tty *tp, struct uio *uio, int flag) 1467 { 1468 struct timeout *stime = NULL; 1469 struct proc *p = curproc; 1470 struct process *pr = p->p_p; 1471 int s, first, error = 0; 1472 u_char *cc = tp->t_cc; 1473 struct clist *qp; 1474 int last_cc = 0; 1475 long lflag; 1476 int c; 1477 1478 loop: lflag = tp->t_lflag; 1479 s = spltty(); 1480 /* 1481 * take pending input first 1482 */ 1483 if (ISSET(lflag, PENDIN)) 1484 ttypend(tp); 1485 splx(s); 1486 1487 /* 1488 * Hang process if it's in the background. 1489 */ 1490 if (isbackground(pr, tp)) { 1491 if ((pr->ps_sigacts->ps_sigignore & sigmask(SIGTTIN)) || 1492 (p->p_sigmask & sigmask(SIGTTIN)) || 1493 pr->ps_flags & PS_PPWAIT || pr->ps_pgrp->pg_jobc == 0) { 1494 error = EIO; 1495 goto out; 1496 } 1497 pgsignal(pr->ps_pgrp, SIGTTIN, 1); 1498 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1499 if (error) 1500 goto out; 1501 goto loop; 1502 } 1503 1504 s = spltty(); 1505 if (!ISSET(lflag, ICANON)) { 1506 int m = cc[VMIN]; 1507 long t; 1508 1509 /* 1510 * Note - since cc[VTIME] is a u_char, this won't overflow 1511 * until we have 32-bit longs and a hz > 8388608. 1512 * Hopefully this code and 32-bit longs are obsolete by then. 1513 */ 1514 t = cc[VTIME] * hz / 10; 1515 1516 qp = &tp->t_rawq; 1517 /* 1518 * Check each of the four combinations. 1519 * (m > 0 && t == 0) is the normal read case. 1520 * It should be fairly efficient, so we check that and its 1521 * companion case (m == 0 && t == 0) first. 1522 */ 1523 if (t == 0) { 1524 if (qp->c_cc < m) 1525 goto sleep; 1526 goto read; 1527 } 1528 if (m > 0) { 1529 if (qp->c_cc <= 0) 1530 goto sleep; 1531 if (qp->c_cc >= m) 1532 goto read; 1533 if (stime == NULL) { 1534 alloc_timer: 1535 stime = malloc(sizeof(*stime), M_TEMP, M_WAITOK); 1536 timeout_set(stime, ttvtimeout, tp); 1537 timeout_add(stime, t); 1538 } else if (qp->c_cc > last_cc) { 1539 /* got a character, restart timer */ 1540 timeout_add(stime, t); 1541 } 1542 } else { /* m == 0 */ 1543 if (qp->c_cc > 0) 1544 goto read; 1545 if (stime == NULL) { 1546 goto alloc_timer; 1547 } 1548 } 1549 last_cc = qp->c_cc; 1550 if (stime && !timeout_triggered(stime)) { 1551 goto sleep; 1552 } 1553 } else if ((qp = &tp->t_canq)->c_cc <= 0) { 1554 int carrier; 1555 1556 sleep: 1557 /* 1558 * If there is no input, sleep on rawq 1559 * awaiting hardware receipt and notification. 1560 * If we have data, we don't need to check for carrier. 1561 */ 1562 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1563 ISSET(tp->t_cflag, CLOCAL); 1564 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) { 1565 splx(s); 1566 error = 0; 1567 goto out; 1568 } 1569 if (flag & IO_NDELAY) { 1570 splx(s); 1571 error = EWOULDBLOCK; 1572 goto out; 1573 } 1574 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 1575 carrier ? ttyin : ttopen, 0); 1576 splx(s); 1577 if (stime && timeout_triggered(stime)) 1578 error = EWOULDBLOCK; 1579 if (cc[VMIN] == 0 && error == EWOULDBLOCK) { 1580 error = 0; 1581 goto out; 1582 } 1583 if (error && error != EWOULDBLOCK) 1584 goto out; 1585 error = 0; 1586 goto loop; 1587 } 1588 read: 1589 splx(s); 1590 1591 /* 1592 * Input present, check for input mapping and processing. 1593 */ 1594 first = 1; 1595 while ((c = getc(qp)) >= 0) { 1596 /* 1597 * delayed suspend (^Y) 1598 */ 1599 if (CCEQ(cc[VDSUSP], c) && 1600 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) { 1601 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1602 if (first) { 1603 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, 1604 ttybg, 0); 1605 if (error) 1606 break; 1607 goto loop; 1608 } 1609 break; 1610 } 1611 /* 1612 * Interpret EOF only in canonical mode. 1613 */ 1614 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1615 break; 1616 /* 1617 * Give user character. 1618 */ 1619 error = ureadc(c, uio); 1620 if (error) 1621 break; 1622 if (uio->uio_resid == 0) 1623 break; 1624 /* 1625 * In canonical mode check for a "break character" 1626 * marking the end of a "line of input". 1627 */ 1628 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag)) 1629 break; 1630 first = 0; 1631 } 1632 /* 1633 * Look to unblock output now that (presumably) 1634 * the input queue has gone down. 1635 */ 1636 s = spltty(); 1637 if (tp->t_rawq.c_cc < TTYHOG(tp)/5) 1638 ttyunblock(tp); 1639 splx(s); 1640 1641 out: 1642 if (stime) { 1643 timeout_del(stime); 1644 free(stime, M_TEMP, 0); 1645 } 1646 return (error); 1647 } 1648 1649 /* Call at spltty */ 1650 void 1651 ttyunblock(struct tty *tp) 1652 { 1653 u_char *cc = tp->t_cc; 1654 1655 splassert(IPL_TTY); 1656 1657 if (ISSET(tp->t_state, TS_TBLOCK)) { 1658 if (ISSET(tp->t_iflag, IXOFF) && 1659 cc[VSTART] != _POSIX_VDISABLE && 1660 putc(cc[VSTART], &tp->t_outq) == 0) { 1661 CLR(tp->t_state, TS_TBLOCK); 1662 ttstart(tp); 1663 } 1664 /* Try to unblock remote output via hardware flow control. */ 1665 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow && 1666 (*tp->t_hwiflow)(tp, 0) != 0) 1667 CLR(tp->t_state, TS_TBLOCK); 1668 } 1669 } 1670 1671 /* 1672 * Check the output queue on tp for space for a kernel message (from uprintf 1673 * or tprintf). Allow some space over the normal hiwater mark so we don't 1674 * lose messages due to normal flow control, but don't let the tty run amok. 1675 * Sleeps here are not interruptible, but we return prematurely if new signals 1676 * arrive. 1677 */ 1678 int 1679 ttycheckoutq(struct tty *tp, int wait) 1680 { 1681 int hiwat, s, oldsig; 1682 1683 hiwat = tp->t_hiwat; 1684 s = spltty(); 1685 oldsig = wait ? curproc->p_siglist : 0; 1686 if (tp->t_outq.c_cc > hiwat + 200) 1687 while (tp->t_outq.c_cc > hiwat) { 1688 ttstart(tp); 1689 if (wait == 0 || curproc->p_siglist != oldsig) { 1690 splx(s); 1691 return (0); 1692 } 1693 SET(tp->t_state, TS_ASLEEP); 1694 tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", hz); 1695 } 1696 splx(s); 1697 return (1); 1698 } 1699 1700 /* 1701 * Process a write call on a tty device. 1702 */ 1703 int 1704 ttwrite(struct tty *tp, struct uio *uio, int flag) 1705 { 1706 u_char *cp = NULL; 1707 int cc, ce, obufcc = 0; 1708 struct proc *p; 1709 struct process *pr; 1710 int i, hiwat, error, s; 1711 size_t cnt; 1712 u_char obuf[OBUFSIZ]; 1713 1714 hiwat = tp->t_hiwat; 1715 cnt = uio->uio_resid; 1716 error = 0; 1717 cc = 0; 1718 loop: 1719 s = spltty(); 1720 if (!ISSET(tp->t_state, TS_CARR_ON) && 1721 !ISSET(tp->t_cflag, CLOCAL)) { 1722 if (ISSET(tp->t_state, TS_ISOPEN)) { 1723 splx(s); 1724 error = EIO; 1725 goto done; 1726 } else if (flag & IO_NDELAY) { 1727 splx(s); 1728 error = EWOULDBLOCK; 1729 goto out; 1730 } else { 1731 /* Sleep awaiting carrier. */ 1732 error = ttysleep(tp, 1733 &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0); 1734 splx(s); 1735 if (error) 1736 goto out; 1737 goto loop; 1738 } 1739 } 1740 splx(s); 1741 /* 1742 * Hang the process if it's in the background. 1743 */ 1744 p = curproc; 1745 pr = p->p_p; 1746 if (isbackground(pr, tp) && 1747 ISSET(tp->t_lflag, TOSTOP) && (pr->ps_flags & PS_PPWAIT) == 0 && 1748 (pr->ps_sigacts->ps_sigignore & sigmask(SIGTTOU)) == 0 && 1749 (p->p_sigmask & sigmask(SIGTTOU)) == 0) { 1750 if (pr->ps_pgrp->pg_jobc == 0) { 1751 error = EIO; 1752 goto out; 1753 } 1754 pgsignal(pr->ps_pgrp, SIGTTOU, 1); 1755 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1756 if (error) 1757 goto out; 1758 goto loop; 1759 } 1760 /* 1761 * Process the user's data in at most OBUFSIZ chunks. Perform any 1762 * output translation. Keep track of high water mark, sleep on 1763 * overflow awaiting device aid in acquiring new space. 1764 */ 1765 while (uio->uio_resid > 0 || cc > 0) { 1766 if (ISSET(tp->t_lflag, FLUSHO)) { 1767 uio->uio_resid = 0; 1768 goto done; 1769 } 1770 if (tp->t_outq.c_cc > hiwat) 1771 goto ovhiwat; 1772 /* 1773 * Grab a hunk of data from the user, unless we have some 1774 * leftover from last time. 1775 */ 1776 if (cc == 0) { 1777 cc = MIN(uio->uio_resid, OBUFSIZ); 1778 cp = obuf; 1779 error = uiomove(cp, cc, uio); 1780 if (error) { 1781 cc = 0; 1782 break; 1783 } 1784 if (cc > obufcc) 1785 obufcc = cc; 1786 } 1787 /* 1788 * If nothing fancy need be done, grab those characters we 1789 * can handle without any of ttyoutput's processing and 1790 * just transfer them to the output q. For those chars 1791 * which require special processing (as indicated by the 1792 * bits in char_type), call ttyoutput. After processing 1793 * a hunk of data, look for FLUSHO so ^O's will take effect 1794 * immediately. 1795 */ 1796 while (cc > 0) { 1797 if (!ISSET(tp->t_oflag, OPOST)) 1798 ce = cc; 1799 else { 1800 ce = cc - scanc((u_int)cc, cp, char_type, 1801 CCLASSMASK); 1802 /* 1803 * If ce is zero, then we're processing 1804 * a special character through ttyoutput. 1805 */ 1806 if (ce == 0) { 1807 tp->t_rocount = 0; 1808 if (ttyoutput(*cp, tp) >= 0) { 1809 /* out of space */ 1810 goto overfull; 1811 } 1812 cp++; 1813 cc--; 1814 if (ISSET(tp->t_lflag, FLUSHO) || 1815 tp->t_outq.c_cc > hiwat) 1816 goto ovhiwat; 1817 continue; 1818 } 1819 } 1820 /* 1821 * A bunch of normal characters have been found. 1822 * Transfer them en masse to the output queue and 1823 * continue processing at the top of the loop. 1824 * If there are any further characters in this 1825 * <= OBUFSIZ chunk, the first should be a character 1826 * requiring special handling by ttyoutput. 1827 */ 1828 tp->t_rocount = 0; 1829 i = b_to_q(cp, ce, &tp->t_outq); 1830 ce -= i; 1831 tp->t_column += ce; 1832 cp += ce, cc -= ce, tk_nout += ce; 1833 tp->t_outcc += ce; 1834 if (i > 0) { 1835 /* out of space */ 1836 goto overfull; 1837 } 1838 if (ISSET(tp->t_lflag, FLUSHO) || 1839 tp->t_outq.c_cc > hiwat) 1840 break; 1841 } 1842 ttstart(tp); 1843 } 1844 out: 1845 /* 1846 * If cc is nonzero, we leave the uio structure inconsistent, as the 1847 * offset and iov pointers have moved forward, but it doesn't matter 1848 * (the call will either return short or restart with a new uio). 1849 */ 1850 uio->uio_resid += cc; 1851 done: 1852 if (obufcc) 1853 explicit_bzero(obuf, obufcc); 1854 return (error); 1855 1856 overfull: 1857 /* 1858 * Since we are using ring buffers, if we can't insert any more into 1859 * the output queue, we can assume the ring is full and that someone 1860 * forgot to set the high water mark correctly. We set it and then 1861 * proceed as normal. 1862 */ 1863 hiwat = tp->t_outq.c_cc - 1; 1864 1865 ovhiwat: 1866 ttstart(tp); 1867 s = spltty(); 1868 /* 1869 * This can only occur if FLUSHO is set in t_lflag, 1870 * or if ttstart/oproc is synchronous (or very fast). 1871 */ 1872 if (tp->t_outq.c_cc <= hiwat) { 1873 splx(s); 1874 goto loop; 1875 } 1876 if (flag & IO_NDELAY) { 1877 splx(s); 1878 uio->uio_resid += cc; 1879 if (obufcc) 1880 explicit_bzero(obuf, obufcc); 1881 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1882 } 1883 SET(tp->t_state, TS_ASLEEP); 1884 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1885 splx(s); 1886 if (error) 1887 goto out; 1888 goto loop; 1889 } 1890 1891 /* 1892 * Rubout one character from the rawq of tp 1893 * as cleanly as possible. 1894 */ 1895 void 1896 ttyrub(int c, struct tty *tp) 1897 { 1898 u_char *cp; 1899 int savecol; 1900 int tabc, s; 1901 1902 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1903 return; 1904 CLR(tp->t_lflag, FLUSHO); 1905 if (ISSET(tp->t_lflag, ECHOE)) { 1906 if (tp->t_rocount == 0) { 1907 /* 1908 * Screwed by ttwrite; retype 1909 */ 1910 ttyretype(tp); 1911 return; 1912 } 1913 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1914 ttyrubo(tp, 2); 1915 else { 1916 CLR(c, ~TTY_CHARMASK); 1917 switch (CCLASS(c)) { 1918 case ORDINARY: 1919 ttyrubo(tp, 1); 1920 break; 1921 case BACKSPACE: 1922 case CONTROL: 1923 case NEWLINE: 1924 case RETURN: 1925 case VTAB: 1926 if (ISSET(tp->t_lflag, ECHOCTL)) 1927 ttyrubo(tp, 2); 1928 break; 1929 case TAB: 1930 if (tp->t_rocount < tp->t_rawq.c_cc) { 1931 ttyretype(tp); 1932 return; 1933 } 1934 s = spltty(); 1935 savecol = tp->t_column; 1936 SET(tp->t_state, TS_CNTTB); 1937 SET(tp->t_lflag, FLUSHO); 1938 tp->t_column = tp->t_rocol; 1939 for (cp = firstc(&tp->t_rawq, &tabc); cp; 1940 cp = nextc(&tp->t_rawq, cp, &tabc)) 1941 ttyecho(tabc, tp); 1942 CLR(tp->t_lflag, FLUSHO); 1943 CLR(tp->t_state, TS_CNTTB); 1944 splx(s); 1945 1946 /* savecol will now be length of the tab. */ 1947 savecol -= tp->t_column; 1948 tp->t_column += savecol; 1949 if (savecol > 8) 1950 savecol = 8; /* overflow screw */ 1951 while (--savecol >= 0) 1952 (void)ttyoutput('\b', tp); 1953 break; 1954 default: /* XXX */ 1955 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1956 (void)printf(PANICSTR, c, CCLASS(c)); 1957 #ifdef notdef 1958 panic(PANICSTR, c, CCLASS(c)); 1959 #endif 1960 } 1961 } 1962 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1963 if (!ISSET(tp->t_state, TS_ERASE)) { 1964 SET(tp->t_state, TS_ERASE); 1965 (void)ttyoutput('\\', tp); 1966 } 1967 ttyecho(c, tp); 1968 } else 1969 ttyecho(tp->t_cc[VERASE], tp); 1970 --tp->t_rocount; 1971 } 1972 1973 /* 1974 * Back over cnt characters, erasing them. 1975 */ 1976 static void 1977 ttyrubo(struct tty *tp, int cnt) 1978 { 1979 1980 while (cnt-- > 0) { 1981 (void)ttyoutput('\b', tp); 1982 (void)ttyoutput(' ', tp); 1983 (void)ttyoutput('\b', tp); 1984 } 1985 } 1986 1987 /* 1988 * ttyretype -- 1989 * Reprint the rawq line. Note, it is assumed that c_cc has already 1990 * been checked. 1991 */ 1992 void 1993 ttyretype(struct tty *tp) 1994 { 1995 u_char *cp; 1996 int s, c; 1997 1998 /* Echo the reprint character. */ 1999 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 2000 ttyecho(tp->t_cc[VREPRINT], tp); 2001 2002 (void)ttyoutput('\n', tp); 2003 2004 s = spltty(); 2005 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c)) 2006 ttyecho(c, tp); 2007 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c)) 2008 ttyecho(c, tp); 2009 CLR(tp->t_state, TS_ERASE); 2010 splx(s); 2011 2012 tp->t_rocount = tp->t_rawq.c_cc; 2013 tp->t_rocol = 0; 2014 } 2015 2016 /* 2017 * Echo a typed character to the terminal. 2018 */ 2019 static void 2020 ttyecho(int c, struct tty *tp) 2021 { 2022 2023 if (!ISSET(tp->t_state, TS_CNTTB)) 2024 CLR(tp->t_lflag, FLUSHO); 2025 if ((!ISSET(tp->t_lflag, ECHO) && 2026 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) || 2027 ISSET(tp->t_lflag, EXTPROC)) 2028 return; 2029 if (((ISSET(tp->t_lflag, ECHOCTL) && 2030 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) || 2031 ISSET(c, TTY_CHARMASK) == 0177)) { 2032 (void)ttyoutput('^', tp); 2033 CLR(c, ~TTY_CHARMASK); 2034 if (c == 0177) 2035 c = '?'; 2036 else 2037 c += 'A' - 1; 2038 } 2039 (void)ttyoutput(c, tp); 2040 } 2041 2042 /* 2043 * Wakeup any writers if necessary. 2044 */ 2045 void 2046 ttwakeupwr(struct tty *tp) 2047 { 2048 2049 if (tp->t_outq.c_cc <= tp->t_lowat) { 2050 if (ISSET(tp->t_state, TS_ASLEEP)) { 2051 CLR(tp->t_state, TS_ASLEEP); 2052 wakeup(&tp->t_outq); 2053 } 2054 selwakeup(&tp->t_wsel); 2055 } 2056 } 2057 2058 /* 2059 * Wake up any readers on a tty. 2060 */ 2061 void 2062 ttwakeup(struct tty *tp) 2063 { 2064 2065 selwakeup(&tp->t_rsel); 2066 if (ISSET(tp->t_state, TS_ASYNC)) 2067 pgsignal(tp->t_pgrp, SIGIO, 1); 2068 wakeup((caddr_t)&tp->t_rawq); 2069 } 2070 2071 /* 2072 * Look up a code for a specified speed in a conversion table; 2073 * used by drivers to map software speed values to hardware parameters. 2074 */ 2075 int 2076 ttspeedtab(int speed, const struct speedtab *table) 2077 { 2078 2079 for ( ; table->sp_speed != -1; table++) 2080 if (table->sp_speed == speed) 2081 return (table->sp_code); 2082 return (-1); 2083 } 2084 2085 /* 2086 * Set tty hi and low water marks. 2087 * 2088 * Try to arrange the dynamics so there's about one second 2089 * from hi to low water. 2090 */ 2091 void 2092 ttsetwater(struct tty *tp) 2093 { 2094 int cps, x, omost; 2095 2096 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 2097 2098 cps = tp->t_ospeed / 10; 2099 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 2100 x += cps; 2101 omost = MIN(tp->t_outq.c_cn - 200, tp->t_outq.c_cn); 2102 tp->t_hiwat = CLAMP(x, omost, 100); 2103 #undef CLAMP 2104 } 2105 2106 /* 2107 * Get the total estcpu for a process, summing across threads. 2108 * Returns true if at least one thread is runnable/running. 2109 */ 2110 static int 2111 process_sum(struct process *pr, fixpt_t *estcpup) 2112 { 2113 struct proc *p; 2114 fixpt_t estcpu; 2115 int ret; 2116 2117 ret = 0; 2118 estcpu = 0; 2119 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 2120 if (p->p_stat == SRUN || p->p_stat == SONPROC) 2121 ret = 1; 2122 estcpu += p->p_pctcpu; 2123 } 2124 2125 *estcpup = estcpu; 2126 return (ret); 2127 } 2128 2129 /* 2130 * Report on state of foreground process group. 2131 */ 2132 void 2133 ttyinfo(struct tty *tp) 2134 { 2135 struct process *pr, *pickpr; 2136 struct proc *p, *pick; 2137 struct timespec utime, stime; 2138 int tmp; 2139 2140 if (ttycheckoutq(tp,0) == 0) 2141 return; 2142 2143 /* Print load average. */ 2144 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 2145 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 2146 2147 if (tp->t_session == NULL) 2148 ttyprintf(tp, "not a controlling terminal\n"); 2149 else if (tp->t_pgrp == NULL) 2150 ttyprintf(tp, "no foreground process group\n"); 2151 else if ((pr = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL) 2152 empty: ttyprintf(tp, "empty foreground process group\n"); 2153 else { 2154 const char *state; 2155 fixpt_t pctcpu, pctcpu2; 2156 int run, run2; 2157 int calc_pctcpu; 2158 long rss; 2159 2160 /* 2161 * Pick the most active process: 2162 * - prefer at least one running/runnable thread 2163 * - prefer higher total pctcpu 2164 * - prefer non-zombie 2165 * Otherwise take the most recently added to this process group 2166 */ 2167 pickpr = pr; 2168 run = process_sum(pickpr, &pctcpu); 2169 while ((pr = LIST_NEXT(pr, ps_pglist)) != NULL) { 2170 run2 = process_sum(pr, &pctcpu2); 2171 if (run) { 2172 /* 2173 * pick is running; is p running w/same or 2174 * more cpu? 2175 */ 2176 if (run2 && pctcpu2 >= pctcpu) 2177 goto update_pickpr; 2178 continue; 2179 } 2180 /* pick isn't running; is p running *or* w/more cpu? */ 2181 if (run2 || pctcpu2 > pctcpu) 2182 goto update_pickpr; 2183 2184 /* if p has less cpu or is zombie, then it's worse */ 2185 if (pctcpu2 < pctcpu || (pr->ps_flags & PS_ZOMBIE)) 2186 continue; 2187 update_pickpr: 2188 pickpr = pr; 2189 run = run2; 2190 pctcpu = pctcpu2; 2191 } 2192 2193 /* Calculate percentage cpu, resident set size. */ 2194 calc_pctcpu = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT; 2195 rss = (pickpr->ps_flags & (PS_EMBRYO | PS_ZOMBIE)) ? 0 : 2196 vm_resident_count(pickpr->ps_vmspace); 2197 2198 calctsru(&pickpr->ps_tu, &utime, &stime, NULL); 2199 2200 /* Round up and print user time. */ 2201 utime.tv_nsec += 5000000; 2202 if (utime.tv_nsec >= 1000000000) { 2203 utime.tv_sec += 1; 2204 utime.tv_nsec -= 1000000000; 2205 } 2206 2207 /* Round up and print system time. */ 2208 stime.tv_nsec += 5000000; 2209 if (stime.tv_nsec >= 1000000000) { 2210 stime.tv_sec += 1; 2211 stime.tv_nsec -= 1000000000; 2212 } 2213 2214 /* 2215 * Find the most active thread: 2216 * - prefer runnable 2217 * - prefer higher pctcpu 2218 * - prefer living 2219 * Otherwise take the newest thread 2220 */ 2221 pick = p = TAILQ_FIRST(&pickpr->ps_threads); 2222 if (p == NULL) 2223 goto empty; 2224 run = p->p_stat == SRUN || p->p_stat == SONPROC; 2225 pctcpu = p->p_pctcpu; 2226 while ((p = TAILQ_NEXT(p, p_thr_link)) != NULL) { 2227 run2 = p->p_stat == SRUN || p->p_stat == SONPROC; 2228 pctcpu2 = p->p_pctcpu; 2229 if (run) { 2230 /* 2231 * pick is running; is p running w/same or 2232 * more cpu? 2233 */ 2234 if (run2 && pctcpu2 >= pctcpu) 2235 goto update_pick; 2236 continue; 2237 } 2238 /* pick isn't running; is p running *or* w/more cpu? */ 2239 if (run2 || pctcpu2 > pctcpu) 2240 goto update_pick; 2241 2242 /* if p has less cpu or is exiting, then it's worse */ 2243 if (pctcpu2 < pctcpu || p->p_flag & P_WEXIT) 2244 continue; 2245 update_pick: 2246 pick = p; 2247 run = run2; 2248 pctcpu = p->p_pctcpu; 2249 } 2250 state = pick->p_stat == SONPROC ? "running" : 2251 pick->p_stat == SRUN ? "runnable" : 2252 pick->p_wmesg ? pick->p_wmesg : "iowait"; 2253 2254 ttyprintf(tp, 2255 " cmd: %s %d [%s] %lld.%02ldu %lld.%02lds %d%% %ldk\n", 2256 pick->p_comm, pickpr->ps_pid, state, 2257 (long long)utime.tv_sec, utime.tv_nsec / 10000000, 2258 (long long)stime.tv_sec, stime.tv_nsec / 10000000, 2259 calc_pctcpu / 100, rss); 2260 } 2261 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2262 } 2263 2264 /* 2265 * Output char to tty; console putchar style. 2266 */ 2267 int 2268 tputchar(int c, struct tty *tp) 2269 { 2270 int s; 2271 2272 s = spltty(); 2273 if (ISSET(tp->t_state, TS_ISOPEN) == 0 || 2274 !(ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))) { 2275 splx(s); 2276 return (-1); 2277 } 2278 if (c == '\n') 2279 (void)ttyoutput('\r', tp); 2280 (void)ttyoutput(c, tp); 2281 ttstart(tp); 2282 splx(s); 2283 return (0); 2284 } 2285 2286 /* 2287 * Sleep on chan, returning ERESTART if tty changed while we napped and 2288 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 2289 * the tty is revoked, restarting a pending call will redo validation done 2290 * at the start of the call. 2291 */ 2292 int 2293 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo) 2294 { 2295 int error; 2296 short gen; 2297 2298 gen = tp->t_gen; 2299 if ((error = tsleep(chan, pri, wmesg, timo)) != 0) 2300 return (error); 2301 return (tp->t_gen == gen ? 0 : ERESTART); 2302 } 2303 2304 /* 2305 * Initialise the global tty list. 2306 */ 2307 void 2308 tty_init(void) 2309 { 2310 2311 TAILQ_INIT(&ttylist); 2312 tty_count = 0; 2313 } 2314 2315 /* 2316 * Allocate a tty structure and its associated buffers, and attach it to the 2317 * tty list. 2318 */ 2319 struct tty * 2320 ttymalloc(int baud) 2321 { 2322 struct tty *tp; 2323 2324 tp = malloc(sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO); 2325 2326 if (baud <= 115200) 2327 tp->t_qlen = 1024; 2328 else 2329 tp->t_qlen = 8192; 2330 clalloc(&tp->t_rawq, tp->t_qlen, 1); 2331 clalloc(&tp->t_canq, tp->t_qlen, 1); 2332 /* output queue doesn't need quoting */ 2333 clalloc(&tp->t_outq, tp->t_qlen, 0); 2334 2335 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link); 2336 ++tty_count; 2337 timeout_set(&tp->t_rstrt_to, ttrstrt, tp); 2338 2339 return(tp); 2340 } 2341 2342 2343 /* 2344 * Free a tty structure and its buffers, after removing it from the tty list. 2345 */ 2346 void 2347 ttyfree(struct tty *tp) 2348 { 2349 2350 --tty_count; 2351 #ifdef DIAGNOSTIC 2352 if (tty_count < 0) 2353 panic("ttyfree: tty_count < 0"); 2354 #endif 2355 TAILQ_REMOVE(&ttylist, tp, tty_link); 2356 2357 ttkqflush(&tp->t_rsel.si_note); 2358 ttkqflush(&tp->t_wsel.si_note); 2359 2360 clfree(&tp->t_rawq); 2361 clfree(&tp->t_canq); 2362 clfree(&tp->t_outq); 2363 free(tp, M_TTYS, 0); 2364 } 2365 2366 void 2367 ttystats_init(struct itty **ttystats) 2368 { 2369 struct itty *itp; 2370 struct tty *tp; 2371 2372 *ttystats = mallocarray(tty_count, sizeof(struct itty), 2373 M_SYSCTL, M_WAITOK|M_ZERO); 2374 for (tp = TAILQ_FIRST(&ttylist), itp = *ttystats; tp; 2375 tp = TAILQ_NEXT(tp, tty_link), itp++) { 2376 itp->t_dev = tp->t_dev; 2377 itp->t_rawq_c_cc = tp->t_rawq.c_cc; 2378 itp->t_canq_c_cc = tp->t_canq.c_cc; 2379 itp->t_outq_c_cc = tp->t_outq.c_cc; 2380 itp->t_hiwat = tp->t_hiwat; 2381 itp->t_lowat = tp->t_lowat; 2382 itp->t_column = tp->t_column; 2383 itp->t_state = tp->t_state; 2384 itp->t_session = tp->t_session; 2385 if (tp->t_pgrp) 2386 itp->t_pgrp_pg_id = tp->t_pgrp->pg_id; 2387 else 2388 itp->t_pgrp_pg_id = 0; 2389 itp->t_line = tp->t_line; 2390 } 2391 } 2392 2393 /* 2394 * Return tty-related information. 2395 */ 2396 int 2397 sysctl_tty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 2398 size_t newlen) 2399 { 2400 int err; 2401 2402 if (namelen != 1) 2403 return (ENOTDIR); 2404 2405 switch (name[0]) { 2406 case KERN_TTY_TKNIN: 2407 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nin)); 2408 case KERN_TTY_TKNOUT: 2409 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nout)); 2410 case KERN_TTY_TKRAWCC: 2411 return (sysctl_rdquad(oldp, oldlenp, newp, tk_rawcc)); 2412 case KERN_TTY_TKCANCC: 2413 return (sysctl_rdquad(oldp, oldlenp, newp, tk_cancc)); 2414 case KERN_TTY_INFO: 2415 { 2416 struct itty *ttystats; 2417 2418 ttystats_init(&ttystats); 2419 err = sysctl_rdstruct(oldp, oldlenp, newp, ttystats, 2420 tty_count * sizeof(struct itty)); 2421 free(ttystats, M_SYSCTL, 0); 2422 return (err); 2423 } 2424 default: 2425 #if NPTY > 0 2426 return (sysctl_pty(name, namelen, oldp, oldlenp, newp, newlen)); 2427 #else 2428 return (EOPNOTSUPP); 2429 #endif 2430 } 2431 /* NOTREACHED */ 2432 } 2433 2434 void 2435 ttytstamp(struct tty *tp, int octs, int ncts, int odcd, int ndcd) 2436 { 2437 int doit = 0; 2438 2439 if (ncts ^ octs) 2440 doit |= ncts ? ISSET(tp->t_flags, TS_TSTAMPCTSSET) : 2441 ISSET(tp->t_flags, TS_TSTAMPCTSCLR); 2442 if (ndcd ^ odcd) 2443 doit |= ndcd ? ISSET(tp->t_flags, TS_TSTAMPDCDSET) : 2444 ISSET(tp->t_flags, TS_TSTAMPDCDCLR); 2445 2446 if (doit) 2447 microtime(&tp->t_tv); 2448 } 2449