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