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