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