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