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