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