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