1 /* tty.c 6.12 84/12/20 */ 2 3 #include "../machine/reg.h" 4 5 #include "param.h" 6 #include "systm.h" 7 #include "dir.h" 8 #include "user.h" 9 #include "ioctl.h" 10 #include "tty.h" 11 #include "proc.h" 12 #include "inode.h" 13 #include "file.h" 14 #include "conf.h" 15 #include "buf.h" 16 #include "dk.h" 17 #include "uio.h" 18 #include "kernel.h" 19 20 /* 21 * Table giving parity for characters and indicating 22 * character classes to tty driver. In particular, 23 * if the low 6 bits are 0, then the character needs 24 * no special processing on output. 25 */ 26 27 char partab[] = { 28 0001,0201,0201,0001,0201,0001,0001,0201, 29 0202,0004,0003,0201,0005,0206,0201,0001, 30 0201,0001,0001,0201,0001,0201,0201,0001, 31 0001,0201,0201,0001,0201,0001,0001,0201, 32 0200,0000,0000,0200,0000,0200,0200,0000, 33 0000,0200,0200,0000,0200,0000,0000,0200, 34 0000,0200,0200,0000,0200,0000,0000,0200, 35 0200,0000,0000,0200,0000,0200,0200,0000, 36 0200,0000,0000,0200,0000,0200,0200,0000, 37 0000,0200,0200,0000,0200,0000,0000,0200, 38 0000,0200,0200,0000,0200,0000,0000,0200, 39 0200,0000,0000,0200,0000,0200,0200,0000, 40 0000,0200,0200,0000,0200,0000,0000,0200, 41 0200,0000,0000,0200,0000,0200,0200,0000, 42 0200,0000,0000,0200,0000,0200,0200,0000, 43 0000,0200,0200,0000,0200,0000,0000,0201, 44 45 /* 46 * 7 bit ascii ends with the last character above, 47 * but we contine through all 256 codes for the sake 48 * of the tty output routines which use special vax 49 * instructions which need a 256 character trt table. 50 */ 51 52 0007,0007,0007,0007,0007,0007,0007,0007, 53 0007,0007,0007,0007,0007,0007,0007,0007, 54 0007,0007,0007,0007,0007,0007,0007,0007, 55 0007,0007,0007,0007,0007,0007,0007,0007, 56 0007,0007,0007,0007,0007,0007,0007,0007, 57 0007,0007,0007,0007,0007,0007,0007,0007, 58 0007,0007,0007,0007,0007,0007,0007,0007, 59 0007,0007,0007,0007,0007,0007,0007,0007, 60 0007,0007,0007,0007,0007,0007,0007,0007, 61 0007,0007,0007,0007,0007,0007,0007,0007, 62 0007,0007,0007,0007,0007,0007,0007,0007, 63 0007,0007,0007,0007,0007,0007,0007,0007, 64 0007,0007,0007,0007,0007,0007,0007,0007, 65 0007,0007,0007,0007,0007,0007,0007,0007, 66 0007,0007,0007,0007,0007,0007,0007,0007, 67 0007,0007,0007,0007,0007,0007,0007,0007 68 }; 69 70 /* 71 * Input mapping table-- if an entry is non-zero, when the 72 * corresponding character is typed preceded by "\" the escape 73 * sequence is replaced by the table value. Mostly used for 74 * upper-case only terminals. 75 */ 76 char maptab[] ={ 77 000,000,000,000,000,000,000,000, 78 000,000,000,000,000,000,000,000, 79 000,000,000,000,000,000,000,000, 80 000,000,000,000,000,000,000,000, 81 000,'|',000,000,000,000,000,'`', 82 '{','}',000,000,000,000,000,000, 83 000,000,000,000,000,000,000,000, 84 000,000,000,000,000,000,000,000, 85 000,000,000,000,000,000,000,000, 86 000,000,000,000,000,000,000,000, 87 000,000,000,000,000,000,000,000, 88 000,000,000,000,000,000,'~',000, 89 000,'A','B','C','D','E','F','G', 90 'H','I','J','K','L','M','N','O', 91 'P','Q','R','S','T','U','V','W', 92 'X','Y','Z',000,000,000,000,000, 93 }; 94 95 short tthiwat[16] = 96 { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 }; 97 short ttlowat[16] = 98 { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 }; 99 100 struct ttychars ttydefaults = { 101 CERASE, CKILL, CINTR, CQUIT, CSTART, CSTOP, CEOF, 102 CBRK, CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT 103 }; 104 105 ttychars(tp) 106 struct tty *tp; 107 { 108 109 tp->t_chars = ttydefaults; 110 } 111 112 /* 113 * Wait for output to drain, then flush input waiting. 114 */ 115 ttywflush(tp) 116 register struct tty *tp; 117 { 118 119 ttywait(tp); 120 ttyflush(tp, FREAD); 121 } 122 123 ttywait(tp) 124 register struct tty *tp; 125 { 126 register int s = spltty(); 127 128 while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) && 129 tp->t_state&TS_CARR_ON && tp->t_oproc) { /* kludge for pty */ 130 (*tp->t_oproc)(tp); 131 tp->t_state |= TS_ASLEEP; 132 sleep((caddr_t)&tp->t_outq, TTOPRI); 133 } 134 splx(s); 135 } 136 137 /* 138 * Flush all TTY queues 139 */ 140 ttyflush(tp, rw) 141 register struct tty *tp; 142 { 143 register s; 144 145 s = spltty(); 146 if (rw & FREAD) { 147 while (getc(&tp->t_canq) >= 0) 148 ; 149 wakeup((caddr_t)&tp->t_rawq); 150 } 151 if (rw & FWRITE) { 152 wakeup((caddr_t)&tp->t_outq); 153 tp->t_state &= ~TS_TTSTOP; 154 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 155 while (getc(&tp->t_outq) >= 0) 156 ; 157 } 158 if (rw & FREAD) { 159 while (getc(&tp->t_rawq) >= 0) 160 ; 161 tp->t_rocount = 0; 162 tp->t_rocol = 0; 163 tp->t_state &= ~TS_LOCAL; 164 } 165 splx(s); 166 } 167 168 /* 169 * Send stop character on input overflow. 170 */ 171 ttyblock(tp) 172 register struct tty *tp; 173 { 174 register x; 175 176 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 177 if (tp->t_rawq.c_cc > TTYHOG) { 178 ttyflush(tp, FREAD|FWRITE); 179 tp->t_state &= ~TS_TBLOCK; 180 } 181 /* 182 * Block further input iff: 183 * Current input > threshold AND input is available to user program 184 */ 185 if (x >= TTYHOG/2 && 186 ((tp->t_flags & (RAW|CBREAK)) || (tp->t_canq.c_cc > 0))) { 187 if (putc(tp->t_stopc, &tp->t_outq)==0) { 188 tp->t_state |= TS_TBLOCK; 189 ttstart(tp); 190 } 191 } 192 } 193 194 /* 195 * Restart typewriter output following a delay 196 * timeout. 197 * The name of the routine is passed to the timeout 198 * subroutine and it is called during a clock interrupt. 199 */ 200 ttrstrt(tp) 201 register struct tty *tp; 202 { 203 204 if (tp == 0) 205 panic("ttrstrt"); 206 tp->t_state &= ~TS_TIMEOUT; 207 ttstart(tp); 208 } 209 210 /* 211 * Start output on the typewriter. It is used from the top half 212 * after some characters have been put on the output queue, 213 * from the interrupt routine to transmit the next 214 * character, and after a timeout has finished. 215 */ 216 ttstart(tp) 217 register struct tty *tp; 218 { 219 register s; 220 221 s = spltty(); 222 if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 && 223 tp->t_oproc) /* kludge for pty */ 224 (*tp->t_oproc)(tp); 225 splx(s); 226 } 227 228 /* 229 * Common code for tty ioctls. 230 */ 231 /*ARGSUSED*/ 232 ttioctl(tp, com, data, flag) 233 register struct tty *tp; 234 caddr_t data; 235 { 236 int dev = tp->t_dev; 237 extern int nldisp; 238 int s; 239 register int newflags; 240 241 /* 242 * If the ioctl involves modification, 243 * hang if in the background. 244 */ 245 switch (com) { 246 247 case TIOCSETD: 248 case TIOCSETP: 249 case TIOCSETN: 250 case TIOCFLUSH: 251 case TIOCSETC: 252 case TIOCSLTC: 253 case TIOCSPGRP: 254 case TIOCLBIS: 255 case TIOCLBIC: 256 case TIOCLSET: 257 case TIOCSTI: 258 #define bit(a) (1<<(a-1)) 259 while (tp->t_line == NTTYDISC && 260 u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 261 (u.u_procp->p_flag&SVFORK) == 0 && 262 !(u.u_procp->p_sigignore & bit(SIGTTOU)) && 263 !(u.u_procp->p_sigmask & bit(SIGTTOU))) { 264 gsignal(u.u_procp->p_pgrp, SIGTTOU); 265 sleep((caddr_t)&lbolt, TTOPRI); 266 } 267 break; 268 } 269 #undef bit 270 271 /* 272 * Process the ioctl. 273 */ 274 switch (com) { 275 276 /* get discipline number */ 277 case TIOCGETD: 278 *(int *)data = tp->t_line; 279 break; 280 281 /* set line discipline */ 282 case TIOCSETD: { 283 register int t = *(int *)data; 284 int error = 0; 285 286 if ((unsigned) t >= nldisp) 287 return (ENXIO); 288 s = spltty(); 289 if (tp->t_line) 290 (*linesw[tp->t_line].l_close)(tp); 291 if (t) 292 error = (*linesw[t].l_open)(dev, tp); 293 splx(s); 294 if (error) { 295 s = spltty(); 296 if (tp->t_line) 297 (void) (*linesw[tp->t_line].l_open)(dev, tp); 298 splx(s); 299 return (error); 300 } 301 tp->t_line = t; 302 break; 303 } 304 305 /* prevent more opens on channel */ 306 case TIOCEXCL: 307 tp->t_state |= TS_XCLUDE; 308 break; 309 310 case TIOCNXCL: 311 tp->t_state &= ~TS_XCLUDE; 312 break; 313 314 /* hang up line on last close */ 315 case TIOCHPCL: 316 tp->t_state |= TS_HUPCLS; 317 break; 318 319 case TIOCFLUSH: { 320 register int flags = *(int *)data; 321 322 if (flags == 0) 323 flags = FREAD|FWRITE; 324 else 325 flags &= FREAD|FWRITE; 326 ttyflush(tp, flags); 327 break; 328 } 329 330 /* return number of characters immediately available */ 331 case FIONREAD: 332 *(off_t *)data = ttnread(tp); 333 break; 334 335 case TIOCOUTQ: 336 *(int *)data = tp->t_outq.c_cc; 337 break; 338 339 case TIOCSTOP: 340 s = spltty(); 341 if ((tp->t_state&TS_TTSTOP) == 0) { 342 tp->t_state |= TS_TTSTOP; 343 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 344 } 345 splx(s); 346 break; 347 348 case TIOCSTART: 349 s = spltty(); 350 if ((tp->t_state&TS_TTSTOP) || (tp->t_flags&FLUSHO)) { 351 tp->t_state &= ~TS_TTSTOP; 352 tp->t_flags &= ~FLUSHO; 353 ttstart(tp); 354 } 355 splx(s); 356 break; 357 358 /* 359 * Simulate typing of a character at the terminal. 360 */ 361 case TIOCSTI: 362 if (u.u_uid && (flag & FREAD) == 0) 363 return (EPERM); 364 if (u.u_uid && u.u_ttyp != tp) 365 return (EACCES); 366 (*linesw[tp->t_line].l_rint)(*(char *)data, tp); 367 break; 368 369 case TIOCSETP: 370 case TIOCSETN: { 371 register struct sgttyb *sg = (struct sgttyb *)data; 372 373 tp->t_erase = sg->sg_erase; 374 tp->t_kill = sg->sg_kill; 375 tp->t_ispeed = sg->sg_ispeed; 376 tp->t_ospeed = sg->sg_ospeed; 377 newflags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff); 378 s = spltty(); 379 if (tp->t_flags&RAW || newflags&RAW || com == TIOCSETP) { 380 ttywait(tp); 381 ttyflush(tp, FREAD); 382 } else if ((tp->t_flags&CBREAK) != (newflags&CBREAK)) { 383 if (newflags&CBREAK) { 384 struct clist tq; 385 386 catq(&tp->t_rawq, &tp->t_canq); 387 tq = tp->t_rawq; 388 tp->t_rawq = tp->t_canq; 389 tp->t_canq = tq; 390 } else { 391 tp->t_flags |= PENDIN; 392 newflags |= PENDIN; 393 ttwakeup(tp); 394 } 395 } 396 tp->t_flags = newflags; 397 if (tp->t_flags&RAW) { 398 tp->t_state &= ~TS_TTSTOP; 399 ttstart(tp); 400 } 401 splx(s); 402 break; 403 } 404 405 /* send current parameters to user */ 406 case TIOCGETP: { 407 register struct sgttyb *sg = (struct sgttyb *)data; 408 409 sg->sg_ispeed = tp->t_ispeed; 410 sg->sg_ospeed = tp->t_ospeed; 411 sg->sg_erase = tp->t_erase; 412 sg->sg_kill = tp->t_kill; 413 sg->sg_flags = tp->t_flags; 414 break; 415 } 416 417 case FIONBIO: 418 if (*(int *)data) 419 tp->t_state |= TS_NBIO; 420 else 421 tp->t_state &= ~TS_NBIO; 422 break; 423 424 case FIOASYNC: 425 if (*(int *)data) 426 tp->t_state |= TS_ASYNC; 427 else 428 tp->t_state &= ~TS_ASYNC; 429 break; 430 431 case TIOCGETC: 432 bcopy((caddr_t)&tp->t_intrc, data, sizeof (struct tchars)); 433 break; 434 435 case TIOCSETC: 436 bcopy(data, (caddr_t)&tp->t_intrc, sizeof (struct tchars)); 437 break; 438 439 /* set/get local special characters */ 440 case TIOCSLTC: 441 bcopy(data, (caddr_t)&tp->t_suspc, sizeof (struct ltchars)); 442 break; 443 444 case TIOCGLTC: 445 bcopy((caddr_t)&tp->t_suspc, data, sizeof (struct ltchars)); 446 break; 447 448 /* 449 * Modify local mode word. 450 */ 451 case TIOCLBIS: 452 tp->t_flags |= *(int *)data << 16; 453 break; 454 455 case TIOCLBIC: 456 tp->t_flags &= ~(*(int *)data << 16); 457 break; 458 459 case TIOCLSET: 460 tp->t_flags &= 0xffff; 461 tp->t_flags |= *(int *)data << 16; 462 break; 463 464 case TIOCLGET: 465 *(int *)data = ((unsigned) tp->t_flags) >> 16; 466 break; 467 468 /* 469 * Allow SPGRP only if tty is ours and is open for reading. 470 */ 471 case TIOCSPGRP: 472 { 473 struct proc *p; 474 int pgrp = *(int *)data; 475 476 if (u.u_uid && (flag & FREAD) == 0) 477 return (EPERM); 478 if (u.u_uid && u.u_ttyp != tp) 479 return (EACCES); 480 tp->t_pgrp = pgrp; 481 break; 482 } 483 484 case TIOCGPGRP: 485 *(int *)data = tp->t_pgrp; 486 break; 487 488 default: 489 return (-1); 490 } 491 return (0); 492 } 493 494 ttnread(tp) 495 struct tty *tp; 496 { 497 int nread = 0; 498 499 if (tp->t_flags & PENDIN) 500 ttypend(tp); 501 nread = tp->t_canq.c_cc; 502 if (tp->t_flags & (RAW|CBREAK)) 503 nread += tp->t_rawq.c_cc; 504 return (nread); 505 } 506 507 ttselect(dev, rw) 508 dev_t dev; 509 int rw; 510 { 511 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 512 int nread; 513 int s = spltty(); 514 515 switch (rw) { 516 517 case FREAD: 518 nread = ttnread(tp); 519 if (nread > 0) 520 goto win; 521 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 522 tp->t_state |= TS_RCOLL; 523 else 524 tp->t_rsel = u.u_procp; 525 break; 526 527 case FWRITE: 528 if (tp->t_outq.c_cc <= TTLOWAT(tp)) 529 goto win; 530 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 531 tp->t_state |= TS_WCOLL; 532 else 533 tp->t_wsel = u.u_procp; 534 break; 535 } 536 splx(s); 537 return (0); 538 win: 539 splx(s); 540 return (1); 541 } 542 543 /* 544 * Establish a process group for distribution of 545 * quits and interrupts from the tty. 546 */ 547 ttyopen(dev, tp) 548 dev_t dev; 549 register struct tty *tp; 550 { 551 register struct proc *pp; 552 553 pp = u.u_procp; 554 tp->t_dev = dev; 555 if (pp->p_pgrp == 0) { 556 u.u_ttyp = tp; 557 u.u_ttyd = dev; 558 if (tp->t_pgrp == 0) 559 tp->t_pgrp = pp->p_pid; 560 pp->p_pgrp = tp->t_pgrp; 561 } 562 tp->t_state &= ~TS_WOPEN; 563 if ((tp->t_state & TS_ISOPEN) == 0) { 564 tp->t_state |= TS_ISOPEN; 565 if (tp->t_line != NTTYDISC) 566 ttywflush(tp); 567 } 568 return (0); 569 } 570 571 /* 572 * clean tp on last close 573 */ 574 ttyclose(tp) 575 register struct tty *tp; 576 { 577 578 if (tp->t_line) { 579 ttywflush(tp); 580 tp->t_line = 0; 581 return; 582 } 583 tp->t_pgrp = 0; 584 ttywflush(tp); 585 tp->t_state = 0; 586 } 587 588 /* 589 * reinput pending characters after state switch 590 * call at spltty(). 591 */ 592 ttypend(tp) 593 register struct tty *tp; 594 { 595 struct clist tq; 596 register c; 597 598 tp->t_flags &= ~PENDIN; 599 tp->t_state |= TS_TYPEN; 600 tq = tp->t_rawq; 601 tp->t_rawq.c_cc = 0; 602 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 603 while ((c = getc(&tq)) >= 0) 604 ttyinput(c, tp); 605 tp->t_state &= ~TS_TYPEN; 606 } 607 608 /* 609 * Place a character on raw TTY input queue, 610 * putting in delimiters and waking up top 611 * half as needed. Also echo if required. 612 * The arguments are the character and the 613 * appropriate tty structure. 614 */ 615 ttyinput(c, tp) 616 register c; 617 register struct tty *tp; 618 { 619 register int t_flags = tp->t_flags; 620 int i; 621 622 /* 623 * If input is pending take it first. 624 */ 625 if (t_flags&PENDIN) 626 ttypend(tp); 627 tk_nin++; 628 c &= 0377; 629 630 /* 631 * In tandem mode, check high water mark. 632 */ 633 if (t_flags&TANDEM) 634 ttyblock(tp); 635 636 if (t_flags&RAW) { 637 /* 638 * Raw mode, just put character 639 * in input q w/o interpretation. 640 */ 641 if (tp->t_rawq.c_cc > TTYHOG) 642 ttyflush(tp, FREAD|FWRITE); 643 else { 644 if (putc(c, &tp->t_rawq) >= 0) 645 ttwakeup(tp); 646 ttyecho(c, tp); 647 } 648 goto endcase; 649 } 650 651 /* 652 * Ignore any high bit added during 653 * previous ttyinput processing. 654 */ 655 if ((tp->t_state&TS_TYPEN) == 0) 656 c &= 0177; 657 /* 658 * Check for literal nexting very first 659 */ 660 if (tp->t_state&TS_LNCH) { 661 c |= 0200; 662 tp->t_state &= ~TS_LNCH; 663 } 664 665 /* 666 * Scan for special characters. This code 667 * is really just a big case statement with 668 * non-constant cases. The bottom of the 669 * case statement is labeled ``endcase'', so goto 670 * it after a case match, or similar. 671 */ 672 if (tp->t_line == NTTYDISC) { 673 if (c == tp->t_lnextc) { 674 if (tp->t_flags&ECHO) 675 ttyout("^\b", tp); 676 tp->t_state |= TS_LNCH; 677 goto endcase; 678 } 679 if (c == tp->t_flushc) { 680 if (tp->t_flags&FLUSHO) 681 tp->t_flags &= ~FLUSHO; 682 else { 683 ttyflush(tp, FWRITE); 684 ttyecho(c, tp); 685 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 686 ttyretype(tp); 687 tp->t_flags |= FLUSHO; 688 } 689 goto startoutput; 690 } 691 if (c == tp->t_suspc) { 692 if ((tp->t_flags&NOFLSH) == 0) 693 ttyflush(tp, FREAD); 694 ttyecho(c, tp); 695 gsignal(tp->t_pgrp, SIGTSTP); 696 goto endcase; 697 } 698 } 699 700 /* 701 * Handle start/stop characters. 702 */ 703 if (c == tp->t_stopc) { 704 if ((tp->t_state&TS_TTSTOP) == 0) { 705 tp->t_state |= TS_TTSTOP; 706 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 707 return; 708 } 709 if (c != tp->t_startc) 710 return; 711 goto endcase; 712 } 713 if (c == tp->t_startc) 714 goto restartoutput; 715 716 /* 717 * Look for interrupt/quit chars. 718 */ 719 if (c == tp->t_intrc || c == tp->t_quitc) { 720 if ((tp->t_flags&NOFLSH) == 0) 721 ttyflush(tp, FREAD|FWRITE); 722 ttyecho(c, tp); 723 gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT); 724 goto endcase; 725 } 726 727 /* 728 * Cbreak mode, don't process line editing 729 * characters; check high water mark for wakeup. 730 */ 731 if (t_flags&CBREAK) { 732 if (tp->t_rawq.c_cc > TTYHOG) { 733 if (tp->t_outq.c_cc < TTHIWAT(tp) && 734 tp->t_line == NTTYDISC) 735 (void) ttyoutput(CTRL(g), tp); 736 } else if (putc(c, &tp->t_rawq) >= 0) { 737 ttwakeup(tp); 738 ttyecho(c, tp); 739 } 740 goto endcase; 741 } 742 743 /* 744 * From here on down cooked mode character 745 * processing takes place. 746 */ 747 if ((tp->t_state&TS_QUOT) && 748 (c == tp->t_erase || c == tp->t_kill)) { 749 ttyrub(unputc(&tp->t_rawq), tp); 750 c |= 0200; 751 } 752 if (c == tp->t_erase) { 753 if (tp->t_rawq.c_cc) 754 ttyrub(unputc(&tp->t_rawq), tp); 755 goto endcase; 756 } 757 if (c == tp->t_kill) { 758 if (tp->t_flags&CRTKIL && 759 tp->t_rawq.c_cc == tp->t_rocount) { 760 while (tp->t_rawq.c_cc) 761 ttyrub(unputc(&tp->t_rawq), tp); 762 } else { 763 ttyecho(c, tp); 764 ttyecho('\n', tp); 765 while (getc(&tp->t_rawq) > 0) 766 ; 767 tp->t_rocount = 0; 768 } 769 tp->t_state &= ~TS_LOCAL; 770 goto endcase; 771 } 772 773 /* 774 * New line discipline, 775 * check word erase/reprint line. 776 */ 777 if (tp->t_line == NTTYDISC) { 778 if (c == tp->t_werasc) { 779 if (tp->t_rawq.c_cc == 0) 780 goto endcase; 781 do { 782 c = unputc(&tp->t_rawq); 783 if (c != ' ' && c != '\t') 784 goto erasenb; 785 ttyrub(c, tp); 786 } while (tp->t_rawq.c_cc); 787 goto endcase; 788 erasenb: 789 do { 790 ttyrub(c, tp); 791 if (tp->t_rawq.c_cc == 0) 792 goto endcase; 793 c = unputc(&tp->t_rawq); 794 } while (c != ' ' && c != '\t'); 795 (void) putc(c, &tp->t_rawq); 796 goto endcase; 797 } 798 if (c == tp->t_rprntc) { 799 ttyretype(tp); 800 goto endcase; 801 } 802 } 803 804 /* 805 * Check for input buffer overflow 806 */ 807 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 808 if (tp->t_line == NTTYDISC) 809 (void) ttyoutput(CTRL(g), tp); 810 goto endcase; 811 } 812 813 /* 814 * Put data char in q for user and 815 * wakeup on seeing a line delimiter. 816 */ 817 if (putc(c, &tp->t_rawq) >= 0) { 818 if (ttbreakc(c, tp)) { 819 tp->t_rocount = 0; 820 catq(&tp->t_rawq, &tp->t_canq); 821 ttwakeup(tp); 822 } else if (tp->t_rocount++ == 0) 823 tp->t_rocol = tp->t_col; 824 tp->t_state &= ~TS_QUOT; 825 if (c == '\\') 826 tp->t_state |= TS_QUOT; 827 if (tp->t_state&TS_ERASE) { 828 tp->t_state &= ~TS_ERASE; 829 (void) ttyoutput('/', tp); 830 } 831 i = tp->t_col; 832 ttyecho(c, tp); 833 if (c == tp->t_eofc && tp->t_flags&ECHO) { 834 i = MIN(2, tp->t_col - i); 835 while (i > 0) { 836 (void) ttyoutput('\b', tp); 837 i--; 838 } 839 } 840 } 841 842 endcase: 843 /* 844 * If DEC-style start/stop is enabled don't restart 845 * output until seeing the start character. 846 */ 847 if (tp->t_flags&DECCTQ && tp->t_state&TS_TTSTOP && 848 tp->t_startc != tp->t_stopc) 849 return; 850 851 restartoutput: 852 tp->t_state &= ~TS_TTSTOP; 853 tp->t_flags &= ~FLUSHO; 854 855 startoutput: 856 ttstart(tp); 857 } 858 859 /* 860 * Put character on TTY output queue, adding delays, 861 * expanding tabs, and handling the CR/NL bit. 862 * This is called both from the top half for output, 863 * and from interrupt level for echoing. 864 * The arguments are the character and the tty structure. 865 * Returns < 0 if putc succeeds, otherwise returns char to resend 866 * Must be recursive. 867 */ 868 ttyoutput(c, tp) 869 register c; 870 register struct tty *tp; 871 { 872 register char *colp; 873 register ctype; 874 875 if (tp->t_flags & (RAW|LITOUT)) { 876 if (tp->t_flags&FLUSHO) 877 return (-1); 878 if (putc(c, &tp->t_outq)) 879 return (c); 880 tk_nout++; 881 return (-1); 882 } 883 884 /* 885 * Ignore EOT in normal mode to avoid 886 * hanging up certain terminals. 887 */ 888 c &= 0177; 889 if (c == CEOT && (tp->t_flags&CBREAK) == 0) 890 return (-1); 891 /* 892 * Turn tabs to spaces as required 893 */ 894 if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) { 895 register int s; 896 897 c = 8 - (tp->t_col&7); 898 if ((tp->t_flags&FLUSHO) == 0) { 899 s = spltty(); /* don't interrupt tabs */ 900 c -= b_to_q(" ", c, &tp->t_outq); 901 tk_nout += c; 902 splx(s); 903 } 904 tp->t_col += c; 905 return (c ? -1 : '\t'); 906 } 907 tk_nout++; 908 /* 909 * for upper-case-only terminals, 910 * generate escapes. 911 */ 912 if (tp->t_flags&LCASE) { 913 colp = "({)}!|^~'`"; 914 while (*colp++) 915 if (c == *colp++) { 916 if (ttyoutput('\\', tp) >= 0) 917 return (c); 918 c = colp[-2]; 919 break; 920 } 921 if ('A' <= c && c <= 'Z') { 922 if (ttyoutput('\\', tp) >= 0) 923 return (c); 924 } else if ('a' <= c && c <= 'z') 925 c += 'A' - 'a'; 926 } 927 928 /* 929 * turn <nl> to <cr><lf> if desired. 930 */ 931 if (c == '\n' && tp->t_flags&CRMOD) 932 if (ttyoutput('\r', tp) >= 0) 933 return (c); 934 if (c == '~' && tp->t_flags&TILDE) 935 c = '`'; 936 if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq)) 937 return (c); 938 /* 939 * Calculate delays. 940 * The numbers here represent clock ticks 941 * and are not necessarily optimal for all terminals. 942 * The delays are indicated by characters above 0200. 943 * In raw mode there are no delays and the 944 * transmission path is 8 bits wide. 945 * 946 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 947 */ 948 colp = &tp->t_col; 949 ctype = partab[c]; 950 c = 0; 951 switch (ctype&077) { 952 953 case ORDINARY: 954 (*colp)++; 955 956 case CONTROL: 957 break; 958 959 case BACKSPACE: 960 if (*colp) 961 (*colp)--; 962 break; 963 964 /* 965 * This macro is close enough to the correct thing; 966 * it should be replaced by real user settable delays 967 * in any event... 968 */ 969 #define mstohz(ms) (((ms) * hz) >> 10) 970 case NEWLINE: 971 ctype = (tp->t_flags >> 8) & 03; 972 if (ctype == 1) { /* tty 37 */ 973 if (*colp > 0) 974 c = max((((unsigned)*colp) >> 4) + 3, 975 (unsigned)6); 976 } else if (ctype == 2) /* vt05 */ 977 c = mstohz(100); 978 *colp = 0; 979 break; 980 981 case TAB: 982 ctype = (tp->t_flags >> 10) & 03; 983 if (ctype == 1) { /* tty 37 */ 984 c = 1 - (*colp | ~07); 985 if (c < 5) 986 c = 0; 987 } 988 *colp |= 07; 989 (*colp)++; 990 break; 991 992 case VTAB: 993 if (tp->t_flags&VTDELAY) /* tty 37 */ 994 c = 0177; 995 break; 996 997 case RETURN: 998 ctype = (tp->t_flags >> 12) & 03; 999 if (ctype == 1) /* tn 300 */ 1000 c = mstohz(83); 1001 else if (ctype == 2) /* ti 700 */ 1002 c = mstohz(166); 1003 else if (ctype == 3) { /* concept 100 */ 1004 int i; 1005 1006 if ((i = *colp) >= 0) 1007 for (; i < 9; i++) 1008 (void) putc(0177, &tp->t_outq); 1009 } 1010 *colp = 0; 1011 } 1012 if (c && (tp->t_flags&FLUSHO) == 0) 1013 (void) putc(c|0200, &tp->t_outq); 1014 return (-1); 1015 } 1016 #undef mstohz 1017 1018 /* 1019 * Called from device's read routine after it has 1020 * calculated the tty-structure given as argument. 1021 */ 1022 ttread(tp, uio) 1023 register struct tty *tp; 1024 struct uio *uio; 1025 { 1026 register struct clist *qp; 1027 register c, t_flags; 1028 int s, first, error = 0; 1029 1030 if ((tp->t_state&TS_CARR_ON)==0) 1031 return (EIO); 1032 loop: 1033 /* 1034 * Take any pending input first. 1035 */ 1036 s = spltty(); 1037 if (tp->t_flags&PENDIN) 1038 ttypend(tp); 1039 splx(s); 1040 1041 /* 1042 * Hang process if it's in the background. 1043 */ 1044 #define bit(a) (1<<(a-1)) 1045 while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 1046 if ((u.u_procp->p_sigignore & bit(SIGTTIN)) || 1047 (u.u_procp->p_sigmask & bit(SIGTTIN)) || 1048 /* 1049 (u.u_procp->p_flag&SDETACH) || 1050 */ 1051 u.u_procp->p_flag&SVFORK) 1052 return (EIO); 1053 gsignal(u.u_procp->p_pgrp, SIGTTIN); 1054 sleep((caddr_t)&lbolt, TTIPRI); 1055 } 1056 t_flags = tp->t_flags; 1057 #undef bit 1058 1059 /* 1060 * In raw mode take characters directly from the 1061 * raw queue w/o processing. Interlock against 1062 * device interrupts when interrogating rawq. 1063 */ 1064 if (t_flags&RAW) { 1065 s = spltty(); 1066 if (tp->t_rawq.c_cc <= 0) { 1067 if ((tp->t_state&TS_CARR_ON) == 0 || 1068 (tp->t_state&TS_NBIO)) { 1069 splx(s); 1070 return (EWOULDBLOCK); 1071 } 1072 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1073 splx(s); 1074 goto loop; 1075 } 1076 splx(s); 1077 while (!error && tp->t_rawq.c_cc && uio->uio_resid) 1078 error = ureadc(getc(&tp->t_rawq), uio); 1079 goto checktandem; 1080 } 1081 1082 /* 1083 * In cbreak mode use the rawq, otherwise 1084 * take characters from the canonicalized q. 1085 */ 1086 qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq; 1087 1088 /* 1089 * No input, sleep on rawq awaiting hardware 1090 * receipt and notification. 1091 */ 1092 s = spltty(); 1093 if (qp->c_cc <= 0) { 1094 if ((tp->t_state&TS_CARR_ON) == 0 || 1095 (tp->t_state&TS_NBIO)) { 1096 splx(s); 1097 return (EWOULDBLOCK); 1098 } 1099 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1100 splx(s); 1101 goto loop; 1102 } 1103 splx(s); 1104 1105 /* 1106 * Input present, perform input mapping 1107 * and processing (we're not in raw mode). 1108 */ 1109 first = 1; 1110 while ((c = getc(qp)) >= 0) { 1111 if (t_flags&CRMOD && c == '\r') 1112 c = '\n'; 1113 /* 1114 * Hack lower case simulation on 1115 * upper case only terminals. 1116 */ 1117 if (t_flags&LCASE && c <= 0177) 1118 if (tp->t_state&TS_BKSL) { 1119 if (maptab[c]) 1120 c = maptab[c]; 1121 tp->t_state &= ~TS_BKSL; 1122 } else if (c >= 'A' && c <= 'Z') 1123 c += 'a' - 'A'; 1124 else if (c == '\\') { 1125 tp->t_state |= TS_BKSL; 1126 continue; 1127 } 1128 /* 1129 * Check for delayed suspend character. 1130 */ 1131 if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) { 1132 gsignal(tp->t_pgrp, SIGTSTP); 1133 if (first) { 1134 sleep((caddr_t)&lbolt, TTIPRI); 1135 goto loop; 1136 } 1137 break; 1138 } 1139 /* 1140 * Interpret EOF only in cooked mode. 1141 */ 1142 if (c == tp->t_eofc && (t_flags&CBREAK) == 0) 1143 break; 1144 /* 1145 * Give user character. 1146 */ 1147 error = ureadc(c & 0177, uio); 1148 if (error) 1149 break; 1150 if (uio->uio_resid == 0) 1151 break; 1152 /* 1153 * In cooked mode check for a "break character" 1154 * marking the end of a "line of input". 1155 */ 1156 if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp)) 1157 break; 1158 first = 0; 1159 } 1160 tp->t_state &= ~TS_BKSL; 1161 1162 checktandem: 1163 /* 1164 * Look to unblock output now that (presumably) 1165 * the input queue has gone down. 1166 */ 1167 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) 1168 if (putc(tp->t_startc, &tp->t_outq) == 0) { 1169 tp->t_state &= ~TS_TBLOCK; 1170 ttstart(tp); 1171 } 1172 return (error); 1173 } 1174 1175 /* 1176 * Called from the device's write routine after it has 1177 * calculated the tty-structure given as argument. 1178 */ 1179 ttwrite(tp, uio) 1180 register struct tty *tp; 1181 register struct uio *uio; 1182 { 1183 register char *cp; 1184 register int cc, ce, c; 1185 int i, hiwat, cnt, error, s; 1186 char obuf[OBUFSIZ]; 1187 1188 if ((tp->t_state&TS_CARR_ON) == 0) 1189 return (EIO); 1190 hiwat = TTHIWAT(tp); 1191 cnt = uio->uio_resid; 1192 error = 0; 1193 loop: 1194 /* 1195 * Hang the process if it's in the background. 1196 */ 1197 #define bit(a) (1<<(a-1)) 1198 while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 1199 (tp->t_flags&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1200 !(u.u_procp->p_sigignore & bit(SIGTTOU)) && 1201 !(u.u_procp->p_sigmask & bit(SIGTTOU)) 1202 /* 1203 && 1204 (u.u_procp->p_flag&SDETACH)==0) { 1205 */ 1206 ) { 1207 gsignal(u.u_procp->p_pgrp, SIGTTOU); 1208 sleep((caddr_t)&lbolt, TTIPRI); 1209 } 1210 #undef bit 1211 1212 /* 1213 * Process the user's data in at most OBUFSIZ 1214 * chunks. Perform lower case simulation and 1215 * similar hacks. Keep track of high water 1216 * mark, sleep on overflow awaiting device aid 1217 * in acquiring new space. 1218 */ 1219 while (uio->uio_resid > 0) { 1220 /* 1221 * Grab a hunk of data from the user. 1222 */ 1223 cc = uio->uio_iov->iov_len; 1224 if (cc == 0) { 1225 uio->uio_iovcnt--; 1226 uio->uio_iov++; 1227 if (uio->uio_iovcnt < 0) 1228 panic("ttwrite"); 1229 continue; 1230 } 1231 if (cc > OBUFSIZ) 1232 cc = OBUFSIZ; 1233 cp = obuf; 1234 error = uiomove(cp, cc, UIO_WRITE, uio); 1235 if (error) 1236 break; 1237 if (tp->t_outq.c_cc > hiwat) 1238 goto ovhiwat; 1239 if (tp->t_flags&FLUSHO) 1240 continue; 1241 /* 1242 * If we're mapping lower case or kludging tildes, 1243 * then we've got to look at each character, so 1244 * just feed the stuff to ttyoutput... 1245 */ 1246 if (tp->t_flags & (LCASE|TILDE)) { 1247 while (cc > 0) { 1248 c = *cp++; 1249 tp->t_rocount = 0; 1250 while ((c = ttyoutput(c, tp)) >= 0) { 1251 /* out of clists, wait a bit */ 1252 ttstart(tp); 1253 sleep((caddr_t)&lbolt, TTOPRI); 1254 tp->t_rocount = 0; 1255 } 1256 --cc; 1257 if (tp->t_outq.c_cc > hiwat) 1258 goto ovhiwat; 1259 } 1260 continue; 1261 } 1262 /* 1263 * If nothing fancy need be done, grab those characters we 1264 * can handle without any of ttyoutput's processing and 1265 * just transfer them to the output q. For those chars 1266 * which require special processing (as indicated by the 1267 * bits in partab), call ttyoutput. After processing 1268 * a hunk of data, look for FLUSHO so ^O's will take effect 1269 * immediately. 1270 */ 1271 while (cc > 0) { 1272 if (tp->t_flags & (RAW|LITOUT)) 1273 ce = cc; 1274 else { 1275 ce = cc - scanc((unsigned)cc, (caddr_t)cp, 1276 (caddr_t)partab, 077); 1277 /* 1278 * If ce is zero, then we're processing 1279 * a special character through ttyoutput. 1280 */ 1281 if (ce == 0) { 1282 tp->t_rocount = 0; 1283 if (ttyoutput(*cp, tp) >= 0) { 1284 /* no c-lists, wait a bit */ 1285 ttstart(tp); 1286 sleep((caddr_t)&lbolt, TTOPRI); 1287 continue; 1288 } 1289 cp++, cc--; 1290 if (tp->t_flags&FLUSHO || 1291 tp->t_outq.c_cc > hiwat) 1292 goto ovhiwat; 1293 continue; 1294 } 1295 } 1296 /* 1297 * A bunch of normal characters have been found, 1298 * transfer them en masse to the output queue and 1299 * continue processing at the top of the loop. 1300 * If there are any further characters in this 1301 * <= OBUFSIZ chunk, the first should be a character 1302 * requiring special handling by ttyoutput. 1303 */ 1304 tp->t_rocount = 0; 1305 i = b_to_q(cp, ce, &tp->t_outq); 1306 ce -= i; 1307 tp->t_col += ce; 1308 cp += ce, cc -= ce, tk_nout += ce; 1309 if (i > 0) { 1310 /* out of c-lists, wait a bit */ 1311 ttstart(tp); 1312 sleep((caddr_t)&lbolt, TTOPRI); 1313 } 1314 if (tp->t_flags&FLUSHO || tp->t_outq.c_cc > hiwat) 1315 goto ovhiwat; 1316 } 1317 } 1318 ttstart(tp); 1319 return (error); 1320 1321 ovhiwat: 1322 s = spltty(); 1323 if (cc != 0) { 1324 uio->uio_iov->iov_base -= cc; 1325 uio->uio_iov->iov_len += cc; 1326 uio->uio_resid += cc; 1327 uio->uio_offset -= cc; 1328 } 1329 /* 1330 * This can only occur if FLUSHO 1331 * is also set in t_flags. 1332 */ 1333 if (tp->t_outq.c_cc <= hiwat) { 1334 splx(s); 1335 goto loop; 1336 } 1337 ttstart(tp); 1338 if (tp->t_state&TS_NBIO) { 1339 splx(s); 1340 if (uio->uio_resid == cnt) 1341 return (EWOULDBLOCK); 1342 return (0); 1343 } 1344 tp->t_state |= TS_ASLEEP; 1345 sleep((caddr_t)&tp->t_outq, TTOPRI); 1346 splx(s); 1347 goto loop; 1348 } 1349 1350 /* 1351 * Rubout one character from the rawq of tp 1352 * as cleanly as possible. 1353 */ 1354 ttyrub(c, tp) 1355 register c; 1356 register struct tty *tp; 1357 { 1358 register char *cp; 1359 register int savecol; 1360 int s; 1361 char *nextc(); 1362 1363 if ((tp->t_flags&ECHO) == 0) 1364 return; 1365 tp->t_flags &= ~FLUSHO; 1366 c &= 0377; 1367 if (tp->t_flags&CRTBS) { 1368 if (tp->t_rocount == 0) { 1369 /* 1370 * Screwed by ttwrite; retype 1371 */ 1372 ttyretype(tp); 1373 return; 1374 } 1375 if (c == ('\t'|0200) || c == ('\n'|0200)) 1376 ttyrubo(tp, 2); 1377 else switch (partab[c&=0177]&0177) { 1378 1379 case ORDINARY: 1380 if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z') 1381 ttyrubo(tp, 2); 1382 else 1383 ttyrubo(tp, 1); 1384 break; 1385 1386 case VTAB: 1387 case BACKSPACE: 1388 case CONTROL: 1389 case RETURN: 1390 if (tp->t_flags&CTLECH) 1391 ttyrubo(tp, 2); 1392 break; 1393 1394 case TAB: 1395 if (tp->t_rocount < tp->t_rawq.c_cc) { 1396 ttyretype(tp); 1397 return; 1398 } 1399 s = spltty(); 1400 savecol = tp->t_col; 1401 tp->t_state |= TS_CNTTB; 1402 tp->t_flags |= FLUSHO; 1403 tp->t_col = tp->t_rocol; 1404 cp = tp->t_rawq.c_cf; 1405 for (; cp; cp = nextc(&tp->t_rawq, cp)) 1406 ttyecho(*cp, tp); 1407 tp->t_flags &= ~FLUSHO; 1408 tp->t_state &= ~TS_CNTTB; 1409 splx(s); 1410 /* 1411 * savecol will now be length of the tab 1412 */ 1413 savecol -= tp->t_col; 1414 tp->t_col += savecol; 1415 if (savecol > 8) 1416 savecol = 8; /* overflow screw */ 1417 while (--savecol >= 0) 1418 (void) ttyoutput('\b', tp); 1419 break; 1420 1421 default: 1422 panic("ttyrub"); 1423 } 1424 } else if (tp->t_flags&PRTERA) { 1425 if ((tp->t_state&TS_ERASE) == 0) { 1426 (void) ttyoutput('\\', tp); 1427 tp->t_state |= TS_ERASE; 1428 } 1429 ttyecho(c, tp); 1430 } else 1431 ttyecho(tp->t_erase, tp); 1432 tp->t_rocount--; 1433 } 1434 1435 /* 1436 * Crt back over cnt chars perhaps 1437 * erasing them. 1438 */ 1439 ttyrubo(tp, cnt) 1440 register struct tty *tp; 1441 int cnt; 1442 { 1443 register char *rubostring = tp->t_flags&CRTERA ? "\b \b" : "\b"; 1444 1445 while (--cnt >= 0) 1446 ttyout(rubostring, tp); 1447 } 1448 1449 /* 1450 * Reprint the rawq line. 1451 * We assume c_cc has already been checked. 1452 */ 1453 ttyretype(tp) 1454 register struct tty *tp; 1455 { 1456 register char *cp; 1457 char *nextc(); 1458 int s; 1459 1460 if (tp->t_rprntc != 0377) 1461 ttyecho(tp->t_rprntc, tp); 1462 (void) ttyoutput('\n', tp); 1463 s = spltty(); 1464 for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp)) 1465 ttyecho(*cp, tp); 1466 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1467 ttyecho(*cp, tp); 1468 tp->t_state &= ~TS_ERASE; 1469 splx(s); 1470 tp->t_rocount = tp->t_rawq.c_cc; 1471 tp->t_rocol = 0; 1472 } 1473 1474 /* 1475 * Echo a typed character to the terminal 1476 */ 1477 ttyecho(c, tp) 1478 register c; 1479 register struct tty *tp; 1480 { 1481 1482 if ((tp->t_state&TS_CNTTB) == 0) 1483 tp->t_flags &= ~FLUSHO; 1484 if ((tp->t_flags&ECHO) == 0) 1485 return; 1486 c &= 0377; 1487 if (tp->t_flags&RAW) { 1488 (void) ttyoutput(c, tp); 1489 return; 1490 } 1491 if (c == '\r' && tp->t_flags&CRMOD) 1492 c = '\n'; 1493 if (tp->t_flags&CTLECH) { 1494 if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) { 1495 (void) ttyoutput('^', tp); 1496 c &= 0177; 1497 if (c == 0177) 1498 c = '?'; 1499 else if (tp->t_flags&LCASE) 1500 c += 'a' - 1; 1501 else 1502 c += 'A' - 1; 1503 } 1504 } 1505 if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z')) 1506 c += 'a' - 'A'; 1507 (void) ttyoutput(c&0177, tp); 1508 } 1509 1510 /* 1511 * Is c a break char for tp? 1512 */ 1513 ttbreakc(c, tp) 1514 register c; 1515 register struct tty *tp; 1516 { 1517 return (c == '\n' || c == tp->t_eofc || c == tp->t_brkc || 1518 c == '\r' && (tp->t_flags&CRMOD)); 1519 } 1520 1521 /* 1522 * send string cp to tp 1523 */ 1524 ttyout(cp, tp) 1525 register char *cp; 1526 register struct tty *tp; 1527 { 1528 register char c; 1529 1530 while (c = *cp++) 1531 (void) ttyoutput(c, tp); 1532 } 1533 1534 ttwakeup(tp) 1535 struct tty *tp; 1536 { 1537 1538 if (tp->t_rsel) { 1539 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1540 tp->t_state &= ~TS_RCOLL; 1541 tp->t_rsel = 0; 1542 } 1543 if (tp->t_state & TS_ASYNC) 1544 gsignal(tp->t_pgrp, SIGIO); 1545 wakeup((caddr_t)&tp->t_rawq); 1546 } 1547 1548 #if !defined(vax) 1549 scanc(size, cp, table, mask) 1550 register int size; 1551 register char *cp, table[]; 1552 register int mask; 1553 { 1554 register int i = 0; 1555 1556 while ((table[*(u_char *)(cp + i)]&mask) == 0 && i < size) 1557 i++; 1558 return (size - i); 1559 } 1560 #endif 1561