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