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