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