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