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