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