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