1 /* tty.c 4.40 83/02/10 */ 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 return (ENXIO); 277 s = spl5(); 278 if (tp->t_line) 279 (*linesw[tp->t_line].l_close)(tp); 280 if (t) 281 error = (*linesw[t].l_open)(dev, tp); 282 splx(s); 283 if (error) { 284 s = spl5(); 285 if (tp->t_line) 286 (void) (*linesw[tp->t_line].l_open)(dev, tp); 287 splx(s); 288 return (error); 289 } 290 tp->t_line = t; 291 break; 292 } 293 294 /* prevent more opens on channel */ 295 case TIOCEXCL: 296 tp->t_state |= TS_XCLUDE; 297 break; 298 299 case TIOCNXCL: 300 tp->t_state &= ~TS_XCLUDE; 301 break; 302 303 case TIOCSET: 304 case TIOCBIS: { 305 u_long newflags = *(u_long *)data; 306 307 s = spl5(); 308 if (tp->t_flags&RAW || newflags&RAW) 309 wflushtty(tp); 310 else if ((tp->t_flags&CBREAK) != (newflags&CBREAK)) 311 if (newflags&CBREAK) { 312 struct clist tq; 313 314 catq(&tp->t_rawq, &tp->t_canq); 315 tq = tp->t_rawq; 316 tp->t_rawq = tp->t_canq; 317 tp->t_canq = tq; 318 } else { 319 tp->t_flags |= PENDIN; 320 ttwakeup(tp); 321 } 322 if (com == TIOCSET) 323 tp->t_flags = newflags; 324 else 325 tp->t_flags |= newflags; 326 if (tp->t_flags&RAW) { 327 tp->t_state &= ~TS_TTSTOP; 328 ttstart(tp); 329 } 330 splx(s); 331 break; 332 } 333 334 case TIOCBIC: { 335 u_long newflags = *(long *)data; 336 337 if (tp->t_flags&RAW) 338 wflushtty(tp); 339 else if ((tp->t_flags&CBREAK) != (CBREAK&~newflags)) 340 if (newflags&CBREAK) { 341 tp->t_flags |= PENDIN; 342 ttwakeup(tp); 343 } else { 344 struct clist tq; 345 346 catq(&tp->t_rawq, &tp->t_canq); 347 tq = tp->t_rawq; 348 tp->t_rawq = tp->t_canq; 349 tp->t_canq = tq; 350 } 351 if (tp->t_flags&RAW) { 352 tp->t_state &= ~TS_TTSTOP; 353 ttstart(tp); 354 } 355 splx(s); 356 break; 357 } 358 359 case TIOCGET: 360 *(long *)data = tp->t_flags; 361 break; 362 363 case TIOCCGET: 364 bcopy((caddr_t)&tp->t_chars, data, sizeof (struct ttychars)); 365 break; 366 367 case TIOCCSET: 368 bcopy(data, (caddr_t)&tp->t_chars, sizeof (struct ttychars)); 369 break; 370 371 /* hang up line on last close */ 372 case TIOCHPCL: 373 tp->t_state |= TS_HUPCLS; 374 break; 375 376 case TIOCFLUSH: { 377 register int flags = *(int *)data; 378 379 if (flags == 0) 380 flags = FREAD|FWRITE; 381 else 382 flags &= FREAD|FWRITE; 383 flushtty(tp, flags); 384 break; 385 } 386 387 /* return number of characters immediately available */ 388 case FIONREAD: 389 *(off_t *)data = ttnread(tp); 390 break; 391 392 case TIOCSTOP: 393 s = spl5(); 394 if ((tp->t_state&TS_TTSTOP) == 0) { 395 tp->t_state |= TS_TTSTOP; 396 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 397 } 398 splx(s); 399 break; 400 401 case TIOCSTART: 402 s = spl5(); 403 if ((tp->t_state&TS_TTSTOP) || (tp->t_flags&FLUSHO)) { 404 tp->t_state &= ~TS_TTSTOP; 405 tp->t_flags &= ~FLUSHO; 406 ttstart(tp); 407 } 408 splx(s); 409 break; 410 411 /* 412 * Simulate typing of a character at the terminal. 413 */ 414 case TIOCSTI: 415 if (u.u_uid && u.u_ttyp != tp) 416 return (EACCES); 417 (*linesw[tp->t_line].l_rint)(*(char *)data, tp); 418 break; 419 420 default: 421 #ifndef NOCOMPAT 422 return (ottioctl(tp, com, data, flag)); 423 #else 424 return (-1); 425 #endif 426 } 427 return (0); 428 } 429 430 ttnread(tp) 431 struct tty *tp; 432 { 433 int nread = 0; 434 435 if (tp->t_flags & PENDIN) 436 ttypend(tp); 437 nread = tp->t_canq.c_cc; 438 if (tp->t_flags & (RAW|CBREAK)) 439 nread += tp->t_rawq.c_cc; 440 return (nread); 441 } 442 443 ttselect(dev, rw) 444 dev_t dev; 445 int rw; 446 { 447 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 448 int nread; 449 int s = spl5(); 450 451 switch (rw) { 452 453 case FREAD: 454 nread = ttnread(tp); 455 if (nread > 0) 456 goto win; 457 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 458 tp->t_state |= TS_RCOLL; 459 else 460 tp->t_rsel = u.u_procp; 461 break; 462 463 case FWRITE: 464 if (tp->t_outq.c_cc <= TTLOWAT(tp)) 465 goto win; 466 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 467 tp->t_state |= TS_WCOLL; 468 else 469 tp->t_wsel = u.u_procp; 470 break; 471 } 472 splx(s); 473 return (0); 474 win: 475 splx(s); 476 return (1); 477 } 478 479 /* 480 * Establish a process group for distribution of 481 * quits and interrupts from the tty. 482 */ 483 ttyopen(dev, tp) 484 dev_t dev; 485 register struct tty *tp; 486 { 487 register struct proc *pp; 488 489 pp = u.u_procp; 490 tp->t_dev = dev; 491 if (pp->p_pgrp == 0) { 492 u.u_ttyp = tp; 493 u.u_ttyd = dev; 494 if (tp->t_pgrp == 0) 495 tp->t_pgrp = pp->p_pid; 496 pp->p_pgrp = tp->t_pgrp; 497 } 498 tp->t_state &= ~TS_WOPEN; 499 tp->t_state |= TS_ISOPEN; 500 if (tp->t_line != NTTYDISC) 501 wflushtty(tp); 502 return (0); 503 } 504 505 /* 506 * clean tp on last close 507 */ 508 ttyclose(tp) 509 register struct tty *tp; 510 { 511 512 if (tp->t_line) { 513 wflushtty(tp); 514 tp->t_line = 0; 515 return; 516 } 517 tp->t_pgrp = 0; 518 wflushtty(tp); 519 tp->t_state = 0; 520 } 521 522 /* 523 * reinput pending characters after state switch 524 * call at spl5(). 525 */ 526 ttypend(tp) 527 register struct tty *tp; 528 { 529 struct clist tq; 530 register c; 531 532 tp->t_flags &= ~PENDIN; 533 tp->t_state |= TS_TYPEN; 534 tq = tp->t_rawq; 535 tp->t_rawq.c_cc = 0; 536 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 537 while ((c = getc(&tq)) >= 0) 538 ttyinput(c, tp); 539 tp->t_state &= ~TS_TYPEN; 540 } 541 542 /* 543 * Place a character on raw TTY input queue, 544 * putting in delimiters and waking up top 545 * half as needed. Also echo if required. 546 * The arguments are the character and the 547 * appropriate tty structure. 548 */ 549 ttyinput(c, tp) 550 register c; 551 register struct tty *tp; 552 { 553 register int t_flags = tp->t_flags; 554 int i; 555 556 /* 557 * If input is pending take it first. 558 */ 559 if (t_flags&PENDIN) 560 ttypend(tp); 561 tk_nin++; 562 c &= 0377; 563 564 /* 565 * In tandem mode, check high water mark. 566 */ 567 if (t_flags&TANDEM) 568 ttyblock(tp); 569 570 if (t_flags&RAW) { 571 /* 572 * Raw mode, just put character 573 * in input q w/o interpretation. 574 */ 575 if (tp->t_rawq.c_cc > TTYHOG) 576 flushtty(tp, FREAD|FWRITE); 577 else { 578 if (putc(c, &tp->t_rawq) >= 0) 579 ttwakeup(tp); 580 ttyecho(c, tp); 581 } 582 goto endcase; 583 } 584 585 /* 586 * Ignore any high bit added during 587 * previous ttyinput processing. 588 */ 589 if ((tp->t_state&TS_TYPEN) == 0) 590 c &= 0177; 591 /* 592 * Check for literal nexting very first 593 */ 594 if (tp->t_state&TS_LNCH) { 595 c |= 0200; 596 tp->t_state &= ~TS_LNCH; 597 } 598 599 /* 600 * Scan for special characters. This code 601 * is really just a big case statement with 602 * non-constant cases. The bottom of the 603 * case statement is labeled ``endcase'', so goto 604 * it after a case match, or similar. 605 */ 606 if (tp->t_line == NTTYDISC) { 607 if (c == tp->t_lnextc) { 608 if (tp->t_flags&ECHO) 609 ttyout("^\b", tp); 610 tp->t_state |= TS_LNCH; 611 goto endcase; 612 } 613 if (c == tp->t_flushc) { 614 if (tp->t_flags&FLUSHO) 615 tp->t_flags &= ~FLUSHO; 616 else { 617 flushtty(tp, FWRITE); 618 ttyecho(c, tp); 619 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 620 ttyretype(tp); 621 tp->t_flags |= FLUSHO; 622 } 623 goto startoutput; 624 } 625 if (c == tp->t_suspc) { 626 if ((tp->t_flags&NOFLSH) == 0) 627 flushtty(tp, FREAD); 628 ttyecho(c, tp); 629 gsignal(tp->t_pgrp, SIGTSTP); 630 goto endcase; 631 } 632 } 633 634 /* 635 * Handle start/stop characters. 636 */ 637 if (c == tp->t_stopc) { 638 if ((tp->t_state&TS_TTSTOP) == 0) { 639 tp->t_state |= TS_TTSTOP; 640 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 641 return; 642 } 643 if (c != tp->t_startc) 644 return; 645 goto endcase; 646 } 647 if (c == tp->t_startc) 648 goto restartoutput; 649 650 /* 651 * Look for interrupt/quit chars. 652 */ 653 if (c == tp->t_intrc || c == tp->t_quitc) { 654 if ((tp->t_flags&NOFLSH) == 0) 655 flushtty(tp, FREAD|FWRITE); 656 ttyecho(c, tp); 657 gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT); 658 goto endcase; 659 } 660 661 /* 662 * Cbreak mode, don't process line editing 663 * characters; check high water mark for wakeup. 664 */ 665 if (t_flags&CBREAK) { 666 if (tp->t_rawq.c_cc > TTYHOG) { 667 if (tp->t_outq.c_cc < TTHIWAT(tp) && 668 tp->t_line == NTTYDISC) 669 (void) ttyoutput(CTRL(g), tp); 670 } else if (putc(c, &tp->t_rawq) >= 0) { 671 ttwakeup(tp); 672 ttyecho(c, tp); 673 } 674 goto endcase; 675 } 676 677 /* 678 * From here on down cooked mode character 679 * processing takes place. 680 */ 681 if ((tp->t_state&TS_QUOT) && 682 (c == tp->t_erase || c == tp->t_kill)) { 683 ttyrub(unputc(&tp->t_rawq), tp); 684 c |= 0200; 685 } 686 if (c == tp->t_erase) { 687 if (tp->t_rawq.c_cc) 688 ttyrub(unputc(&tp->t_rawq), tp); 689 goto endcase; 690 } 691 if (c == tp->t_kill) { 692 if (tp->t_flags&CRTKIL && 693 tp->t_rawq.c_cc == tp->t_rocount) { 694 while (tp->t_rawq.c_cc) 695 ttyrub(unputc(&tp->t_rawq), tp); 696 } else { 697 ttyecho(c, tp); 698 ttyecho('\n', tp); 699 while (getc(&tp->t_rawq) > 0) 700 ; 701 tp->t_rocount = 0; 702 } 703 tp->t_state &= ~TS_LOCAL; 704 goto endcase; 705 } 706 707 /* 708 * New line discipline, 709 * check word erase/reprint line. 710 */ 711 if (tp->t_line == NTTYDISC) { 712 if (c == tp->t_werasc) { 713 if (tp->t_rawq.c_cc == 0) 714 goto endcase; 715 do { 716 c = unputc(&tp->t_rawq); 717 if (c != ' ' && c != '\t') 718 goto erasenb; 719 ttyrub(c, tp); 720 } while (tp->t_rawq.c_cc); 721 goto endcase; 722 erasenb: 723 do { 724 ttyrub(c, tp); 725 if (tp->t_rawq.c_cc == 0) 726 goto endcase; 727 c = unputc(&tp->t_rawq); 728 } while (c != ' ' && c != '\t'); 729 (void) putc(c, &tp->t_rawq); 730 goto endcase; 731 } 732 if (c == tp->t_rprntc) { 733 ttyretype(tp); 734 goto endcase; 735 } 736 } 737 738 /* 739 * Check for input buffer overflow 740 */ 741 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 742 if (tp->t_line == NTTYDISC) 743 (void) ttyoutput(CTRL(g), tp); 744 goto endcase; 745 } 746 747 /* 748 * Put data char in q for user and 749 * wakeup on seeing a line delimiter. 750 */ 751 if (putc(c, &tp->t_rawq) >= 0) { 752 if (ttbreakc(c, tp)) { 753 tp->t_rocount = 0; 754 catq(&tp->t_rawq, &tp->t_canq); 755 ttwakeup(tp); 756 } else if (tp->t_rocount++ == 0) 757 tp->t_rocol = tp->t_col; 758 tp->t_state &= ~TS_QUOT; 759 if (c == '\\') 760 tp->t_state |= TS_QUOT; 761 if (tp->t_state&TS_ERASE) { 762 tp->t_state &= ~TS_ERASE; 763 (void) ttyoutput('/', tp); 764 } 765 i = tp->t_col; 766 ttyecho(c, tp); 767 if (c == tp->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 776 endcase: 777 /* 778 * If DEC-style start/stop is enabled don't restart 779 * output until seeing the start character. 780 */ 781 if (tp->t_flags&DECCTQ && tp->t_state&TS_TTSTOP && 782 tp->t_startc != tp->t_stopc) 783 return; 784 785 restartoutput: 786 tp->t_state &= ~TS_TTSTOP; 787 tp->t_flags &= ~FLUSHO; 788 789 startoutput: 790 ttstart(tp); 791 } 792 793 /* 794 * Put character on TTY output queue, adding delays, 795 * expanding tabs, and handling the CR/NL bit. 796 * This is called both from the top half for output, 797 * and from interrupt level for echoing. 798 * The arguments are the character and the tty structure. 799 * Returns < 0 if putc succeeds, otherwise returns char to resend 800 * Must be recursive. 801 */ 802 ttyoutput(c, tp) 803 register c; 804 register struct tty *tp; 805 { 806 register char *colp; 807 register ctype; 808 809 if (tp->t_flags & (RAW|LITOUT)) { 810 if (tp->t_flags&FLUSHO) 811 return (-1); 812 if (putc(c, &tp->t_outq)) 813 return (c); 814 tk_nout++; 815 return (-1); 816 } 817 818 /* 819 * Ignore EOT in normal mode to avoid 820 * hanging up certain terminals. 821 */ 822 c &= 0177; 823 if (c == CEOT && (tp->t_flags&CBREAK) == 0) 824 return (-1); 825 /* 826 * Turn tabs to spaces as required 827 */ 828 if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) { 829 register int s; 830 831 c = 8 - (tp->t_col&7); 832 if ((tp->t_flags&FLUSHO) == 0) { 833 s = spl5(); /* don't interrupt tabs */ 834 c -= b_to_q(" ", c, &tp->t_outq); 835 tk_nout += c; 836 splx(s); 837 } 838 tp->t_col += c; 839 return (c ? -1 : '\t'); 840 } 841 tk_nout++; 842 /* 843 * for upper-case-only terminals, 844 * generate escapes. 845 */ 846 if (tp->t_flags&LCASE) { 847 colp = "({)}!|^~'`"; 848 while (*colp++) 849 if (c == *colp++) { 850 if (ttyoutput('\\', tp) >= 0) 851 return (c); 852 c = colp[-2]; 853 break; 854 } 855 if ('A' <= c && c <= 'Z') { 856 if (ttyoutput('\\', tp) >= 0) 857 return (c); 858 } else if ('a' <= c && c <= 'z') 859 c += 'A' - 'a'; 860 } 861 862 /* 863 * turn <nl> to <cr><lf> if desired. 864 */ 865 if (c == '\n' && tp->t_flags&CRMOD) 866 if (ttyoutput('\r', tp) >= 0) 867 return (c); 868 if (c == '~' && tp->t_flags&TILDE) 869 c = '`'; 870 if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq)) 871 return (c); 872 /* 873 * Calculate delays. 874 * The numbers here represent clock ticks 875 * and are not necessarily optimal for all terminals. 876 * The delays are indicated by characters above 0200. 877 * In raw mode there are no delays and the 878 * transmission path is 8 bits wide. 879 * 880 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 881 */ 882 colp = &tp->t_col; 883 ctype = partab[c]; 884 c = 0; 885 switch (ctype&077) { 886 887 case ORDINARY: 888 (*colp)++; 889 890 case CONTROL: 891 break; 892 893 case BACKSPACE: 894 if (*colp) 895 (*colp)--; 896 break; 897 898 case NEWLINE: 899 ctype = (tp->t_flags >> 8) & 03; 900 if (ctype == 1) { /* tty 37 */ 901 if (*colp) 902 c = max(((unsigned)*colp>>4) + 3, (unsigned)6); 903 } else if (ctype == 2) /* vt05 */ 904 c = 6; 905 *colp = 0; 906 break; 907 908 case TAB: 909 ctype = (tp->t_flags >> 10) & 03; 910 if (ctype == 1) { /* tty 37 */ 911 c = 1 - (*colp | ~07); 912 if (c < 5) 913 c = 0; 914 } 915 *colp |= 07; 916 (*colp)++; 917 break; 918 919 case VTAB: 920 if (tp->t_flags&VTDELAY) /* tty 37 */ 921 c = 0177; 922 break; 923 924 case RETURN: 925 ctype = (tp->t_flags >> 12) & 03; 926 if (ctype == 1) /* tn 300 */ 927 c = 5; 928 else if (ctype == 2) /* ti 700 */ 929 c = 10; 930 else if (ctype == 3) { /* concept 100 */ 931 int i; 932 933 if ((i = *colp) >= 0) 934 for (; i < 9; i++) 935 (void) putc(0177, &tp->t_outq); 936 } 937 *colp = 0; 938 } 939 if (c && (tp->t_flags&FLUSHO) == 0) 940 (void) putc(c|0200, &tp->t_outq); 941 return (-1); 942 } 943 944 /* 945 * Called from device's read routine after it has 946 * calculated the tty-structure given as argument. 947 */ 948 ttread(tp, uio) 949 register struct tty *tp; 950 struct uio *uio; 951 { 952 register struct clist *qp; 953 register c, t_flags; 954 int s, first, error = 0; 955 956 if ((tp->t_state&TS_CARR_ON)==0) 957 return (EIO); 958 loop: 959 /* 960 * Take any pending input first. 961 */ 962 s = spl5(); 963 if (tp->t_flags&PENDIN) 964 ttypend(tp); 965 splx(s); 966 967 /* 968 * Hang process if it's in the background. 969 */ 970 while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 971 if (u.u_signal[SIGTTIN] == SIG_IGN || 972 u.u_signal[SIGTTIN] == SIG_HOLD || 973 /* 974 (u.u_procp->p_flag&SDETACH) || 975 */ 976 u.u_procp->p_flag&SVFORK) 977 return (EIO); 978 gsignal(u.u_procp->p_pgrp, SIGTTIN); 979 sleep((caddr_t)&lbolt, TTIPRI); 980 } 981 t_flags = tp->t_flags; 982 983 /* 984 * In raw mode take characters directly from the 985 * raw queue w/o processing. Interlock against 986 * device interrupts when interrogating rawq. 987 */ 988 if (t_flags&RAW) { 989 s = spl5(); 990 if (tp->t_rawq.c_cc <= 0) { 991 if ((tp->t_state&TS_CARR_ON) == 0 || 992 (tp->t_state&TS_NBIO)) { 993 splx(s); 994 return (0); 995 } 996 sleep((caddr_t)&tp->t_rawq, TTIPRI); 997 splx(s); 998 goto loop; 999 } 1000 splx(s); 1001 while (!error && tp->t_rawq.c_cc && uio->uio_iovcnt) 1002 error = passuc(getc(&tp->t_rawq), uio); 1003 goto checktandem; 1004 } 1005 1006 /* 1007 * In cbreak mode use the rawq, otherwise 1008 * take characters from the canonicalized q. 1009 */ 1010 qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq; 1011 1012 /* 1013 * No input, sleep on rawq awaiting hardware 1014 * receipt and notification. 1015 */ 1016 s = spl5(); 1017 if (qp->c_cc <= 0) { 1018 if ((tp->t_state&TS_CARR_ON) == 0 || 1019 (tp->t_state&TS_NBIO)) { 1020 splx(s); 1021 return (EWOULDBLOCK); 1022 } 1023 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1024 splx(s); 1025 goto loop; 1026 } 1027 splx(s); 1028 1029 /* 1030 * Input present, perform input mapping 1031 * and processing (we're not in raw mode). 1032 */ 1033 first = 1; 1034 while ((c = getc(qp)) >= 0) { 1035 if (t_flags&CRMOD && c == '\r') 1036 c = '\n'; 1037 /* 1038 * Hack lower case simulation on 1039 * upper case only terminals. 1040 */ 1041 if (t_flags&LCASE && c <= 0177) 1042 if (tp->t_state&TS_BKSL) { 1043 if (maptab[c]) 1044 c = maptab[c]; 1045 tp->t_state &= ~TS_BKSL; 1046 } else if (c >= 'A' && c <= 'Z') 1047 c += 'a' - 'A'; 1048 else if (c == '\\') { 1049 tp->t_state |= TS_BKSL; 1050 continue; 1051 } 1052 /* 1053 * Check for delayed suspend character. 1054 */ 1055 if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) { 1056 gsignal(tp->t_pgrp, SIGTSTP); 1057 if (first) { 1058 sleep((caddr_t)&lbolt, TTIPRI); 1059 goto loop; 1060 } 1061 break; 1062 } 1063 /* 1064 * Interpret EOF only in cooked mode. 1065 */ 1066 if (c == tp->t_eofc && (t_flags&CBREAK) == 0) 1067 break; 1068 /* 1069 * Give user character. 1070 */ 1071 error = passuc(c & 0177, uio); 1072 if (error) 1073 break; 1074 if (uio->uio_iovcnt == 0) 1075 break; 1076 /* 1077 * In cooked mode check for a "break character" 1078 * marking the end of a "line of input". 1079 */ 1080 if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp)) 1081 break; 1082 first = 0; 1083 } 1084 tp->t_state &= ~TS_BKSL; 1085 1086 checktandem: 1087 /* 1088 * Look to unblock output now that (presumably) 1089 * the input queue has gone down. 1090 */ 1091 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) 1092 if (putc(tp->t_startc, &tp->t_outq) == 0) { 1093 tp->t_state &= ~TS_TBLOCK; 1094 ttstart(tp); 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 #if !defined(vax) && !defined(sun) 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