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