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