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