1 /* tty.c 4.24 82/07/24 */ 2 3 /* 4 * TTY subroutines common to more than one line discipline 5 */ 6 #include "../h/param.h" 7 #include "../h/systm.h" 8 #include "../h/dir.h" 9 #include "../h/user.h" 10 #include "../h/tty.h" 11 #include "../h/proc.h" 12 #include "../h/inode.h" 13 #include "../h/file.h" 14 #include "../h/reg.h" 15 #include "../h/conf.h" 16 #include "../h/buf.h" 17 #include "../h/dk.h" 18 19 /* 20 * Table giving parity for characters and indicating 21 * character classes to tty driver. In particular, 22 * if the low 6 bits are 0, then the character needs 23 * no special processing on output. 24 */ 25 26 char partab[] = { 27 0001,0201,0201,0001,0201,0001,0001,0201, 28 0202,0004,0003,0201,0005,0206,0201,0001, 29 0201,0001,0001,0201,0001,0201,0201,0001, 30 0001,0201,0201,0001,0201,0001,0001,0201, 31 0200,0000,0000,0200,0000,0200,0200,0000, 32 0000,0200,0200,0000,0200,0000,0000,0200, 33 0000,0200,0200,0000,0200,0000,0000,0200, 34 0200,0000,0000,0200,0000,0200,0200,0000, 35 0200,0000,0000,0200,0000,0200,0200,0000, 36 0000,0200,0200,0000,0200,0000,0000,0200, 37 0000,0200,0200,0000,0200,0000,0000,0200, 38 0200,0000,0000,0200,0000,0200,0200,0000, 39 0000,0200,0200,0000,0200,0000,0000,0200, 40 0200,0000,0000,0200,0000,0200,0200,0000, 41 0200,0000,0000,0200,0000,0200,0200,0000, 42 0000,0200,0200,0000,0200,0000,0000,0201, 43 44 /* 45 * 7 bit ascii ends with the last character above, 46 * but we contine through all 256 codes for the sake 47 * of the tty output routines which use special vax 48 * instructions which need a 256 character trt table. 49 */ 50 51 0007,0007,0007,0007,0007,0007,0007,0007, 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 }; 68 69 /* 70 * Input mapping table-- if an entry is non-zero, when the 71 * corresponding character is typed preceded by "\" the escape 72 * sequence is replaced by the table value. Mostly used for 73 * upper-case only terminals. 74 */ 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,650,650 }; 97 short ttlowat[16] = 98 { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 }; 99 100 #define OBUFSIZ 100 101 102 /* 103 * set default control characters. 104 */ 105 ttychars(tp) 106 register struct tty *tp; 107 { 108 109 tun.t_intrc = CINTR; 110 tun.t_quitc = CQUIT; 111 tun.t_startc = CSTART; 112 tun.t_stopc = CSTOP; 113 tun.t_eofc = CEOT; 114 tun.t_brkc = CBRK; 115 tp->t_erase = CERASE; 116 tp->t_kill = CKILL; 117 /* begin local */ 118 tlun.t_suspc = CTRL(z); 119 tlun.t_dsuspc = CTRL(y); 120 tlun.t_rprntc = CTRL(r); 121 tlun.t_flushc = CTRL(o); 122 tlun.t_werasc = CTRL(w); 123 tlun.t_lnextc = CTRL(v); 124 tp->t_local = 0; 125 tp->t_lstate = 0; 126 /* end local */ 127 } 128 129 /* 130 * Wait for output to drain, then flush input waiting. 131 */ 132 wflushtty(tp) 133 register struct tty *tp; 134 { 135 136 (void) spl5(); 137 while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON 138 && tp->t_oproc) { /* kludge for pty */ 139 (*tp->t_oproc)(tp); 140 tp->t_state |= TS_ASLEEP; 141 sleep((caddr_t)&tp->t_outq, TTOPRI); 142 } 143 flushtty(tp, FREAD); 144 (void) spl0(); 145 } 146 147 /* 148 * flush all TTY queues 149 */ 150 flushtty(tp, rw) 151 register struct tty *tp; 152 { 153 register s; 154 155 s = spl6(); 156 if (rw & FREAD) { 157 while (getc(&tp->t_canq) >= 0) 158 ; 159 wakeup((caddr_t)&tp->t_rawq); 160 } 161 if (rw & FWRITE) { 162 wakeup((caddr_t)&tp->t_outq); 163 tp->t_state &= ~TS_TTSTOP; 164 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 165 while (getc(&tp->t_outq) >= 0) 166 ; 167 } 168 if (rw & FREAD) { 169 while (getc(&tp->t_rawq) >= 0) 170 ; 171 tp->t_delct = 0; 172 tp->t_rocount = 0; /* local */ 173 tp->t_rocol = 0; 174 tp->t_lstate = 0; 175 } 176 splx(s); 177 } 178 179 /* 180 * Send stop character on input overflow. 181 */ 182 ttyblock(tp) 183 register struct tty *tp; 184 { 185 register x; 186 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 187 if (tp->t_rawq.c_cc > TTYHOG) { 188 flushtty(tp, FREAD|FWRITE); 189 tp->t_state &= ~TS_TBLOCK; 190 } 191 if (x >= TTYHOG/2) { 192 if (putc(tun.t_stopc, &tp->t_outq)==0) { 193 tp->t_state |= TS_TBLOCK; 194 tp->t_char++; 195 ttstart(tp); 196 } 197 } 198 } 199 200 /* 201 * Restart typewriter output following a delay 202 * timeout. 203 * The name of the routine is passed to the timeout 204 * subroutine and it is called during a clock interrupt. 205 */ 206 ttrstrt(tp) 207 register struct tty *tp; 208 { 209 210 if (tp == 0) { 211 printf("ttrstrt: arg was 0!\n"); 212 return; 213 } 214 tp->t_state &= ~TS_TIMEOUT; 215 ttstart(tp); 216 } 217 218 /* 219 * Start output on the typewriter. It is used from the top half 220 * after some characters have been put on the output queue, 221 * from the interrupt routine to transmit the next 222 * character, and after a timeout has finished. 223 */ 224 ttstart(tp) 225 register struct tty *tp; 226 { 227 register s; 228 229 s = spl5(); 230 if((tp->t_state&(TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 && 231 tp->t_oproc) /* kludge for pty */ 232 (*tp->t_oproc)(tp); 233 splx(s); 234 } 235 236 /* 237 * Common code for tty ioctls. 238 */ 239 /*ARGSUSED*/ 240 ttioctl(tp, com, addr, flag) 241 register struct tty *tp; 242 caddr_t addr; 243 { 244 int dev; 245 unsigned t; 246 struct sgttyb iocb; 247 struct clist tq; 248 extern int nldisp; 249 register c; 250 int temp; 251 252 /* 253 * This is especially so that isatty() will 254 * fail when carrier is gone. 255 */ 256 if ((tp->t_state&TS_CARR_ON) == 0) { 257 u.u_error = EBADF; 258 return (1); 259 } 260 261 dev = tp->t_dev; 262 /* 263 * If the ioctl involves modification, 264 * insist on being able to write the device, 265 * and hang if in the background. 266 */ 267 switch(com) { 268 269 case TIOCSETD: 270 case TIOCSETP: 271 case TIOCSETN: 272 case TIOCFLUSH: 273 case TIOCSETC: 274 case TIOCSLTC: 275 case TIOCSPGRP: 276 case TIOCLBIS: 277 case TIOCLBIC: 278 case TIOCLSET: 279 case TIOCSTI: 280 /* this is reasonable, but impractical... 281 if ((flag & FWRITE) == 0) { 282 u.u_error = EBADF; 283 return (1); 284 } 285 */ 286 while (tp->t_line == NTTYDISC && 287 u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 288 (u.u_procp->p_flag&SVFORK) == 0 && 289 u.u_signal[SIGTTOU] != SIG_IGN && 290 u.u_signal[SIGTTOU] != SIG_HOLD 291 /* 292 && 293 (u.u_procp->p_flag&SDETACH)==0) { 294 */ 295 ) { 296 gsignal(u.u_procp->p_pgrp, SIGTTOU); 297 sleep((caddr_t)&lbolt, TTOPRI); 298 } 299 break; 300 } 301 302 /* 303 * Process the ioctl. 304 */ 305 switch(com) { 306 307 /* 308 * Get discipline number 309 */ 310 case TIOCGETD: 311 t = tp->t_line; 312 if (copyout((caddr_t)&t, addr, sizeof(t))) 313 u.u_error = EFAULT; 314 break; 315 316 /* 317 * Set line discipline 318 */ 319 case TIOCSETD: 320 if (copyin(addr, (caddr_t)&t, sizeof(t))) { 321 u.u_error = EFAULT; 322 break; 323 } 324 if (t >= nldisp) { 325 u.u_error = ENXIO; 326 break; 327 } 328 (void) spl5(); 329 if (tp->t_line) 330 (*linesw[tp->t_line].l_close)(tp); 331 if (t) 332 (*linesw[t].l_open)(dev, tp, addr); 333 if (u.u_error==0) 334 tp->t_line = t; 335 (void) spl0(); 336 break; 337 338 /* 339 * Prevent more opens on channel 340 */ 341 case TIOCEXCL: 342 tp->t_state |= TS_XCLUDE; 343 break; 344 345 case TIOCNXCL: 346 tp->t_state &= ~TS_XCLUDE; 347 break; 348 349 /* 350 * Set new parameters 351 */ 352 case TIOCSETP: 353 case TIOCSETN: 354 if (copyin(addr, (caddr_t)&iocb, sizeof(iocb))) { 355 u.u_error = EFAULT; 356 return(1); 357 } 358 (void) spl5(); 359 if (tp->t_flags&RAW || iocb.sg_flags&RAW || 360 com == TIOCSETP) 361 wflushtty(tp); 362 else if ((tp->t_flags&CBREAK) != (iocb.sg_flags&CBREAK)) { 363 if (iocb.sg_flags & CBREAK) { 364 catq(&tp->t_rawq, &tp->t_canq); 365 tq = tp->t_rawq; 366 tp->t_rawq = tp->t_canq; 367 tp->t_canq = tq; 368 } else { 369 tp->t_local |= LPENDIN; 370 ttwakeup(tp); 371 } 372 } 373 tp->t_ispeed = iocb.sg_ispeed; 374 tp->t_ospeed = iocb.sg_ospeed; 375 tp->t_erase = iocb.sg_erase; 376 tp->t_kill = iocb.sg_kill; 377 tp->t_flags = iocb.sg_flags; 378 if (tp->t_flags & RAW) { 379 tp->t_state &= ~TS_TTSTOP; 380 ttstart(tp); 381 } 382 (void) spl0(); 383 break; 384 385 /* 386 * Send current parameters to user 387 */ 388 case TIOCGETP: 389 iocb.sg_ispeed = tp->t_ispeed; 390 iocb.sg_ospeed = tp->t_ospeed; 391 iocb.sg_erase = tp->t_erase; 392 iocb.sg_kill = tp->t_kill; 393 iocb.sg_flags = tp->t_flags; 394 if (copyout((caddr_t)&iocb, addr, sizeof(iocb))) 395 u.u_error = EFAULT; 396 break; 397 398 /* 399 * Hang up line on last close 400 */ 401 case TIOCHPCL: 402 tp->t_state |= TS_HUPCLS; 403 break; 404 405 case TIOCFLUSH: { 406 int flags; 407 if (addr == 0) 408 flags = FREAD|FWRITE; 409 else if (copyin(addr, (caddr_t)&flags, sizeof (flags))) { 410 u.u_error = EFAULT; 411 return(1); 412 } 413 flushtty(tp, flags); 414 break; 415 } 416 417 case FIONBIO: { 418 int nbio; 419 if (copyin(addr, (caddr_t)&nbio, sizeof (nbio))) { 420 u.u_error = EFAULT; 421 return(1); 422 } 423 if (nbio) 424 tp->t_state |= TS_NBIO; 425 else 426 tp->t_state &= ~TS_NBIO; 427 break; 428 } 429 430 case FIOASYNC: { 431 int async; 432 if (copyin(addr, (caddr_t)&async, sizeof (async))) { 433 u.u_error = EFAULT; 434 return(1); 435 } 436 if (async) 437 tp->t_state |= TS_ASYNC; 438 else 439 tp->t_state &= ~TS_ASYNC; 440 break; 441 } 442 443 /* 444 * Set and fetch special characters 445 */ 446 case TIOCSETC: 447 if (copyin(addr, (caddr_t)&tun, sizeof(struct tchars))) 448 u.u_error = EFAULT; 449 break; 450 451 case TIOCGETC: 452 if (copyout((caddr_t)&tun, addr, sizeof(struct tchars))) 453 u.u_error = EFAULT; 454 break; 455 456 /* local ioctls */ 457 /* 458 * Set/get local special characters. 459 */ 460 case TIOCSLTC: 461 if (copyin(addr, (caddr_t)&tlun, sizeof (struct ltchars))) 462 u.u_error = EFAULT; 463 break; 464 465 case TIOCGLTC: 466 if (copyout((caddr_t)&tlun, addr, sizeof (struct ltchars))) 467 u.u_error = EFAULT; 468 break; 469 470 /* 471 * Return number of characters immediately available. 472 */ 473 case FIONREAD: { 474 off_t nread = ttnread(tp); 475 if (copyout((caddr_t)&nread, addr, sizeof (off_t))) 476 u.u_error = EFAULT; 477 break; 478 } 479 480 /* 481 * Should allow SPGRP and GPGRP only if tty open for reading. 482 */ 483 case TIOCSPGRP: 484 if (copyin(addr, (caddr_t)&tp->t_pgrp, sizeof (tp->t_pgrp))) 485 u.u_error = EFAULT; 486 break; 487 488 case TIOCGPGRP: 489 if (copyout((caddr_t)&tp->t_pgrp, addr, sizeof(tp->t_pgrp))) 490 u.u_error = EFAULT; 491 break; 492 493 /* 494 * Modify local mode word. 495 */ 496 case TIOCLBIS: 497 if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local))) 498 u.u_error = EFAULT; 499 else 500 tp->t_local |= temp; 501 break; 502 503 case TIOCLBIC: 504 if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local))) 505 u.u_error = EFAULT; 506 else 507 tp->t_local &= ~temp; 508 break; 509 510 case TIOCLSET: 511 if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local))) 512 u.u_error = EFAULT; 513 else 514 tp->t_local = temp; 515 break; 516 517 case TIOCLGET: 518 if (copyout((caddr_t)&tp->t_local, addr, sizeof(tp->t_local))) 519 u.u_error = EFAULT; 520 break; 521 522 /* 523 * Return number of characters in 524 * the output. 525 */ 526 case TIOCOUTQ: 527 if (copyout((caddr_t)&tp->t_outq.c_cc, addr, sizeof(tp->t_outq.c_cc))) 528 u.u_error = EFAULT; 529 break; 530 531 /* 532 * Simulate typing of a character at the terminal. 533 */ 534 case TIOCSTI: 535 c = fubyte(addr); 536 if (u.u_uid && u.u_ttyp != tp || c < 0) 537 u.u_error = EFAULT; 538 else 539 (*linesw[tp->t_line].l_rint)(c, tp); 540 break; 541 542 case TIOCSTOP: 543 c = spl5(); 544 if ((tp->t_state & TS_TTSTOP) == 0) { 545 tp->t_state |= TS_TTSTOP; 546 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 547 } 548 splx(c); 549 break; 550 551 case TIOCSTART: 552 c = spl5(); 553 if ((tp->t_state & TS_TTSTOP) || (tp->t_local & LFLUSHO)) { 554 tp->t_state &= ~TS_TTSTOP; 555 tp->t_local &= ~LFLUSHO; 556 ttstart(tp); 557 } 558 splx(c); 559 break; 560 561 /* end of locals */ 562 563 default: 564 return(0); 565 } 566 return(1); 567 } 568 569 ttnread(tp) 570 struct tty *tp; 571 { 572 int nread = 0; 573 574 if (tp->t_local & LPENDIN) 575 ttypend(tp); 576 nread = tp->t_canq.c_cc; 577 if (tp->t_flags & (RAW|CBREAK)) 578 nread += tp->t_rawq.c_cc; 579 return (nread); 580 } 581 582 ttselect(dev, rw) 583 dev_t dev; 584 int rw; 585 { 586 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 587 int nread; 588 int s = spl5(); 589 590 switch (rw) { 591 592 case FREAD: 593 nread = ttnread(tp); 594 if (nread > 0) 595 goto win; 596 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 597 tp->t_state |= TS_RCOLL; 598 else 599 tp->t_rsel = u.u_procp; 600 break; 601 602 case FWRITE: 603 if (tp->t_outq.c_cc <= TTLOWAT(tp)) 604 goto win; 605 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 606 tp->t_state |= TS_WCOLL; 607 else 608 tp->t_wsel = u.u_procp; 609 break; 610 } 611 splx(s); 612 return (0); 613 win: 614 splx(s); 615 return (1); 616 } 617 618 #define OBUFSIZ 100 619 620 /* 621 * routine called on opens while tp->t_line == NTTYDISC 622 * establishes a process group for distribution of 623 * quits and interrupts from the tty. 624 * (actually, pp->p_pgrp can't be 0 when this routine 625 * is called since NTTYDISC is not the default discipline) 626 */ 627 ttyopen(dev, tp) 628 dev_t dev; 629 register struct tty *tp; 630 { 631 register struct proc *pp; 632 633 pp = u.u_procp; 634 tp->t_dev = dev; 635 if(pp->p_pgrp == 0) { 636 u.u_ttyp = tp; 637 u.u_ttyd = dev; 638 if (tp->t_pgrp == 0) 639 tp->t_pgrp = pp->p_pid; 640 pp->p_pgrp = tp->t_pgrp; 641 } 642 tp->t_state &= ~TS_WOPEN; 643 tp->t_state |= TS_ISOPEN; 644 if (tp->t_line != NTTYDISC) 645 wflushtty(tp); 646 } 647 648 /* 649 * clean tp on last close 650 */ 651 ttyclose(tp) 652 register struct tty *tp; 653 { 654 655 if (tp->t_line) { 656 wflushtty(tp); 657 tp->t_line = 0; 658 return; 659 } 660 tp->t_pgrp = 0; 661 wflushtty(tp); 662 tp->t_state = 0; 663 } 664 665 /* 666 * reinput pending characters after state switch 667 * call at spl5(). 668 */ 669 ttypend(tp) 670 register struct tty *tp; 671 { 672 struct clist tq; 673 register c; 674 675 tp->t_local &= ~LPENDIN; 676 tp->t_lstate |= LSTYPEN; 677 tq = tp->t_rawq; 678 tp->t_rawq.c_cc = 0; 679 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 680 while ((c = getc(&tq)) >= 0) 681 ttyinput(c, tp); 682 tp->t_lstate &= ~LSTYPEN; 683 } 684 685 /* 686 * Place a character on raw TTY input queue, putting in delimiters 687 * and waking up top half as needed. 688 * Also echo if required. 689 * The arguments are the character and the appropriate 690 * tty structure. 691 */ 692 ttyinput(c, tp) 693 register c; 694 register struct tty *tp; 695 { 696 register int t_flags; 697 int i; 698 699 if (tp->t_local&LPENDIN) 700 ttypend(tp); 701 tk_nin++; 702 c &= 0377; 703 t_flags = tp->t_flags; 704 if (t_flags&TANDEM) 705 ttyblock(tp); 706 if ((t_flags&RAW)==0) { 707 if ((tp->t_lstate&LSTYPEN) == 0) 708 c &= 0177; 709 /* check for literal nexting very first */ 710 if (tp->t_lstate&LSLNCH) { 711 c |= 0200; 712 tp->t_lstate &= ~LSLNCH; 713 } 714 if (tp->t_line == NTTYDISC && c==tlun.t_lnextc) { 715 if (tp->t_flags&ECHO) 716 ttyout("^\b", tp); 717 tp->t_lstate |= LSLNCH; 718 /* check for output control functions */ 719 } else if (c==tun.t_stopc) { 720 if ((tp->t_state&TS_TTSTOP)==0) { 721 tp->t_state |= TS_TTSTOP; 722 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 723 return; 724 } 725 if (c!=tun.t_startc) 726 return; 727 } else if (c==tun.t_startc) { 728 tp->t_state &= ~TS_TTSTOP; 729 tp->t_local &= ~LFLUSHO; 730 ttstart(tp); 731 return; 732 } else if (tp->t_line == NTTYDISC && c==tlun.t_flushc) { 733 if (tp->t_local & LFLUSHO) 734 tp->t_local &= ~LFLUSHO; 735 else { 736 flushtty(tp, FWRITE); 737 ttyecho(c, tp); 738 if (tp->t_rawq.c_cc+tp->t_canq.c_cc) 739 ttyretype(tp); 740 tp->t_local |= LFLUSHO; 741 } 742 ttstart(tp); 743 return; 744 } else if (c==tun.t_intrc || c==tun.t_quitc || 745 (tp->t_line == NTTYDISC && c==tlun.t_suspc)) { 746 if ((tp->t_local & LNOFLSH) == 0) 747 flushtty(tp, 748 c==tlun.t_suspc ? FREAD : FREAD|FWRITE); 749 ttyecho(c, tp); 750 c = c==tun.t_intrc ? SIGINT : 751 ((c==tun.t_quitc) ? SIGQUIT : SIGTSTP); 752 ttsignal(tp, c); 753 /* check for buffer editing functions - cooked mode */ 754 } else if ((t_flags&CBREAK) == 0) { 755 if ((tp->t_lstate&LSQUOT) && 756 (c==tp->t_erase||c==tp->t_kill)) { 757 ttyrub(unputc(&tp->t_rawq), tp); 758 c |= 0200; 759 } 760 if (c==tp->t_erase) { 761 if (tp->t_rawq.c_cc) 762 ttyrub(unputc(&tp->t_rawq), tp); 763 } else if (c==tp->t_kill) { 764 if (tp->t_local&LCRTKIL && 765 tp->t_rawq.c_cc == tp->t_rocount) { 766 while (tp->t_rawq.c_cc) 767 ttyrub(unputc(&tp->t_rawq), tp); 768 } else { 769 ttyecho(c, tp); 770 ttyecho('\n', tp); 771 while (getc(&tp->t_rawq) > 0) 772 ; 773 tp->t_rocount = 0; 774 } 775 tp->t_lstate = 0; 776 } else if (tp->t_line == NTTYDISC && c==tlun.t_werasc) { 777 if (tp->t_rawq.c_cc == 0) 778 goto out; 779 do { 780 c = unputc(&tp->t_rawq); 781 if (c != ' ' && c != '\t') 782 goto erasenb; 783 ttyrub(c, tp); 784 } while (tp->t_rawq.c_cc); 785 goto out; 786 erasenb: 787 do { 788 ttyrub(c, tp); 789 if (tp->t_rawq.c_cc == 0) 790 goto out; 791 c = unputc(&tp->t_rawq); 792 } while (c != ' ' && c != '\t'); 793 (void) putc(c, &tp->t_rawq); 794 } else if (tp->t_line == NTTYDISC && c==tlun.t_rprntc) { 795 ttyretype(tp); 796 /* check for cooked mode input buffer overflow */ 797 } else if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 798 ; 799 /* put data char in q for user and wakeup if a break char */ 800 } else if (putc(c, &tp->t_rawq) >= 0) { 801 if (tp->t_rawq.c_cc+tp->t_canq.c_cc==TTYHOG 802 && tp->t_line == NTTYDISC) 803 (void) ttyoutput(CTRL(g), tp); 804 if (!ttbreakc(c, tp)) { 805 if (tp->t_rocount++ == 0) 806 tp->t_rocol = tp->t_col; 807 } else { 808 tp->t_rocount = 0; 809 catq(&tp->t_rawq, &tp->t_canq); 810 /* IF (TP->T_CHAN) (VOID) SDATA(TP->T_CHAN); */ 811 ttwakeup(tp); 812 } 813 tp->t_lstate &= ~LSQUOT; 814 if (c == '\\') 815 tp->t_lstate |= LSQUOT; 816 if (tp->t_lstate&LSERASE) { 817 tp->t_lstate &= ~LSERASE; 818 (void) ttyoutput('/', tp); 819 } 820 i = tp->t_col; 821 ttyecho(c, tp); 822 if (c==tun.t_eofc && tp->t_flags&ECHO) { 823 i = MIN(2, tp->t_col - i); 824 while (i > 0) { 825 (void) ttyoutput('\b', tp); 826 i--; 827 } 828 } 829 } 830 /* CBREAK mode */ 831 } else if (tp->t_rawq.c_cc > TTYHOG) { 832 if (tp->t_outq.c_cc < TTHIWAT(tp) && 833 tp->t_line == NTTYDISC) 834 (void) ttyoutput(CTRL(g), tp); 835 } else if (putc(c, &tp->t_rawq) >= 0) { 836 ttwakeup(tp); 837 ttyecho(c, tp); 838 } 839 /* RAW mode */ 840 } else if (tp->t_rawq.c_cc > TTYHOG) 841 flushtty(tp, FREAD|FWRITE); 842 else { 843 if (putc(c, &tp->t_rawq) >= 0) 844 ttwakeup(tp); 845 ttyecho(c, tp); 846 } 847 out: 848 if (tp->t_local & LDECCTQ && tp->t_state & TS_TTSTOP && 849 tun.t_startc != tun.t_stopc) 850 return; 851 tp->t_state &= ~TS_TTSTOP; 852 tp->t_local &= ~LFLUSHO; 853 ttstart(tp); 854 } 855 856 /* 857 * put character on TTY output queue, adding delays, 858 * expanding tabs, and handling the CR/NL bit. 859 * It is called both from the top half for output, and from 860 * interrupt level for echoing. 861 * The arguments are the character and the tty structure. 862 * Returns < 0 if putc succeeds, otherwise returns char to resend 863 * Must be recursive. 864 */ 865 ttyoutput(c, tp) 866 register c; 867 register struct tty *tp; 868 { 869 register char *colp; 870 register ctype; 871 872 if (tp->t_flags&RAW || tp->t_local&LLITOUT) { 873 if (tp->t_local&LFLUSHO) 874 return (-1); 875 if (putc(c, &tp->t_outq)) 876 return(c); 877 tk_nout++; 878 return (-1); 879 } 880 /* 881 * Ignore EOT in normal mode to avoid hanging up 882 * certain terminals. 883 */ 884 c &= 0177; 885 if (c==CEOT && (tp->t_flags&CBREAK)==0) 886 return (-1); 887 /* 888 * Turn tabs to spaces as required 889 */ 890 if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) { 891 register int s; 892 893 c = 8 - (tp->t_col&7); 894 if ((tp->t_local&LFLUSHO) == 0) { 895 s = spl5(); /* don't interrupt tabs */ 896 c -= b_to_q(" ", c, &tp->t_outq); 897 tk_nout += c; 898 splx(s); 899 } 900 tp->t_col += c; 901 return (c ? -1 : '\t'); 902 } 903 tk_nout++; 904 /* 905 * for upper-case-only terminals, 906 * generate escapes. 907 */ 908 if (tp->t_flags&LCASE) { 909 colp = "({)}!|^~'`"; 910 while(*colp++) 911 if(c == *colp++) { 912 if (ttyoutput('\\', tp) >= 0) 913 return (c); 914 c = colp[-2]; 915 break; 916 } 917 if ('A'<=c && c<='Z') { 918 if (ttyoutput('\\', tp) >= 0) 919 return (c); 920 } else if ('a'<=c && c<='z') 921 c += 'A' - 'a'; 922 } 923 /* 924 * turn <nl> to <cr><lf> if desired. 925 */ 926 if (c=='\n' && tp->t_flags&CRMOD) 927 if (ttyoutput('\r', tp) >= 0) 928 return (c); 929 if (c=='~' && tp->t_local<ILDE) 930 c = '`'; 931 if ((tp->t_local&LFLUSHO) == 0 && putc(c, &tp->t_outq)) 932 return (c); 933 /* 934 * Calculate delays. 935 * The numbers here represent clock ticks 936 * and are not necessarily optimal for all terminals. 937 * The delays are indicated by characters above 0200. 938 * In raw mode there are no delays and the 939 * transmission path is 8 bits wide. 940 */ 941 colp = &tp->t_col; 942 ctype = partab[c]; 943 c = 0; 944 switch (ctype&077) { 945 946 case ORDINARY: 947 (*colp)++; 948 949 case CONTROL: 950 break; 951 952 case BACKSPACE: 953 if (*colp) 954 (*colp)--; 955 break; 956 957 case NEWLINE: 958 ctype = (tp->t_flags >> 8) & 03; 959 if(ctype == 1) { /* tty 37 */ 960 if (*colp) 961 c = max(((unsigned)*colp>>4) + 3, (unsigned)6); 962 } else 963 if(ctype == 2) { /* vt05 */ 964 c = 6; 965 } 966 *colp = 0; 967 break; 968 969 case TAB: 970 ctype = (tp->t_flags >> 10) & 03; 971 if(ctype == 1) { /* tty 37 */ 972 c = 1 - (*colp | ~07); 973 if(c < 5) 974 c = 0; 975 } 976 *colp |= 07; 977 (*colp)++; 978 break; 979 980 case VTAB: 981 if(tp->t_flags & VTDELAY) /* tty 37 */ 982 c = 0177; 983 break; 984 985 case RETURN: 986 ctype = (tp->t_flags >> 12) & 03; 987 if(ctype == 1) { /* tn 300 */ 988 c = 5; 989 } else if(ctype == 2) { /* ti 700 */ 990 c = 10; 991 } else if(ctype == 3) { /* concept 100 */ 992 int i; 993 if ((i = *colp) >= 0) 994 for (; i<9; i++) 995 (void) putc(0177, &tp->t_outq); 996 } 997 *colp = 0; 998 } 999 if(c && (tp->t_local&LFLUSHO) == 0) 1000 (void) putc(c|0200, &tp->t_outq); 1001 return (-1); 1002 } 1003 1004 /* 1005 * Called from device's read routine after it has 1006 * calculated the tty-structure given as argument. 1007 */ 1008 ttread(tp) 1009 register struct tty *tp; 1010 { 1011 register struct clist *qp; 1012 register c, first; 1013 1014 if ((tp->t_state&TS_CARR_ON)==0) 1015 return(0); 1016 loop: 1017 (void) spl5(); 1018 if (tp->t_local&LPENDIN) 1019 ttypend(tp); 1020 (void) spl0(); 1021 while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 1022 if (u.u_signal[SIGTTIN] == SIG_IGN || 1023 u.u_signal[SIGTTIN] == SIG_HOLD || 1024 /* 1025 (u.u_procp->p_flag&SDETACH) || 1026 */ 1027 u.u_procp->p_flag&SVFORK) 1028 return (0); 1029 gsignal(u.u_procp->p_pgrp, SIGTTIN); 1030 sleep((caddr_t)&lbolt, TTIPRI); 1031 } 1032 if (tp->t_flags&RAW) { 1033 (void) spl5(); 1034 if (tp->t_rawq.c_cc <= 0) { 1035 if ((tp->t_state&TS_CARR_ON)==0 || 1036 (tp->t_state&TS_NBIO)) { 1037 (void) spl0(); 1038 return (0); 1039 } 1040 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1041 (void) spl0(); 1042 goto loop; 1043 } 1044 (void) spl0(); 1045 while (tp->t_rawq.c_cc && passc(getc(&tp->t_rawq))>=0) 1046 ; 1047 return (0); 1048 } else { 1049 qp = tp->t_flags & CBREAK ? &tp->t_rawq : &tp->t_canq; 1050 (void) spl5(); 1051 if (qp->c_cc <= 0) { 1052 if ((tp->t_state&TS_CARR_ON)==0 || 1053 (tp->t_state&TS_NBIO)) { 1054 (void) spl0(); 1055 return (0); 1056 } 1057 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1058 (void) spl0(); 1059 goto loop; 1060 } 1061 (void) spl0(); 1062 first = 1; 1063 while ((c = getc(qp)) >= 0) { 1064 if (tp->t_flags&CRMOD && c == '\r') 1065 c = '\n'; 1066 if (tp->t_flags&LCASE && c <= 0177) 1067 if (tp->t_lstate&LSBKSL) { 1068 if (maptab[c]) 1069 c = maptab[c]; 1070 tp->t_lstate &= ~LSBKSL; 1071 } else if (c >= 'A' && c <= 'Z') 1072 c += 'a' - 'A'; 1073 else if (c == '\\') { 1074 tp->t_lstate |= LSBKSL; 1075 continue; 1076 } 1077 if (c == tlun.t_dsuspc) { 1078 ttsignal(tp, SIGTSTP); 1079 if (first) { 1080 sleep((caddr_t)&lbolt, TTIPRI); 1081 goto loop; 1082 } 1083 break; 1084 } 1085 if (c == tun.t_eofc && (tp->t_flags&CBREAK)==0) 1086 break; 1087 if (passc(c & 0177) < 0) 1088 break; 1089 if ((tp->t_flags&CBREAK)==0 && ttbreakc(c, tp)) 1090 break; 1091 first = 0; 1092 } 1093 tp->t_lstate &= ~LSBKSL; 1094 } 1095 1096 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) { 1097 if (putc(tun.t_startc, &tp->t_outq)==0) { 1098 tp->t_state &= ~TS_TBLOCK; 1099 ttstart(tp); 1100 } 1101 tp->t_char = 0; 1102 } 1103 1104 return (tp->t_rawq.c_cc + tp->t_canq.c_cc); 1105 } 1106 1107 /* 1108 * Called from the device's write routine after it has 1109 * calculated the tty-structure given as argument. 1110 */ 1111 caddr_t 1112 ttwrite(tp) 1113 register struct tty *tp; 1114 { 1115 #ifdef vax 1116 /* 1117 * THE POSITIONING OF CP, CC, AND CE ARE CRITICAL 1118 * AND MUST NOT BE CHANGED WITHOUT PATCHING 1119 * THE 'ASM' INLINES BELOW. WATCH OUT. 1120 */ 1121 #endif 1122 register char *cp; 1123 register int cc, ce; 1124 register i; 1125 char obuf[OBUFSIZ]; 1126 register c; 1127 int hiwat = TTHIWAT(tp); 1128 int cnt = u.u_count; 1129 1130 if ((tp->t_state&TS_CARR_ON)==0) 1131 return (NULL); 1132 loop: 1133 while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 1134 (tp->t_local<OSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1135 u.u_signal[SIGTTOU] != SIG_IGN && 1136 u.u_signal[SIGTTOU] != SIG_HOLD 1137 /* 1138 && 1139 (u.u_procp->p_flag&SDETACH)==0) { 1140 */ 1141 ) { 1142 gsignal(u.u_procp->p_pgrp, SIGTTOU); 1143 sleep((caddr_t)&lbolt, TTIPRI); 1144 } 1145 while (u.u_count) { 1146 cc = MIN(u.u_count, OBUFSIZ); 1147 cp = obuf; 1148 iomove(cp, (unsigned)cc, B_WRITE); 1149 if (u.u_error) 1150 break; 1151 if (tp->t_outq.c_cc > hiwat) 1152 goto ovhiwat; 1153 if (tp->t_local&LFLUSHO) 1154 continue; 1155 if (tp->t_flags&LCASE || tp->t_local<ILDE) { 1156 while (cc) { 1157 c = *cp++; 1158 tp->t_rocount = 0; 1159 while((c = ttyoutput(c, tp)) >= 0) { 1160 /* out of clists, wait a bit */ 1161 ttstart(tp); 1162 sleep((caddr_t)&lbolt, TTOPRI); 1163 tp->t_rocount = 0; 1164 } 1165 --cc; 1166 if (tp->t_outq.c_cc > hiwat) 1167 goto ovhiwat; 1168 } 1169 continue; 1170 } 1171 while (cc) { 1172 if (tp->t_flags&RAW || tp->t_local&LLITOUT) 1173 ce = cc; 1174 else { 1175 #ifdef vax 1176 asm(" scanc r9,(r10),_partab,$077"); 1177 asm(" subl3 r0,r9,r8"); 1178 #else 1179 ce=0; 1180 while(((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce<cc)) 1181 ce++; 1182 #endif 1183 if (ce==0) { 1184 tp->t_rocount = 0; 1185 if (ttyoutput(*cp, tp) >= 0) { 1186 ttstart(tp); 1187 sleep((caddr_t)&lbolt, TTOPRI); 1188 continue; 1189 } 1190 cp++; 1191 cc--; 1192 if (tp->t_outq.c_cc > hiwat) 1193 goto ovhiwat; 1194 } 1195 } 1196 tp->t_rocount = 0; 1197 i=b_to_q(cp,ce,&tp->t_outq); 1198 ce-=i; 1199 tk_nout+=ce; 1200 tp->t_col+=ce; 1201 cp+=ce; 1202 cc-=ce; 1203 if (i) { 1204 ttstart(tp); 1205 sleep((caddr_t)&lbolt, TTOPRI); 1206 } 1207 if (ce || tp->t_outq.c_cc > hiwat) 1208 goto ovhiwat; 1209 } 1210 } 1211 ttstart(tp); 1212 return(NULL); 1213 1214 ovhiwat: 1215 (void) spl5(); 1216 u.u_base -= cc; 1217 u.u_offset -= cc; 1218 u.u_count += cc; 1219 if (tp->t_outq.c_cc <= hiwat) { 1220 (void) spl0(); 1221 goto loop; 1222 } 1223 ttstart(tp); 1224 if (tp->t_state & TS_NBIO) { 1225 if (u.u_count == cnt) 1226 u.u_error = EWOULDBLOCK; 1227 return (NULL); 1228 } 1229 tp->t_state |= TS_ASLEEP; 1230 sleep((caddr_t)&tp->t_outq, TTOPRI); 1231 (void) spl0(); 1232 goto loop; 1233 } 1234 1235 /* 1236 * Rubout one character from the rawq of tp 1237 * as cleanly as possible. 1238 */ 1239 ttyrub(c, tp) 1240 register c; 1241 register struct tty *tp; 1242 { 1243 register char *cp; 1244 register int savecol; 1245 int s; 1246 char *nextc(); 1247 1248 if ((tp->t_flags&ECHO)==0) 1249 return; 1250 tp->t_local &= ~LFLUSHO; 1251 c &= 0377; 1252 if (tp->t_local&LCRTBS) { 1253 if (tp->t_rocount == 0) { 1254 /* 1255 * Screwed by ttwrite; retype 1256 */ 1257 ttyretype(tp); 1258 return; 1259 } 1260 if (c==('\t'|0200) || c==('\n'|0200)) 1261 ttyrubo(tp, 2); 1262 else switch(partab[c&=0177] & 0177) { 1263 1264 case ORDINARY: 1265 if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z') 1266 ttyrubo(tp, 2); 1267 else 1268 ttyrubo(tp, 1); 1269 break; 1270 1271 case VTAB: 1272 case BACKSPACE: 1273 case CONTROL: 1274 case RETURN: 1275 if (tp->t_local & LCTLECH) 1276 ttyrubo(tp, 2); 1277 break; 1278 1279 case TAB: 1280 if (tp->t_rocount < tp->t_rawq.c_cc) { 1281 ttyretype(tp); 1282 return; 1283 } 1284 s = spl5(); 1285 savecol = tp->t_col; 1286 tp->t_lstate |= LSCNTTB; 1287 tp->t_local |= LFLUSHO; 1288 tp->t_col = tp->t_rocol; 1289 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1290 ttyecho(*cp, tp); 1291 tp->t_local &= ~LFLUSHO; 1292 tp->t_lstate &= ~LSCNTTB; 1293 splx(s); 1294 /* 1295 * savecol will now be length of the tab 1296 */ 1297 savecol -= tp->t_col; 1298 tp->t_col += savecol; 1299 if (savecol > 8) 1300 savecol = 8; /* overflow screw */ 1301 while (--savecol >= 0) 1302 (void) ttyoutput('\b', tp); 1303 break; 1304 1305 default: 1306 panic("ttyrub"); 1307 } 1308 } else if (tp->t_local&LPRTERA) { 1309 if ((tp->t_lstate&LSERASE) == 0) { 1310 (void) ttyoutput('\\', tp); 1311 tp->t_lstate |= LSERASE; 1312 } 1313 ttyecho(c, tp); 1314 } else 1315 ttyecho(tp->t_erase, tp); 1316 tp->t_rocount--; 1317 } 1318 1319 /* 1320 * Crt back over cnt chars perhaps 1321 * erasing them. 1322 */ 1323 ttyrubo(tp, cnt) 1324 register struct tty *tp; 1325 int cnt; 1326 { 1327 1328 while (--cnt >= 0) 1329 ttyout(tp->t_local&LCRTERA ? "\b \b" : "\b", tp); 1330 } 1331 1332 /* 1333 * Reprint the rawq line. 1334 * We assume c_cc has already been checked. 1335 */ 1336 ttyretype(tp) 1337 register struct tty *tp; 1338 { 1339 register char *cp; 1340 char *nextc(); 1341 int s; 1342 1343 if (tlun.t_rprntc != 0377) 1344 ttyecho(tlun.t_rprntc, tp); 1345 (void) ttyoutput('\n', tp); 1346 s = spl5(); 1347 for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp)) 1348 ttyecho(*cp, tp); 1349 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1350 ttyecho(*cp, tp); 1351 tp->t_lstate &= ~LSERASE; 1352 splx(s); 1353 tp->t_rocount = tp->t_rawq.c_cc; 1354 tp->t_rocol = 0; 1355 } 1356 1357 /* 1358 * Echo a typed character to the terminal 1359 */ 1360 ttyecho(c, tp) 1361 register c; 1362 register struct tty *tp; 1363 { 1364 1365 if ((tp->t_lstate & LSCNTTB) == 0) 1366 tp->t_local &= ~LFLUSHO; 1367 if ((tp->t_flags&ECHO) == 0) 1368 return; 1369 c &= 0377; 1370 if (tp->t_flags&RAW) { 1371 (void) ttyoutput(c, tp); 1372 return; 1373 } 1374 if (c == '\r' && tp->t_flags&CRMOD) 1375 c = '\n'; 1376 if (tp->t_local&LCTLECH) { 1377 if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) { 1378 (void) ttyoutput('^', tp); 1379 c &= 0177; 1380 if (c == 0177) 1381 c = '?'; 1382 else if (tp->t_flags&LCASE) 1383 c += 'a' - 1; 1384 else 1385 c += 'A' - 1; 1386 } 1387 } 1388 if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z')) 1389 c += 'a' - 'A'; 1390 (void) ttyoutput(c & 0177, tp); 1391 } 1392 1393 /* 1394 * Is c a break char for tp? 1395 */ 1396 ttbreakc(c, tp) 1397 register c; 1398 register struct tty *tp; 1399 { 1400 return (c == '\n' || c == tun.t_eofc || c == tun.t_brkc || 1401 c == '\r' && (tp->t_flags&CRMOD)); 1402 } 1403 1404 /* 1405 * send string cp to tp 1406 */ 1407 ttyout(cp, tp) 1408 register char *cp; 1409 register struct tty *tp; 1410 { 1411 register char c; 1412 1413 while (c = *cp++) 1414 (void) ttyoutput(c, tp); 1415 } 1416 1417 ttwakeup(tp) 1418 struct tty *tp; 1419 { 1420 1421 if (tp->t_rsel) { 1422 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1423 tp->t_state &= ~TS_RCOLL; 1424 tp->t_rsel = 0; 1425 } 1426 wakeup((caddr_t)&tp->t_rawq); 1427 } 1428 1429 ttsignal(tp, signo) 1430 struct tty *tp; 1431 int signo; 1432 { 1433 1434 gsignal(tp->t_pgrp, signo); 1435 } 1436