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