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