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