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