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