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