tty.c revision 6331
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.21 1995/02/09 11:13:30 jkh 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 some output still there, kill it */ 1009 if (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) 1010 ttyflush(tp, FWRITE); 1011 splx(s); 1012 return (error); 1013} 1014 1015/* 1016 * Flush after waiting. 1017 */ 1018int 1019ttywflush(tp) 1020 struct tty *tp; 1021{ 1022 int error; 1023 1024 error = ttywait(tp); 1025 ttyflush(tp, FREAD); 1026 return (error); 1027} 1028 1029/* 1030 * Flush tty read and/or write queues, notifying anyone waiting. 1031 */ 1032void 1033ttyflush(tp, rw) 1034 register struct tty *tp; 1035 int rw; 1036{ 1037 register int s; 1038 1039 s = spltty(); 1040 if (rw & FWRITE) 1041 CLR(tp->t_state, TS_TTSTOP); 1042#ifdef sun4c /* XXX */ 1043 (*tp->t_stop)(tp, rw); 1044#else 1045 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 1046#endif 1047 if (rw & FREAD) { 1048 FLUSHQ(&tp->t_canq); 1049 FLUSHQ(&tp->t_rawq); 1050 tp->t_rocount = 0; 1051 tp->t_rocol = 0; 1052 CLR(tp->t_state, TS_LOCAL); 1053 ttwakeup(tp); 1054 } 1055 if (rw & FWRITE) { 1056 FLUSHQ(&tp->t_outq); 1057 wakeup((caddr_t)&tp->t_outq); 1058 selwakeup(&tp->t_wsel); 1059 } 1060 splx(s); 1061} 1062 1063/* 1064 * Copy in the default termios characters. 1065 */ 1066void 1067ttychars(tp) 1068 struct tty *tp; 1069{ 1070 1071 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 1072} 1073 1074/* 1075 * Send stop character on input overflow. 1076 */ 1077static void 1078ttyblock(tp) 1079 register struct tty *tp; 1080{ 1081 register int total; 1082 1083 total = tp->t_rawq.c_cc + tp->t_canq.c_cc; 1084 if (tp->t_rawq.c_cc > TTYHOG) { 1085 ttyflush(tp, FREAD | FWRITE); 1086 CLR(tp->t_state, TS_TBLOCK); 1087 } 1088 /* 1089 * Block further input iff: current input > threshold 1090 * AND input is available to user program. 1091 */ 1092 if ((total >= TTYHOG / 2 && 1093 !ISSET(tp->t_state, TS_TBLOCK) && 1094 !ISSET(tp->t_lflag, ICANON)) || (tp->t_canq.c_cc > 0 && 1095 tp->t_cc[VSTOP] != _POSIX_VDISABLE)) { 1096 if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) { 1097 SET(tp->t_state, TS_TBLOCK); 1098 ttstart(tp); 1099 } 1100 } 1101} 1102 1103void 1104ttrstrt(tp_arg) 1105 void *tp_arg; 1106{ 1107 struct tty *tp; 1108 int s; 1109 1110#ifdef DIAGNOSTIC 1111 if (tp_arg == NULL) 1112 panic("ttrstrt"); 1113#endif 1114 tp = tp_arg; 1115 s = spltty(); 1116 1117 CLR(tp->t_state, TS_TIMEOUT); 1118 ttstart(tp); 1119 1120 splx(s); 1121} 1122 1123int 1124ttstart(tp) 1125 struct tty *tp; 1126{ 1127 1128 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1129 (*tp->t_oproc)(tp); 1130 return (0); 1131} 1132 1133/* 1134 * "close" a line discipline 1135 */ 1136int 1137ttylclose(tp, flag) 1138 struct tty *tp; 1139 int flag; 1140{ 1141 1142 if (flag & IO_NDELAY) 1143 ttyflush(tp, FREAD | FWRITE); 1144 else 1145 ttywflush(tp); 1146 return (0); 1147} 1148 1149/* 1150 * Handle modem control transition on a tty. 1151 * Flag indicates new state of carrier. 1152 * Returns 0 if the line should be turned off, otherwise 1. 1153 */ 1154int 1155ttymodem(tp, flag) 1156 register struct tty *tp; 1157 int flag; 1158{ 1159 1160 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) { 1161 /* 1162 * MDMBUF: do flow control according to carrier flag 1163 */ 1164 if (flag) { 1165 CLR(tp->t_state, TS_TTSTOP); 1166 ttstart(tp); 1167 } else if (!ISSET(tp->t_state, TS_TTSTOP)) { 1168 SET(tp->t_state, TS_TTSTOP); 1169#ifdef sun4c /* XXX */ 1170 (*tp->t_stop)(tp, 0); 1171#else 1172 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 1173#endif 1174 } 1175 } else if (flag == 0) { 1176 /* 1177 * Lost carrier. 1178 */ 1179 CLR(tp->t_state, TS_CARR_ON); 1180 if (ISSET(tp->t_state, TS_ISOPEN) && 1181 !ISSET(tp->t_cflag, CLOCAL)) { 1182 if (tp->t_session && tp->t_session->s_leader) 1183 psignal(tp->t_session->s_leader, SIGHUP); 1184 ttyflush(tp, FREAD | FWRITE); 1185 return (0); 1186 } 1187 } else { 1188 /* 1189 * Carrier now on. 1190 */ 1191 SET(tp->t_state, TS_CARR_ON); 1192 ttwakeup(tp); 1193 } 1194 return (1); 1195} 1196 1197/* 1198 * Default modem control routine (for other line disciplines). 1199 * Return argument flag, to turn off device on carrier drop. 1200 */ 1201int 1202nullmodem(tp, flag) 1203 register struct tty *tp; 1204 int flag; 1205{ 1206 1207 if (flag) 1208 SET(tp->t_state, TS_CARR_ON); 1209 else { 1210 CLR(tp->t_state, TS_CARR_ON); 1211 if (!ISSET(tp->t_cflag, CLOCAL)) { 1212 if (tp->t_session && tp->t_session->s_leader) 1213 psignal(tp->t_session->s_leader, SIGHUP); 1214 return (0); 1215 } 1216 } 1217 return (1); 1218} 1219 1220/* 1221 * Reinput pending characters after state switch 1222 * call at spltty(). 1223 */ 1224void 1225ttypend(tp) 1226 register struct tty *tp; 1227{ 1228 struct clist tq; 1229 register c; 1230 1231 CLR(tp->t_lflag, PENDIN); 1232 SET(tp->t_state, TS_TYPEN); 1233 /* 1234 * XXX this assumes too much about clist internals. It may even 1235 * fail if the cblock slush pool is empty. We can't allocate more 1236 * cblocks here because we are called from an interrupt handler 1237 * and clist_alloc_cblocks() can wait. 1238 */ 1239 tq = tp->t_rawq; 1240 bzero(&tp->t_rawq, sizeof tp->t_rawq); 1241 tp->t_rawq.c_cbmax = tq.c_cbmax; 1242 tp->t_rawq.c_cbreserved = tq.c_cbreserved; 1243 while ((c = getc(&tq)) >= 0) 1244 ttyinput(c, tp); 1245 CLR(tp->t_state, TS_TYPEN); 1246} 1247 1248/* 1249 * Process a read call on a tty device. 1250 */ 1251int 1252ttread(tp, uio, flag) 1253 register struct tty *tp; 1254 struct uio *uio; 1255 int flag; 1256{ 1257 register struct clist *qp; 1258 register int c; 1259 register tcflag_t lflag; 1260 register cc_t *cc = tp->t_cc; 1261 register struct proc *p = curproc; 1262 int s, first, error = 0, carrier; 1263 int has_stime = 0, last_cc = 0; 1264 long slp = 0; /* XXX this should be renamed `timo'. */ 1265 1266loop: 1267 s = spltty(); 1268 lflag = tp->t_lflag; 1269 /* 1270 * take pending input first 1271 */ 1272 if (ISSET(lflag, PENDIN)) { 1273 ttypend(tp); 1274 splx(s); /* reduce latency */ 1275 s = spltty(); 1276 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1277 } 1278 1279 /* 1280 * Hang process if it's in the background. 1281 */ 1282 if (isbackground(p, tp)) { 1283 splx(s); 1284 if ((p->p_sigignore & sigmask(SIGTTIN)) || 1285 (p->p_sigmask & sigmask(SIGTTIN)) || 1286 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) 1287 return (EIO); 1288 pgsignal(p->p_pgrp, SIGTTIN, 1); 1289 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1290 if (error) 1291 return (error); 1292 goto loop; 1293 } 1294 1295 /* 1296 * If canonical, use the canonical queue, 1297 * else use the raw queue. 1298 * 1299 * (should get rid of clists...) 1300 */ 1301 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq; 1302 1303 if (flag & IO_NDELAY) { 1304 if (qp->c_cc > 0) 1305 goto read; 1306 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1307 ISSET(tp->t_cflag, CLOCAL); 1308 if ((!carrier && ISSET(tp->t_state, TS_ISOPEN)) || 1309 !ISSET(lflag, ICANON) && cc[VMIN] == 0) { 1310 splx(s); 1311 return (0); 1312 } 1313 splx(s); 1314 return (EWOULDBLOCK); 1315 } 1316 if (!ISSET(lflag, ICANON)) { 1317 int m = cc[VMIN]; 1318 long t = cc[VTIME]; 1319 struct timeval stime, timecopy; 1320 int x; 1321 1322 /* 1323 * Check each of the four combinations. 1324 * (m > 0 && t == 0) is the normal read case. 1325 * It should be fairly efficient, so we check that and its 1326 * companion case (m == 0 && t == 0) first. 1327 * For the other two cases, we compute the target sleep time 1328 * into slp. 1329 */ 1330 if (t == 0) { 1331 if (qp->c_cc < m) 1332 goto sleep; 1333 if (qp->c_cc > 0) 1334 goto read; 1335 1336 /* m, t and qp->c_cc are all 0. 0 is enough input. */ 1337 splx(s); 1338 return (0); 1339 } 1340 t *= 100000; /* time in us */ 1341#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \ 1342 ((t1).tv_usec - (t2).tv_usec)) 1343 if (m > 0) { 1344 if (qp->c_cc <= 0) 1345 goto sleep; 1346 if (qp->c_cc >= m) 1347 goto read; 1348 x = splclock(); 1349 timecopy = time; 1350 splx(x); 1351 if (!has_stime) { 1352 /* first character, start timer */ 1353 has_stime = 1; 1354 stime = timecopy; 1355 slp = t; 1356 } else if (qp->c_cc > last_cc) { 1357 /* got a character, restart timer */ 1358 stime = timecopy; 1359 slp = t; 1360 } else { 1361 /* nothing, check expiration */ 1362 slp = t - diff(timecopy, stime); 1363 if (slp <= 0) 1364 goto read; 1365 } 1366 last_cc = qp->c_cc; 1367 } else { /* m == 0 */ 1368 if (qp->c_cc > 0) 1369 goto read; 1370 x = splclock(); 1371 timecopy = time; 1372 splx(x); 1373 if (!has_stime) { 1374 has_stime = 1; 1375 stime = timecopy; 1376 slp = t; 1377 } else { 1378 slp = t - diff(timecopy, stime); 1379 if (slp <= 0) { 1380 /* Timed out, but 0 is enough input. */ 1381 splx(s); 1382 return (0); 1383 } 1384 } 1385 } 1386#undef diff 1387 /* 1388 * Rounding down may make us wake up just short 1389 * of the target, so we round up. 1390 * The formula is ceiling(slp * hz/1000000). 1391 * 32-bit arithmetic is enough for hz < 169. 1392 * XXX see hzto() for how to avoid overflow if hz 1393 * is large (divide by `tick' and/or arrange to 1394 * use hzto() if hz is large). 1395 */ 1396 slp = (long) (((u_long)slp * hz) + 999999) / 1000000; 1397 goto sleep; 1398 } 1399 1400 /* 1401 * If there is no input, sleep on rawq 1402 * awaiting hardware receipt and notification. 1403 * If we have data, we don't need to check for carrier. 1404 */ 1405 if (qp->c_cc <= 0) { 1406sleep: 1407 carrier = ISSET(tp->t_state, TS_CARR_ON) || 1408 ISSET(tp->t_cflag, CLOCAL); 1409 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) { 1410 splx(s); 1411 return (0); /* EOF */ 1412 } 1413 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 1414 carrier ? ttyin : ttopen, (int)slp); 1415 splx(s); 1416 if (error == EWOULDBLOCK) 1417 error = 0; 1418 else if (error) 1419 return (error); 1420 /* 1421 * XXX what happens if another process eats some input 1422 * while we are asleep (not just here)? It would be 1423 * safest to detect changes and reset our state variables 1424 * (has_stime and last_cc). 1425 */ 1426 slp = 0; 1427 goto loop; 1428 } 1429read: 1430 splx(s); 1431 /* 1432 * Input present, check for input mapping and processing. 1433 */ 1434 first = 1; 1435 while ((c = getc(qp)) >= 0) { 1436 /* 1437 * delayed suspend (^Y) 1438 */ 1439 if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) { 1440 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1441 if (first) { 1442 error = ttysleep(tp, 1443 &lbolt, TTIPRI | PCATCH, ttybg, 0); 1444 if (error) 1445 break; 1446 goto loop; 1447 } 1448 break; 1449 } 1450 /* 1451 * Interpret EOF only in canonical mode. 1452 */ 1453 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1454 break; 1455 /* 1456 * Give user character. 1457 */ 1458 error = ureadc(c, uio); 1459 if (error) 1460 break; 1461 if (uio->uio_resid == 0) 1462 break; 1463 /* 1464 * In canonical mode check for a "break character" 1465 * marking the end of a "line of input". 1466 */ 1467 if (ISSET(lflag, ICANON) && TTBREAKC(c)) 1468 break; 1469 first = 0; 1470 } 1471 /* 1472 * Look to unblock output now that (presumably) 1473 * the input queue has gone down. 1474 */ 1475 s = spltty(); 1476 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { 1477 if (cc[VSTART] != _POSIX_VDISABLE && 1478 putc(cc[VSTART], &tp->t_outq) == 0) { 1479 CLR(tp->t_state, TS_TBLOCK); 1480 ttstart(tp); 1481 } 1482 } 1483 splx(s); 1484 return (error); 1485} 1486 1487/* 1488 * Check the output queue on tp for space for a kernel message (from uprintf 1489 * or tprintf). Allow some space over the normal hiwater mark so we don't 1490 * lose messages due to normal flow control, but don't let the tty run amok. 1491 * Sleeps here are not interruptible, but we return prematurely if new signals 1492 * arrive. 1493 */ 1494int 1495ttycheckoutq(tp, wait) 1496 register struct tty *tp; 1497 int wait; 1498{ 1499 int hiwat, s, oldsig; 1500 1501 hiwat = tp->t_hiwat; 1502 s = spltty(); 1503 oldsig = wait ? curproc->p_siglist : 0; 1504 if (tp->t_outq.c_cc > hiwat + 200) 1505 while (tp->t_outq.c_cc > hiwat) { 1506 ttstart(tp); 1507 if (wait == 0 || curproc->p_siglist != oldsig) { 1508 splx(s); 1509 return (0); 1510 } 1511 timeout((void (*)__P((void *)))wakeup, 1512 (void *)&tp->t_outq, hz); 1513 SET(tp->t_state, TS_ASLEEP); 1514 (void) tsleep((caddr_t)&tp->t_outq, PZERO - 1, "ttoutq", 0); 1515 } 1516 splx(s); 1517 return (1); 1518} 1519 1520/* 1521 * Process a write call on a tty device. 1522 */ 1523int 1524ttwrite(tp, uio, flag) 1525 register struct tty *tp; 1526 register struct uio *uio; 1527 int flag; 1528{ 1529 register char *cp = 0; 1530 register int cc, ce; 1531 register struct proc *p; 1532 int i, hiwat, cnt, error, s; 1533 char obuf[OBUFSIZ]; 1534 1535 hiwat = tp->t_hiwat; 1536 cnt = uio->uio_resid; 1537 error = 0; 1538 cc = 0; 1539loop: 1540 s = spltty(); 1541 if (!ISSET(tp->t_state, TS_CARR_ON) && 1542 !ISSET(tp->t_cflag, CLOCAL)) { 1543 if (ISSET(tp->t_state, TS_ISOPEN)) { 1544 splx(s); 1545 return (EIO); 1546 } else if (flag & IO_NDELAY) { 1547 splx(s); 1548 error = EWOULDBLOCK; 1549 goto out; 1550 } else { 1551 /* Sleep awaiting carrier. */ 1552 error = ttysleep(tp, 1553 &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0); 1554 splx(s); 1555 if (error) 1556 goto out; 1557 goto loop; 1558 } 1559 } 1560 splx(s); 1561 /* 1562 * Hang the process if it's in the background. 1563 */ 1564 p = curproc; 1565 if (isbackground(p, tp) && 1566 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 && 1567 (p->p_sigignore & sigmask(SIGTTOU)) == 0 && 1568 (p->p_sigmask & sigmask(SIGTTOU)) == 0 && 1569 p->p_pgrp->pg_jobc) { 1570 pgsignal(p->p_pgrp, SIGTTOU, 1); 1571 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0); 1572 if (error) 1573 goto out; 1574 goto loop; 1575 } 1576 /* 1577 * Process the user's data in at most OBUFSIZ chunks. Perform any 1578 * output translation. Keep track of high water mark, sleep on 1579 * overflow awaiting device aid in acquiring new space. 1580 */ 1581 while (uio->uio_resid > 0 || cc > 0) { 1582 if (ISSET(tp->t_lflag, FLUSHO)) { 1583 uio->uio_resid = 0; 1584 return (0); 1585 } 1586 if (tp->t_outq.c_cc > hiwat) 1587 goto ovhiwat; 1588 /* 1589 * Grab a hunk of data from the user, unless we have some 1590 * leftover from last time. 1591 */ 1592 if (cc == 0) { 1593 cc = min(uio->uio_resid, OBUFSIZ); 1594 cp = obuf; 1595 error = uiomove(cp, cc, uio); 1596 if (error) { 1597 cc = 0; 1598 break; 1599 } 1600 } 1601 /* 1602 * If nothing fancy need be done, grab those characters we 1603 * can handle without any of ttyoutput's processing and 1604 * just transfer them to the output q. For those chars 1605 * which require special processing (as indicated by the 1606 * bits in char_type), call ttyoutput. After processing 1607 * a hunk of data, look for FLUSHO so ^O's will take effect 1608 * immediately. 1609 */ 1610 while (cc > 0) { 1611 if (!ISSET(tp->t_oflag, OPOST)) 1612 ce = cc; 1613 else { 1614 ce = cc - scanc((u_int)cc, (u_char *)cp, 1615 (u_char *)char_type, CCLASSMASK); 1616 /* 1617 * If ce is zero, then we're processing 1618 * a special character through ttyoutput. 1619 */ 1620 if (ce == 0) { 1621 tp->t_rocount = 0; 1622 if (ttyoutput(*cp, tp) >= 0) { 1623 /* No Clists, wait a bit. */ 1624 ttstart(tp); 1625 if (flag & IO_NDELAY) { 1626 error = EWOULDBLOCK; 1627 goto out; 1628 } 1629 error = ttysleep(tp, &lbolt, 1630 TTOPRI | PCATCH, ttybuf, 0); 1631 if (error) 1632 goto out; 1633 goto loop; 1634 } 1635 cp++; 1636 cc--; 1637 if (ISSET(tp->t_lflag, FLUSHO) || 1638 tp->t_outq.c_cc > hiwat) 1639 goto ovhiwat; 1640 continue; 1641 } 1642 } 1643 /* 1644 * A bunch of normal characters have been found. 1645 * Transfer them en masse to the output queue and 1646 * continue processing at the top of the loop. 1647 * If there are any further characters in this 1648 * <= OBUFSIZ chunk, the first should be a character 1649 * requiring special handling by ttyoutput. 1650 */ 1651 tp->t_rocount = 0; 1652 i = b_to_q(cp, ce, &tp->t_outq); 1653 ce -= i; 1654 tp->t_column += ce; 1655 cp += ce, cc -= ce, tk_nout += ce; 1656 tp->t_outcc += ce; 1657 if (i > 0) { 1658 /* No Clists, wait a bit. */ 1659 ttstart(tp); 1660 if (flag & IO_NDELAY) { 1661 error = EWOULDBLOCK; 1662 goto out; 1663 } 1664 error = ttysleep(tp, 1665 &lbolt, TTOPRI | PCATCH, ttybuf, 0); 1666 if (error) 1667 goto out; 1668 goto loop; 1669 } 1670 if (ISSET(tp->t_lflag, FLUSHO) || 1671 tp->t_outq.c_cc > hiwat) 1672 break; 1673 } 1674 ttstart(tp); 1675 } 1676out: 1677 /* 1678 * If cc is nonzero, we leave the uio structure inconsistent, as the 1679 * offset and iov pointers have moved forward, but it doesn't matter 1680 * (the call will either return short or restart with a new uio). 1681 */ 1682 uio->uio_resid += cc; 1683 return (error); 1684 1685ovhiwat: 1686 ttstart(tp); 1687 s = spltty(); 1688 /* 1689 * This can only occur if FLUSHO is set in t_lflag, 1690 * or if ttstart/oproc is synchronous (or very fast). 1691 */ 1692 if (tp->t_outq.c_cc <= hiwat) { 1693 splx(s); 1694 goto loop; 1695 } 1696 if (flag & IO_NDELAY) { 1697 splx(s); 1698 uio->uio_resid += cc; 1699 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1700 } 1701 SET(tp->t_state, TS_ASLEEP); 1702 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0); 1703 splx(s); 1704 if (error) 1705 goto out; 1706 goto loop; 1707} 1708 1709/* 1710 * Rubout one character from the rawq of tp 1711 * as cleanly as possible. 1712 */ 1713void 1714ttyrub(c, tp) 1715 register int c; 1716 register struct tty *tp; 1717{ 1718 register char *cp; 1719 register int savecol; 1720 int tabc, s; 1721 1722 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 1723 return; 1724 CLR(tp->t_lflag, FLUSHO); 1725 if (ISSET(tp->t_lflag, ECHOE)) { 1726 if (tp->t_rocount == 0) { 1727 /* 1728 * Screwed by ttwrite; retype 1729 */ 1730 ttyretype(tp); 1731 return; 1732 } 1733 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 1734 ttyrubo(tp, 2); 1735 else { 1736 CLR(c, ~TTY_CHARMASK); 1737 switch (CCLASS(c)) { 1738 case ORDINARY: 1739 ttyrubo(tp, 1); 1740 break; 1741 case BACKSPACE: 1742 case CONTROL: 1743 case NEWLINE: 1744 case RETURN: 1745 case VTAB: 1746 if (ISSET(tp->t_lflag, ECHOCTL)) 1747 ttyrubo(tp, 2); 1748 break; 1749 case TAB: 1750 if (tp->t_rocount < tp->t_rawq.c_cc) { 1751 ttyretype(tp); 1752 return; 1753 } 1754 s = spltty(); 1755 savecol = tp->t_column; 1756 SET(tp->t_state, TS_CNTTB); 1757 SET(tp->t_lflag, FLUSHO); 1758 tp->t_column = tp->t_rocol; 1759 cp = tp->t_rawq.c_cf; 1760 if (cp) 1761 tabc = *cp; /* XXX FIX NEXTC */ 1762 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 1763 ttyecho(tabc, tp); 1764 CLR(tp->t_lflag, FLUSHO); 1765 CLR(tp->t_state, TS_CNTTB); 1766 splx(s); 1767 1768 /* savecol will now be length of the tab. */ 1769 savecol -= tp->t_column; 1770 tp->t_column += savecol; 1771 if (savecol > 8) 1772 savecol = 8; /* overflow screw */ 1773 while (--savecol >= 0) 1774 (void)ttyoutput('\b', tp); 1775 break; 1776 default: /* XXX */ 1777#define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 1778 (void)printf(PANICSTR, c, CCLASS(c)); 1779#ifdef notdef 1780 panic(PANICSTR, c, CCLASS(c)); 1781#endif 1782 } 1783 } 1784 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 1785 if (!ISSET(tp->t_state, TS_ERASE)) { 1786 SET(tp->t_state, TS_ERASE); 1787 (void)ttyoutput('\\', tp); 1788 } 1789 ttyecho(c, tp); 1790 } else 1791 ttyecho(tp->t_cc[VERASE], tp); 1792 --tp->t_rocount; 1793} 1794 1795/* 1796 * Back over cnt characters, erasing them. 1797 */ 1798static void 1799ttyrubo(tp, cnt) 1800 register struct tty *tp; 1801 int cnt; 1802{ 1803 1804 while (cnt-- > 0) { 1805 (void)ttyoutput('\b', tp); 1806 (void)ttyoutput(' ', tp); 1807 (void)ttyoutput('\b', tp); 1808 } 1809} 1810 1811/* 1812 * ttyretype -- 1813 * Reprint the rawq line. Note, it is assumed that c_cc has already 1814 * been checked. 1815 */ 1816void 1817ttyretype(tp) 1818 register struct tty *tp; 1819{ 1820 register char *cp; 1821 int s, c; 1822 1823 /* Echo the reprint character. */ 1824 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 1825 ttyecho(tp->t_cc[VREPRINT], tp); 1826 1827 (void)ttyoutput('\n', tp); 1828 1829 /* 1830 * XXX 1831 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 1832 * BIT OF FIRST CHAR. 1833 */ 1834 s = spltty(); 1835 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 1836 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 1837 ttyecho(c, tp); 1838 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 1839 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 1840 ttyecho(c, tp); 1841 CLR(tp->t_state, TS_ERASE); 1842 splx(s); 1843 1844 tp->t_rocount = tp->t_rawq.c_cc; 1845 tp->t_rocol = 0; 1846} 1847 1848/* 1849 * Echo a typed character to the terminal. 1850 */ 1851static void 1852ttyecho(c, tp) 1853 register int c; 1854 register struct tty *tp; 1855{ 1856 1857 if (!ISSET(tp->t_state, TS_CNTTB)) 1858 CLR(tp->t_lflag, FLUSHO); 1859 if ((!ISSET(tp->t_lflag, ECHO) && 1860 (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) || 1861 ISSET(tp->t_lflag, EXTPROC)) 1862 return; 1863 if (ISSET(tp->t_lflag, ECHOCTL) && 1864 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') || 1865 ISSET(c, TTY_CHARMASK) == 0177)) { 1866 (void)ttyoutput('^', tp); 1867 CLR(c, ~TTY_CHARMASK); 1868 if (c == 0177) 1869 c = '?'; 1870 else 1871 c += 'A' - 1; 1872 } 1873 (void)ttyoutput(c, tp); 1874} 1875 1876/* 1877 * Wake up any readers on a tty. 1878 */ 1879void 1880ttwakeup(tp) 1881 register struct tty *tp; 1882{ 1883 1884 selwakeup(&tp->t_rsel); 1885 if (ISSET(tp->t_state, TS_ASYNC)) 1886 pgsignal(tp->t_pgrp, SIGIO, 1); 1887 wakeup((caddr_t)&tp->t_rawq); 1888} 1889 1890/* 1891 * Look up a code for a specified speed in a conversion table; 1892 * used by drivers to map software speed values to hardware parameters. 1893 */ 1894int 1895ttspeedtab(speed, table) 1896 int speed; 1897 register struct speedtab *table; 1898{ 1899 1900 for ( ; table->sp_speed != -1; table++) 1901 if (table->sp_speed == speed) 1902 return (table->sp_code); 1903 return (-1); 1904} 1905 1906/* 1907 * Set tty hi and low water marks. 1908 * 1909 * Try to arrange the dynamics so there's about one second 1910 * from hi to low water. 1911 * 1912 */ 1913void 1914ttsetwater(tp) 1915 struct tty *tp; 1916{ 1917 register int cps, x; 1918 1919#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 1920 1921 cps = tp->t_ospeed / 10; 1922 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 1923 x += cps; 1924 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 1925 tp->t_hiwat = roundup(x, CBSIZE); 1926#undef CLAMP 1927} 1928 1929/* 1930 * Report on state of foreground process group. 1931 */ 1932void 1933ttyinfo(tp) 1934 register struct tty *tp; 1935{ 1936 register struct proc *p, *pick; 1937 struct timeval utime, stime; 1938 int tmp; 1939 1940 if (ttycheckoutq(tp,0) == 0) 1941 return; 1942 1943 /* Print load average. */ 1944 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 1945 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 1946 1947 if (tp->t_session == NULL) 1948 ttyprintf(tp, "not a controlling terminal\n"); 1949 else if (tp->t_pgrp == NULL) 1950 ttyprintf(tp, "no foreground process group\n"); 1951 else if ((p = tp->t_pgrp->pg_mem) == NULL) 1952 ttyprintf(tp, "empty foreground process group\n"); 1953 else { 1954 /* Pick interesting process. */ 1955 for (pick = NULL; p != NULL; p = p->p_pgrpnxt) 1956 if (proc_compare(pick, p)) 1957 pick = p; 1958 1959 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 1960 pick->p_stat == SRUN ? "running" : 1961 pick->p_wmesg ? pick->p_wmesg : "iowait"); 1962 1963 calcru(pick, &utime, &stime, NULL); 1964 1965 /* Print user time. */ 1966 ttyprintf(tp, "%d.%02du ", 1967 utime.tv_sec, utime.tv_usec / 10000); 1968 1969 /* Print system time. */ 1970 ttyprintf(tp, "%d.%02ds ", 1971 stime.tv_sec, stime.tv_usec / 10000); 1972 1973#define pgtok(a) (((a) * NBPG) / 1024) 1974 /* Print percentage cpu, resident set size. */ 1975 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT; 1976 ttyprintf(tp, "%d%% %dk\n", 1977 tmp / 100, 1978 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 : 1979#ifdef pmap_resident_count 1980 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap)) 1981#else 1982 pgtok(pick->p_vmspace->vm_rssize) 1983#endif 1984 ); 1985 } 1986 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 1987} 1988 1989/* 1990 * Returns 1 if p2 is "better" than p1 1991 * 1992 * The algorithm for picking the "interesting" process is thus: 1993 * 1994 * 1) Only foreground processes are eligible - implied. 1995 * 2) Runnable processes are favored over anything else. The runner 1996 * with the highest cpu utilization is picked (p_estcpu). Ties are 1997 * broken by picking the highest pid. 1998 * 3) The sleeper with the shortest sleep time is next. With ties, 1999 * we pick out just "short-term" sleepers (P_SINTR == 0). 2000 * 4) Further ties are broken by picking the highest pid. 2001 */ 2002#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 2003#define TESTAB(a, b) ((a)<<1 | (b)) 2004#define ONLYA 2 2005#define ONLYB 1 2006#define BOTH 3 2007 2008static int 2009proc_compare(p1, p2) 2010 register struct proc *p1, *p2; 2011{ 2012 2013 if (p1 == NULL) 2014 return (1); 2015 /* 2016 * see if at least one of them is runnable 2017 */ 2018 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 2019 case ONLYA: 2020 return (0); 2021 case ONLYB: 2022 return (1); 2023 case BOTH: 2024 /* 2025 * tie - favor one with highest recent cpu utilization 2026 */ 2027 if (p2->p_estcpu > p1->p_estcpu) 2028 return (1); 2029 if (p1->p_estcpu > p2->p_estcpu) 2030 return (0); 2031 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2032 } 2033 /* 2034 * weed out zombies 2035 */ 2036 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 2037 case ONLYA: 2038 return (1); 2039 case ONLYB: 2040 return (0); 2041 case BOTH: 2042 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2043 } 2044 /* 2045 * pick the one with the smallest sleep time 2046 */ 2047 if (p2->p_slptime > p1->p_slptime) 2048 return (0); 2049 if (p1->p_slptime > p2->p_slptime) 2050 return (1); 2051 /* 2052 * favor one sleeping in a non-interruptible sleep 2053 */ 2054 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 2055 return (1); 2056 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 2057 return (0); 2058 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2059} 2060 2061/* 2062 * Output char to tty; console putchar style. 2063 */ 2064int 2065tputchar(c, tp) 2066 int c; 2067 struct tty *tp; 2068{ 2069 register int s; 2070 2071 s = spltty(); 2072 if (ISSET(tp->t_state, 2073 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) { 2074 splx(s); 2075 return (-1); 2076 } 2077 if (c == '\n') 2078 (void)ttyoutput('\r', tp); 2079 (void)ttyoutput(c, tp); 2080 ttstart(tp); 2081 splx(s); 2082 return (0); 2083} 2084 2085/* 2086 * Sleep on chan, returning ERESTART if tty changed while we napped and 2087 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If 2088 * the tty is revoked, restarting a pending call will redo validation done 2089 * at the start of the call. 2090 */ 2091int 2092ttysleep(tp, chan, pri, wmesg, timo) 2093 struct tty *tp; 2094 void *chan; 2095 int pri, timo; 2096 char *wmesg; 2097{ 2098 int error; 2099 short gen; 2100 2101 gen = tp->t_gen; 2102 error = tsleep(chan, pri, wmesg, timo); 2103 if (error) 2104 return (error); 2105 return (tp->t_gen == gen ? 0 : ERESTART); 2106} 2107 2108/* 2109 * Allocate a tty structure and its associated buffers. 2110 */ 2111struct tty * 2112ttymalloc() 2113{ 2114 struct tty *tp; 2115 2116 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK); 2117 bzero(tp, sizeof *tp); 2118 2119 /* 2120 * Initialize or restore a cblock allocation policy suitable for 2121 * the standard line discipline. 2122 */ 2123 clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512); 2124 clist_alloc_cblocks(&tp->t_outq, TTMAXHIWAT + 200, 512); 2125 clist_alloc_cblocks(&tp->t_rawq, TTYHOG, 512); 2126 2127 return(tp); 2128} 2129 2130/* 2131 * Free a tty structure and its buffers. 2132 */ 2133void 2134ttyfree(tp) 2135struct tty *tp; 2136{ 2137 clist_free_cblocks(&tp->t_canq); 2138 clist_free_cblocks(&tp->t_outq); 2139 clist_free_cblocks(&tp->t_rawq); 2140 FREE(tp, M_TTYS); 2141} 2142 2143