tty.c revision 1809
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 if (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) { 1535 SET(tp->t_state, TS_ASLEEP); 1536 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1537 } 1538 splx(s); 1539 if (error) 1540 goto out; 1541 goto loop; 1542} 1543 1544/* 1545 * Rubout one character from the rawq of tp 1546 * as cleanly as possible. 1547 */ 1548void 1549ttyrub(c, tp) 1550 register int c; 1551 register struct tty *tp; 1552{ 1553 register char *cp; 1554 register int savecol; 1555 int tabc, s; 1556 1557 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1558 return; 1559 CLR(tp->t_lflag, FLUSHO); 1560 if (ISSET(tp->t_lflag, ECHOE)) { 1561 if (tp->t_rocount == 0) { 1562 /* 1563 * Screwed by ttwrite; retype 1564 */ 1565 ttyretype(tp); 1566 return; 1567 } 1568 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1569 ttyrubo(tp, 2); 1570 else { 1571 CLR(c, ~TTY_CHARMASK); 1572 switch (CCLASS(c)) { 1573 case ORDINARY: 1574 ttyrubo(tp, 1); 1575 break; 1576 case BACKSPACE: 1577 case CONTROL: 1578 case NEWLINE: 1579 case RETURN: 1580 case VTAB: 1581 if (ISSET(tp->t_lflag, ECHOCTL)) 1582 ttyrubo(tp, 2); 1583 break; 1584 case TAB: 1585 if (tp->t_rocount < tp->t_rawq.c_cc) { 1586 ttyretype(tp); 1587 return; 1588 } 1589 s = spltty(); 1590 savecol = tp->t_column; 1591 SET(tp->t_state, TS_CNTTB); 1592 SET(tp->t_lflag, FLUSHO); 1593 tp->t_column = tp->t_rocol; 1594 cp = tp->t_rawq.c_cf; 1595 if (cp) 1596 tabc = *cp; /* XXX FIX NEXTC */ 1597 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 1598 ttyecho(tabc, tp); 1599 CLR(tp->t_lflag, FLUSHO); 1600 CLR(tp->t_state, TS_CNTTB); 1601 splx(s); 1602 1603 /* savecol will now be length of the tab. */ 1604 savecol -= tp->t_column; 1605 tp->t_column += savecol; 1606 if (savecol > 8) 1607 savecol = 8; /* overflow screw */ 1608 while (--savecol >= 0) 1609 (void)ttyoutput('\b', tp); 1610 break; 1611 default: /* XXX */ 1612#define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1613 (void)printf(PANICSTR, c, CCLASS(c)); 1614#ifdef notdef 1615 panic(PANICSTR, c, CCLASS(c)); 1616#endif 1617 } 1618 } 1619 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1620 if (!ISSET(tp->t_state, TS_ERASE)) { 1621 SET(tp->t_state, TS_ERASE); 1622 (void)ttyoutput('\\', tp); 1623 } 1624 ttyecho(c, tp); 1625 } else 1626 ttyecho(tp->t_cc[VERASE], tp); 1627 --tp->t_rocount; 1628} 1629 1630/* 1631 * Back over cnt characters, erasing them. 1632 */ 1633static void 1634ttyrubo(tp, cnt) 1635 register struct tty *tp; 1636 int cnt; 1637{ 1638 1639 while (cnt-- > 0) { 1640 (void)ttyoutput('\b', tp); 1641 (void)ttyoutput(' ', tp); 1642 (void)ttyoutput('\b', tp); 1643 } 1644} 1645 1646/* 1647 * ttyretype -- 1648 * Reprint the rawq line. Note, it is assumed that c_cc has already 1649 * been checked. 1650 */ 1651void 1652ttyretype(tp) 1653 register struct tty *tp; 1654{ 1655 register char *cp; 1656 int s, c; 1657 1658 /* Echo the reprint character. */ 1659 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1660 ttyecho(tp->t_cc[VREPRINT], tp); 1661 1662 (void)ttyoutput('\n', tp); 1663 1664 /* 1665 * XXX 1666 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1667 * BIT OF FIRST CHAR. 1668 */ 1669 s = spltty(); 1670 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 1671 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 1672 ttyecho(c, tp); 1673 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 1674 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 1675 ttyecho(c, tp); 1676 CLR(tp->t_state, TS_ERASE); 1677 splx(s); 1678 1679 tp->t_rocount = tp->t_rawq.c_cc; 1680 tp->t_rocol = 0; 1681} 1682 1683/* 1684 * Echo a typed character to the terminal. 1685 */ 1686static void 1687ttyecho(c, tp) 1688 register int c; 1689 register struct tty *tp; 1690{ 1691 1692 if (!ISSET(tp->t_state, TS_CNTTB)) 1693 CLR(tp->t_lflag, FLUSHO); 1694 if ((!ISSET(tp->t_lflag, ECHO) && 1695 (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) || 1696 ISSET(tp->t_lflag, EXTPROC)) 1697 return; 1698 if (ISSET(tp->t_lflag, ECHOCTL) && 1699 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' || 1700 ISSET(c, TTY_CHARMASK) == 0177)) { 1701 (void)ttyoutput('^', tp); 1702 CLR(c, ~TTY_CHARMASK); 1703 if (c == 0177) 1704 c = '?'; 1705 else 1706 c += 'A' - 1; 1707 } 1708 (void)ttyoutput(c, tp); 1709} 1710 1711/* 1712 * Wake up any readers on a tty. 1713 */ 1714void 1715ttwakeup(tp) 1716 register struct tty *tp; 1717{ 1718 1719 selwakeup(&tp->t_rsel); 1720 if (ISSET(tp->t_state, TS_ASYNC)) 1721 pgsignal(tp->t_pgrp, SIGIO, 1); 1722 wakeup((caddr_t)&tp->t_rawq); 1723} 1724 1725/* 1726 * Look up a code for a specified speed in a conversion table; 1727 * used by drivers to map software speed values to hardware parameters. 1728 */ 1729int 1730ttspeedtab(speed, table) 1731 int speed; 1732 register struct speedtab *table; 1733{ 1734 1735 for ( ; table->sp_speed != -1; table++) 1736 if (table->sp_speed == speed) 1737 return (table->sp_code); 1738 return (-1); 1739} 1740 1741/* 1742 * Set tty hi and low water marks. 1743 * 1744 * Try to arrange the dynamics so there's about one second 1745 * from hi to low water. 1746 * 1747 */ 1748void 1749ttsetwater(tp) 1750 struct tty *tp; 1751{ 1752 register int cps, x; 1753 1754#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 1755 1756 cps = tp->t_ospeed / 10; 1757 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 1758 x += cps; 1759 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 1760 tp->t_hiwat = roundup(x, CBSIZE); 1761#undef CLAMP 1762} 1763 1764/* 1765 * Report on state of foreground process group. 1766 */ 1767void 1768ttyinfo(tp) 1769 register struct tty *tp; 1770{ 1771 register struct proc *p, *pick; 1772 struct timeval utime, stime; 1773 int tmp; 1774 1775 if (ttycheckoutq(tp,0) == 0) 1776 return; 1777 1778 /* Print load average. */ 1779 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 1780 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 1781 1782 if (tp->t_session == NULL) 1783 ttyprintf(tp, "not a controlling terminal\n"); 1784 else if (tp->t_pgrp == NULL) 1785 ttyprintf(tp, "no foreground process group\n"); 1786 else if ((p = tp->t_pgrp->pg_mem) == NULL) 1787 ttyprintf(tp, "empty foreground process group\n"); 1788 else { 1789 /* Pick interesting process. */ 1790 for (pick = NULL; p != NULL; p = p->p_pgrpnxt) 1791 if (proc_compare(pick, p)) 1792 pick = p; 1793 1794 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 1795 pick->p_stat == SRUN ? "running" : 1796 pick->p_wmesg ? pick->p_wmesg : "iowait"); 1797 1798 calcru(pick, &utime, &stime, NULL); 1799 1800 /* Print user time. */ 1801 ttyprintf(tp, "%d.%02du ", 1802 utime.tv_sec, (utime.tv_usec + 5000) / 10000); 1803 1804 /* Print system time. */ 1805 ttyprintf(tp, "%d.%02ds ", 1806 stime.tv_sec, (stime.tv_usec + 5000) / 10000); 1807 1808#define pgtok(a) (((a) * NBPG) / 1024) 1809 /* Print percentage cpu, resident set size. */ 1810 tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT; 1811 ttyprintf(tp, "%d%% %dk\n", 1812 tmp / 100, 1813 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 : 1814#ifdef pmap_resident_count 1815 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap)) 1816#else 1817 pgtok(pick->p_vmspace->vm_rssize) 1818#endif 1819 ); 1820 } 1821 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 1822} 1823 1824/* 1825 * Returns 1 if p2 is "better" than p1 1826 * 1827 * The algorithm for picking the "interesting" process is thus: 1828 * 1829 * 1) Only foreground processes are eligible - implied. 1830 * 2) Runnable processes are favored over anything else. The runner 1831 * with the highest cpu utilization is picked (p_estcpu). Ties are 1832 * broken by picking the highest pid. 1833 * 3) The sleeper with the shortest sleep time is next. With ties, 1834 * we pick out just "short-term" sleepers (P_SINTR == 0). 1835 * 4) Further ties are broken by picking the highest pid. 1836 */ 1837#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 1838#define TESTAB(a, b) ((a)<<1 | (b)) 1839#define ONLYA 2 1840#define ONLYB 1 1841#define BOTH 3 1842 1843static int 1844proc_compare(p1, p2) 1845 register struct proc *p1, *p2; 1846{ 1847 1848 if (p1 == NULL) 1849 return (1); 1850 /* 1851 * see if at least one of them is runnable 1852 */ 1853 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 1854 case ONLYA: 1855 return (0); 1856 case ONLYB: 1857 return (1); 1858 case BOTH: 1859 /* 1860 * tie - favor one with highest recent cpu utilization 1861 */ 1862 if (p2->p_estcpu > p1->p_estcpu) 1863 return (1); 1864 if (p1->p_estcpu > p2->p_estcpu) 1865 return (0); 1866 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1867 } 1868 /* 1869 * weed out zombies 1870 */ 1871 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 1872 case ONLYA: 1873 return (1); 1874 case ONLYB: 1875 return (0); 1876 case BOTH: 1877 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1878 } 1879 /* 1880 * pick the one with the smallest sleep time 1881 */ 1882 if (p2->p_slptime > p1->p_slptime) 1883 return (0); 1884 if (p1->p_slptime > p2->p_slptime) 1885 return (1); 1886 /* 1887 * favor one sleeping in a non-interruptible sleep 1888 */ 1889 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 1890 return (1); 1891 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 1892 return (0); 1893 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 1894} 1895 1896/* 1897 * Output char to tty; console putchar style. 1898 */ 1899int 1900tputchar(c, tp) 1901 int c; 1902 struct tty *tp; 1903{ 1904 register int s; 1905 1906 s = spltty(); 1907 if (ISSET(tp->t_state, 1908 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) { 1909 splx(s); 1910 return (-1); 1911 } 1912 if (c == '\n') 1913 (void)ttyoutput('\r', tp); 1914 (void)ttyoutput(c, tp); 1915 ttstart(tp); 1916 splx(s); 1917 return (0); 1918} 1919 1920/* 1921 * Sleep on chan, returning ERESTART if tty changed while we napped and 1922 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 1923 * the tty is revoked, restarting a pending call will redo validation done 1924 * at the start of the call. 1925 */ 1926int 1927ttysleep(tp, chan, pri, wmesg, timo) 1928 struct tty *tp; 1929 void *chan; 1930 int pri, timo; 1931 char *wmesg; 1932{ 1933 int error; 1934 short gen; 1935 1936 gen = tp->t_gen; 1937 if (error = tsleep(chan, pri, wmesg, timo)) 1938 return (error); 1939 return (tp->t_gen == gen ? 0 : ERESTART); 1940} 1941