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