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.22 (Berkeley) 11/04/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 * reinput pending characters after state switch 658 * call at spltty(). 659 */ 660 ttypend(tp) 661 register struct tty *tp; 662 { 663 struct clist tq; 664 register c; 665 666 tp->t_flags &= ~PENDIN; 667 tp->t_state |= TS_TYPEN; 668 tq = tp->t_rawq; 669 tp->t_rawq.c_cc = 0; 670 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 671 while ((c = getc(&tq)) >= 0) 672 ttyinput(c, tp); 673 tp->t_state &= ~TS_TYPEN; 674 } 675 676 /* 677 * Place a character on raw TTY input queue, 678 * putting in delimiters and waking up top 679 * half as needed. Also echo if required. 680 * The arguments are the character and the 681 * appropriate tty structure. 682 */ 683 ttyinput(c, tp) 684 register c; 685 register struct tty *tp; 686 { 687 register int t_flags = tp->t_flags; 688 int i; 689 690 /* 691 * If input is pending take it first. 692 */ 693 if (t_flags&PENDIN) 694 ttypend(tp); 695 tk_nin++; 696 c &= 0377; 697 698 /* 699 * In tandem mode, check high water mark. 700 */ 701 if (t_flags&TANDEM) 702 ttyblock(tp); 703 704 if (t_flags&RAW) { 705 /* 706 * Raw mode, just put character 707 * in input q w/o interpretation. 708 */ 709 if (tp->t_rawq.c_cc > TTYHOG) 710 ttyflush(tp, FREAD|FWRITE); 711 else { 712 if (putc(c, &tp->t_rawq) >= 0) 713 ttwakeup(tp); 714 ttyecho(c, tp); 715 } 716 goto endcase; 717 } 718 719 /* 720 * Ignore any high bit added during 721 * previous ttyinput processing. 722 */ 723 if ((tp->t_state&TS_TYPEN) == 0 && (t_flags&PASS8) == 0) 724 c &= 0177; 725 /* 726 * Check for literal nexting very first 727 */ 728 if (tp->t_state&TS_LNCH) { 729 c |= 0200; 730 tp->t_state &= ~TS_LNCH; 731 } 732 733 /* 734 * Scan for special characters. This code 735 * is really just a big case statement with 736 * non-constant cases. The bottom of the 737 * case statement is labeled ``endcase'', so goto 738 * it after a case match, or similar. 739 */ 740 if (tp->t_line == NTTYDISC) { 741 if (c == tp->t_lnextc) { 742 if (t_flags&ECHO) 743 ttyout("^\b", tp); 744 tp->t_state |= TS_LNCH; 745 goto endcase; 746 } 747 if (c == tp->t_flushc) { 748 if (t_flags&FLUSHO) 749 tp->t_flags &= ~FLUSHO; 750 else { 751 ttyflush(tp, FWRITE); 752 ttyecho(c, tp); 753 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 754 ttyretype(tp); 755 tp->t_flags |= FLUSHO; 756 } 757 goto startoutput; 758 } 759 if (c == tp->t_suspc) { 760 if ((t_flags&NOFLSH) == 0) 761 ttyflush(tp, FREAD); 762 ttyecho(c, tp); 763 gsignal(tp->t_pgrp, SIGTSTP); 764 goto endcase; 765 } 766 } 767 768 /* 769 * Handle start/stop characters. 770 */ 771 if (c == tp->t_stopc) { 772 if ((tp->t_state&TS_TTSTOP) == 0) { 773 tp->t_state |= TS_TTSTOP; 774 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 775 return; 776 } 777 if (c != tp->t_startc) 778 return; 779 goto endcase; 780 } 781 if (c == tp->t_startc) 782 goto restartoutput; 783 784 /* 785 * Look for interrupt/quit chars. 786 */ 787 if (c == tp->t_intrc || c == tp->t_quitc) { 788 if ((t_flags&NOFLSH) == 0) 789 ttyflush(tp, FREAD|FWRITE); 790 ttyecho(c, tp); 791 gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT); 792 goto endcase; 793 } 794 795 if (tp->t_flags & LCASE && c <= 0177) { 796 if (tp->t_state&TS_BKSL) { 797 ttyrub(unputc(&tp->t_rawq), tp); 798 if (maptab[c]) 799 c = maptab[c]; 800 c |= 0200; 801 tp->t_state &= ~(TS_BKSL|TS_QUOT); 802 } else if (c >= 'A' && c <= 'Z') 803 c += 'a' - 'A'; 804 else if (c == '\\') 805 tp->t_state |= TS_BKSL; 806 } 807 808 /* 809 * Cbreak mode, don't process line editing 810 * characters; check high water mark for wakeup. 811 */ 812 if (t_flags&CBREAK) { 813 if (tp->t_rawq.c_cc > TTYHOG) { 814 if (tp->t_outq.c_cc < TTHIWAT(tp) && 815 tp->t_line == NTTYDISC) 816 (void) ttyoutput(CTRL(g), tp); 817 } else if (putc(c, &tp->t_rawq) >= 0) { 818 ttwakeup(tp); 819 ttyecho(c, tp); 820 } 821 goto endcase; 822 } 823 824 /* 825 * From here on down cooked mode character 826 * processing takes place. 827 */ 828 if ((tp->t_state&TS_QUOT) && 829 (c == tp->t_erase || c == tp->t_kill)) { 830 ttyrub(unputc(&tp->t_rawq), tp); 831 c |= 0200; 832 } 833 if (c == tp->t_erase) { 834 if (tp->t_rawq.c_cc) 835 ttyrub(unputc(&tp->t_rawq), tp); 836 goto endcase; 837 } 838 if (c == tp->t_kill) { 839 if (t_flags&CRTKIL && 840 tp->t_rawq.c_cc == tp->t_rocount) { 841 while (tp->t_rawq.c_cc) 842 ttyrub(unputc(&tp->t_rawq), tp); 843 } else { 844 ttyecho(c, tp); 845 ttyecho('\n', tp); 846 while (getc(&tp->t_rawq) > 0) 847 ; 848 tp->t_rocount = 0; 849 } 850 tp->t_state &= ~TS_LOCAL; 851 goto endcase; 852 } 853 854 /* 855 * New line discipline, 856 * check word erase/reprint line. 857 */ 858 if (tp->t_line == NTTYDISC) { 859 if (c == tp->t_werasc) { 860 if (tp->t_rawq.c_cc == 0) 861 goto endcase; 862 do { 863 c = unputc(&tp->t_rawq); 864 if (c != ' ' && c != '\t') 865 goto erasenb; 866 ttyrub(c, tp); 867 } while (tp->t_rawq.c_cc); 868 goto endcase; 869 erasenb: 870 do { 871 ttyrub(c, tp); 872 if (tp->t_rawq.c_cc == 0) 873 goto endcase; 874 c = unputc(&tp->t_rawq); 875 } while (c != ' ' && c != '\t'); 876 (void) putc(c, &tp->t_rawq); 877 goto endcase; 878 } 879 if (c == tp->t_rprntc) { 880 ttyretype(tp); 881 goto endcase; 882 } 883 } 884 885 /* 886 * Check for input buffer overflow 887 */ 888 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 889 if (tp->t_line == NTTYDISC) 890 (void) ttyoutput(CTRL(g), tp); 891 goto endcase; 892 } 893 894 /* 895 * Put data char in q for user and 896 * wakeup on seeing a line delimiter. 897 */ 898 if (putc(c, &tp->t_rawq) >= 0) { 899 if (ttbreakc(c, tp)) { 900 tp->t_rocount = 0; 901 catq(&tp->t_rawq, &tp->t_canq); 902 ttwakeup(tp); 903 } else if (tp->t_rocount++ == 0) 904 tp->t_rocol = tp->t_col; 905 tp->t_state &= ~TS_QUOT; 906 if (c == '\\') 907 tp->t_state |= TS_QUOT; 908 if (tp->t_state&TS_ERASE) { 909 tp->t_state &= ~TS_ERASE; 910 (void) ttyoutput('/', tp); 911 } 912 i = tp->t_col; 913 ttyecho(c, tp); 914 if (c == tp->t_eofc && t_flags&ECHO) { 915 i = MIN(2, tp->t_col - i); 916 while (i > 0) { 917 (void) ttyoutput('\b', tp); 918 i--; 919 } 920 } 921 } 922 endcase: 923 /* 924 * If DEC-style start/stop is enabled don't restart 925 * output until seeing the start character. 926 */ 927 if (t_flags&DECCTQ && tp->t_state&TS_TTSTOP && 928 tp->t_startc != tp->t_stopc) 929 return; 930 restartoutput: 931 tp->t_state &= ~TS_TTSTOP; 932 tp->t_flags &= ~FLUSHO; 933 startoutput: 934 ttstart(tp); 935 } 936 937 /* 938 * Put character on TTY output queue, adding delays, 939 * expanding tabs, and handling the CR/NL bit. 940 * This is called both from the top half for output, 941 * and from interrupt level for echoing. 942 * The arguments are the character and the tty structure. 943 * Returns < 0 if putc succeeds, otherwise returns char to resend 944 * Must be recursive. 945 */ 946 ttyoutput(c, tp) 947 register c; 948 register struct tty *tp; 949 { 950 register char *colp; 951 register ctype; 952 953 if (tp->t_flags & (RAW|LITOUT)) { 954 if (tp->t_flags&FLUSHO) 955 return (-1); 956 if (putc(c, &tp->t_outq)) 957 return (c); 958 tk_nout++; 959 return (-1); 960 } 961 962 /* 963 * Ignore EOT in normal mode to avoid 964 * hanging up certain terminals. 965 */ 966 c &= 0177; 967 if (c == CEOT && (tp->t_flags&CBREAK) == 0) 968 return (-1); 969 /* 970 * Turn tabs to spaces as required 971 */ 972 if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) { 973 register int s; 974 975 c = 8 - (tp->t_col&7); 976 if ((tp->t_flags&FLUSHO) == 0) { 977 s = spltty(); /* don't interrupt tabs */ 978 c -= b_to_q(" ", c, &tp->t_outq); 979 tk_nout += c; 980 splx(s); 981 } 982 tp->t_col += c; 983 return (c ? -1 : '\t'); 984 } 985 tk_nout++; 986 /* 987 * for upper-case-only terminals, 988 * generate escapes. 989 */ 990 if (tp->t_flags&LCASE) { 991 colp = "({)}!|^~'`"; 992 while (*colp++) 993 if (c == *colp++) { 994 if (ttyoutput('\\', tp) >= 0) 995 return (c); 996 c = colp[-2]; 997 break; 998 } 999 if ('A' <= c && c <= 'Z') { 1000 if (ttyoutput('\\', tp) >= 0) 1001 return (c); 1002 } else if ('a' <= c && c <= 'z') 1003 c += 'A' - 'a'; 1004 } 1005 1006 /* 1007 * turn <nl> to <cr><lf> if desired. 1008 */ 1009 if (c == '\n' && tp->t_flags&CRMOD) 1010 if (ttyoutput('\r', tp) >= 0) 1011 return (c); 1012 if (c == '~' && tp->t_flags&TILDE) 1013 c = '`'; 1014 if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq)) 1015 return (c); 1016 /* 1017 * Calculate delays. 1018 * The numbers here represent clock ticks 1019 * and are not necessarily optimal for all terminals. 1020 * The delays are indicated by characters above 0200. 1021 * In raw mode there are no delays and the 1022 * transmission path is 8 bits wide. 1023 * 1024 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 1025 */ 1026 colp = &tp->t_col; 1027 ctype = partab[c]; 1028 c = 0; 1029 switch (ctype&077) { 1030 1031 case ORDINARY: 1032 (*colp)++; 1033 1034 case CONTROL: 1035 break; 1036 1037 case BACKSPACE: 1038 if (*colp) 1039 (*colp)--; 1040 break; 1041 1042 /* 1043 * This macro is close enough to the correct thing; 1044 * it should be replaced by real user settable delays 1045 * in any event... 1046 */ 1047 #define mstohz(ms) (((ms) * hz) >> 10) 1048 case NEWLINE: 1049 ctype = (tp->t_flags >> 8) & 03; 1050 if (ctype == 1) { /* tty 37 */ 1051 if (*colp > 0) 1052 c = max((((unsigned)*colp) >> 4) + 3, 1053 (unsigned)6); 1054 } else if (ctype == 2) /* vt05 */ 1055 c = mstohz(100); 1056 *colp = 0; 1057 break; 1058 1059 case TAB: 1060 ctype = (tp->t_flags >> 10) & 03; 1061 if (ctype == 1) { /* tty 37 */ 1062 c = 1 - (*colp | ~07); 1063 if (c < 5) 1064 c = 0; 1065 } 1066 *colp |= 07; 1067 (*colp)++; 1068 break; 1069 1070 case VTAB: 1071 if (tp->t_flags&VTDELAY) /* tty 37 */ 1072 c = 0177; 1073 break; 1074 1075 case RETURN: 1076 ctype = (tp->t_flags >> 12) & 03; 1077 if (ctype == 1) /* tn 300 */ 1078 c = mstohz(83); 1079 else if (ctype == 2) /* ti 700 */ 1080 c = mstohz(166); 1081 else if (ctype == 3) { /* concept 100 */ 1082 int i; 1083 1084 if ((i = *colp) >= 0) 1085 for (; i < 9; i++) 1086 (void) putc(0177, &tp->t_outq); 1087 } 1088 *colp = 0; 1089 } 1090 if (c && (tp->t_flags&FLUSHO) == 0) 1091 (void) putc(c|0200, &tp->t_outq); 1092 return (-1); 1093 } 1094 #undef mstohz 1095 1096 /* 1097 * Called from device's read routine after it has 1098 * calculated the tty-structure given as argument. 1099 */ 1100 ttread(tp, uio) 1101 register struct tty *tp; 1102 struct uio *uio; 1103 { 1104 register struct clist *qp; 1105 register c, t_flags; 1106 int s, first, error = 0; 1107 1108 loop: 1109 /* 1110 * Take any pending input first. 1111 */ 1112 s = spltty(); 1113 if (tp->t_flags&PENDIN) 1114 ttypend(tp); 1115 splx(s); 1116 1117 if ((tp->t_state&TS_CARR_ON)==0) 1118 return (EIO); 1119 1120 /* 1121 * Hang process if it's in the background. 1122 */ 1123 if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 1124 if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 1125 (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || 1126 u.u_procp->p_flag&SVFORK) 1127 return (EIO); 1128 gsignal(u.u_procp->p_pgrp, SIGTTIN); 1129 sleep((caddr_t)&lbolt, TTIPRI); 1130 goto loop; 1131 } 1132 t_flags = tp->t_flags; 1133 1134 /* 1135 * In raw mode take characters directly from the 1136 * raw queue w/o processing. Interlock against 1137 * device interrupts when interrogating rawq. 1138 */ 1139 if (t_flags&RAW) { 1140 s = spltty(); 1141 if (tp->t_rawq.c_cc <= 0) { 1142 if ((tp->t_state&TS_CARR_ON) == 0 || 1143 (tp->t_state&TS_NBIO)) { 1144 splx(s); 1145 return (EWOULDBLOCK); 1146 } 1147 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1148 splx(s); 1149 goto loop; 1150 } 1151 splx(s); 1152 while (!error && tp->t_rawq.c_cc && uio->uio_resid) 1153 error = ureadc(getc(&tp->t_rawq), uio); 1154 goto checktandem; 1155 } 1156 1157 /* 1158 * In cbreak mode use the rawq, otherwise 1159 * take characters from the canonicalized q. 1160 */ 1161 qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq; 1162 1163 /* 1164 * No input, sleep on rawq awaiting hardware 1165 * receipt and notification. 1166 */ 1167 s = spltty(); 1168 if (qp->c_cc <= 0) { 1169 if ((tp->t_state&TS_CARR_ON) == 0 || 1170 (tp->t_state&TS_NBIO)) { 1171 splx(s); 1172 return (EWOULDBLOCK); 1173 } 1174 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1175 splx(s); 1176 goto loop; 1177 } 1178 splx(s); 1179 1180 /* 1181 * Input present, perform input mapping 1182 * and processing (we're not in raw mode). 1183 */ 1184 first = 1; 1185 while ((c = getc(qp)) >= 0) { 1186 if (t_flags&CRMOD && c == '\r') 1187 c = '\n'; 1188 /* 1189 * Check for delayed suspend character. 1190 */ 1191 if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) { 1192 gsignal(tp->t_pgrp, SIGTSTP); 1193 if (first) { 1194 sleep((caddr_t)&lbolt, TTIPRI); 1195 goto loop; 1196 } 1197 break; 1198 } 1199 /* 1200 * Interpret EOF only in cooked mode. 1201 */ 1202 if (c == tp->t_eofc && (t_flags&CBREAK) == 0) 1203 break; 1204 /* 1205 * Give user character. 1206 */ 1207 error = ureadc(t_flags&PASS8 ? c : c & 0177, uio); 1208 if (error) 1209 break; 1210 if (uio->uio_resid == 0) 1211 break; 1212 /* 1213 * In cooked mode check for a "break character" 1214 * marking the end of a "line of input". 1215 */ 1216 if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp)) 1217 break; 1218 first = 0; 1219 } 1220 1221 checktandem: 1222 /* 1223 * Look to unblock output now that (presumably) 1224 * the input queue has gone down. 1225 */ 1226 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) 1227 if (putc(tp->t_startc, &tp->t_outq) == 0) { 1228 tp->t_state &= ~TS_TBLOCK; 1229 ttstart(tp); 1230 } 1231 return (error); 1232 } 1233 1234 /* 1235 * Check the output queue on tp for space for a kernel message 1236 * (from uprintf/tprintf). Allow some space over the normal 1237 * hiwater mark so we don't lose messages due to normal flow 1238 * control, but don't let the tty run amok. 1239 */ 1240 ttycheckoutq(tp, wait) 1241 register struct tty *tp; 1242 int wait; 1243 { 1244 int hiwat, s; 1245 1246 hiwat = TTHIWAT(tp); 1247 s = spltty(); 1248 if (tp->t_outq.c_cc > hiwat + 200) 1249 while (tp->t_outq.c_cc > hiwat) { 1250 ttstart(tp); 1251 if (wait == 0) { 1252 splx(s); 1253 return (0); 1254 } 1255 tp->t_state |= TS_ASLEEP; 1256 sleep((caddr_t)&tp->t_outq, TTOPRI); 1257 } 1258 splx(s); 1259 return (1); 1260 } 1261 1262 /* 1263 * Called from the device's write routine after it has 1264 * calculated the tty-structure given as argument. 1265 */ 1266 ttwrite(tp, uio) 1267 register struct tty *tp; 1268 register struct uio *uio; 1269 { 1270 register char *cp; 1271 register int cc, ce, c; 1272 int i, hiwat, cnt, error, s; 1273 char obuf[OBUFSIZ]; 1274 1275 hiwat = TTHIWAT(tp); 1276 cnt = uio->uio_resid; 1277 error = 0; 1278 loop: 1279 if ((tp->t_state&TS_CARR_ON) == 0) 1280 return (EIO); 1281 /* 1282 * Hang the process if it's in the background. 1283 */ 1284 if (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 1285 (tp->t_flags&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1286 !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) && 1287 !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) { 1288 gsignal(u.u_procp->p_pgrp, SIGTTOU); 1289 sleep((caddr_t)&lbolt, TTIPRI); 1290 goto loop; 1291 } 1292 1293 /* 1294 * Process the user's data in at most OBUFSIZ 1295 * chunks. Perform lower case simulation and 1296 * similar hacks. Keep track of high water 1297 * mark, sleep on overflow awaiting device aid 1298 * in acquiring new space. 1299 */ 1300 while (uio->uio_resid > 0) { 1301 /* 1302 * Grab a hunk of data from the user. 1303 */ 1304 cc = uio->uio_iov->iov_len; 1305 if (cc == 0) { 1306 uio->uio_iovcnt--; 1307 uio->uio_iov++; 1308 if (uio->uio_iovcnt <= 0) 1309 panic("ttwrite"); 1310 continue; 1311 } 1312 if (cc > OBUFSIZ) 1313 cc = OBUFSIZ; 1314 cp = obuf; 1315 error = uiomove(cp, cc, UIO_WRITE, uio); 1316 if (error) 1317 break; 1318 if (tp->t_outq.c_cc > hiwat) 1319 goto ovhiwat; 1320 if (tp->t_flags&FLUSHO) 1321 continue; 1322 /* 1323 * If we're mapping lower case or kludging tildes, 1324 * then we've got to look at each character, so 1325 * just feed the stuff to ttyoutput... 1326 */ 1327 if (tp->t_flags & (LCASE|TILDE)) { 1328 while (cc > 0) { 1329 c = *cp++; 1330 tp->t_rocount = 0; 1331 while ((c = ttyoutput(c, tp)) >= 0) { 1332 /* out of clists, wait a bit */ 1333 ttstart(tp); 1334 sleep((caddr_t)&lbolt, TTOPRI); 1335 tp->t_rocount = 0; 1336 if (cc != 0) { 1337 uio->uio_iov->iov_base -= cc; 1338 uio->uio_iov->iov_len += cc; 1339 uio->uio_resid += cc; 1340 uio->uio_offset -= cc; 1341 } 1342 goto loop; 1343 } 1344 --cc; 1345 if (tp->t_outq.c_cc > hiwat) 1346 goto ovhiwat; 1347 } 1348 continue; 1349 } 1350 /* 1351 * If nothing fancy need be done, grab those characters we 1352 * can handle without any of ttyoutput's processing and 1353 * just transfer them to the output q. For those chars 1354 * which require special processing (as indicated by the 1355 * bits in partab), call ttyoutput. After processing 1356 * a hunk of data, look for FLUSHO so ^O's will take effect 1357 * immediately. 1358 */ 1359 while (cc > 0) { 1360 if (tp->t_flags & (RAW|LITOUT)) 1361 ce = cc; 1362 else { 1363 ce = cc - scanc((unsigned)cc, (caddr_t)cp, 1364 (caddr_t)partab, 077); 1365 /* 1366 * If ce is zero, then we're processing 1367 * a special character through ttyoutput. 1368 */ 1369 if (ce == 0) { 1370 tp->t_rocount = 0; 1371 if (ttyoutput(*cp, tp) >= 0) { 1372 /* no c-lists, wait a bit */ 1373 ttstart(tp); 1374 sleep((caddr_t)&lbolt, TTOPRI); 1375 if (cc != 0) { 1376 uio->uio_iov->iov_base -= cc; 1377 uio->uio_iov->iov_len += cc; 1378 uio->uio_resid += cc; 1379 uio->uio_offset -= cc; 1380 } 1381 goto loop; 1382 } 1383 cp++, cc--; 1384 if (tp->t_flags&FLUSHO || 1385 tp->t_outq.c_cc > hiwat) 1386 goto ovhiwat; 1387 continue; 1388 } 1389 } 1390 /* 1391 * A bunch of normal characters have been found, 1392 * transfer them en masse to the output queue and 1393 * continue processing at the top of the loop. 1394 * If there are any further characters in this 1395 * <= OBUFSIZ chunk, the first should be a character 1396 * requiring special handling by ttyoutput. 1397 */ 1398 tp->t_rocount = 0; 1399 i = b_to_q(cp, ce, &tp->t_outq); 1400 ce -= i; 1401 tp->t_col += ce; 1402 cp += ce, cc -= ce, tk_nout += ce; 1403 if (i > 0) { 1404 /* out of c-lists, wait a bit */ 1405 ttstart(tp); 1406 sleep((caddr_t)&lbolt, TTOPRI); 1407 uio->uio_iov->iov_base -= cc; 1408 uio->uio_iov->iov_len += cc; 1409 uio->uio_resid += cc; 1410 uio->uio_offset -= cc; 1411 goto loop; 1412 } 1413 if (tp->t_flags&FLUSHO || tp->t_outq.c_cc > hiwat) 1414 goto ovhiwat; 1415 } 1416 } 1417 ttstart(tp); 1418 return (error); 1419 1420 ovhiwat: 1421 s = spltty(); 1422 if (cc != 0) { 1423 uio->uio_iov->iov_base -= cc; 1424 uio->uio_iov->iov_len += cc; 1425 uio->uio_resid += cc; 1426 uio->uio_offset -= cc; 1427 } 1428 /* 1429 * This can only occur if FLUSHO 1430 * is also set in t_flags. 1431 */ 1432 if (tp->t_outq.c_cc <= hiwat) { 1433 splx(s); 1434 goto loop; 1435 } 1436 ttstart(tp); 1437 if (tp->t_state&TS_NBIO) { 1438 splx(s); 1439 if (uio->uio_resid == cnt) 1440 return (EWOULDBLOCK); 1441 return (0); 1442 } 1443 tp->t_state |= TS_ASLEEP; 1444 sleep((caddr_t)&tp->t_outq, TTOPRI); 1445 splx(s); 1446 goto loop; 1447 } 1448 1449 /* 1450 * Rubout one character from the rawq of tp 1451 * as cleanly as possible. 1452 */ 1453 ttyrub(c, tp) 1454 register c; 1455 register struct tty *tp; 1456 { 1457 register char *cp; 1458 register int savecol; 1459 int s; 1460 char *nextc(); 1461 1462 if ((tp->t_flags&ECHO) == 0) 1463 return; 1464 tp->t_flags &= ~FLUSHO; 1465 c &= 0377; 1466 if (tp->t_flags&CRTBS) { 1467 if (tp->t_rocount == 0) { 1468 /* 1469 * Screwed by ttwrite; retype 1470 */ 1471 ttyretype(tp); 1472 return; 1473 } 1474 if (c == ('\t'|0200) || c == ('\n'|0200)) 1475 ttyrubo(tp, 2); 1476 else switch (partab[c&=0177]&0177) { 1477 1478 case ORDINARY: 1479 if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z') 1480 ttyrubo(tp, 2); 1481 else 1482 ttyrubo(tp, 1); 1483 break; 1484 1485 case VTAB: 1486 case BACKSPACE: 1487 case CONTROL: 1488 case RETURN: 1489 if (tp->t_flags&CTLECH) 1490 ttyrubo(tp, 2); 1491 break; 1492 1493 case TAB: 1494 if (tp->t_rocount < tp->t_rawq.c_cc) { 1495 ttyretype(tp); 1496 return; 1497 } 1498 s = spltty(); 1499 savecol = tp->t_col; 1500 tp->t_state |= TS_CNTTB; 1501 tp->t_flags |= FLUSHO; 1502 tp->t_col = tp->t_rocol; 1503 cp = tp->t_rawq.c_cf; 1504 for (; cp; cp = nextc(&tp->t_rawq, cp)) 1505 ttyecho(*cp, tp); 1506 tp->t_flags &= ~FLUSHO; 1507 tp->t_state &= ~TS_CNTTB; 1508 splx(s); 1509 /* 1510 * savecol will now be length of the tab 1511 */ 1512 savecol -= tp->t_col; 1513 tp->t_col += savecol; 1514 if (savecol > 8) 1515 savecol = 8; /* overflow screw */ 1516 while (--savecol >= 0) 1517 (void) ttyoutput('\b', tp); 1518 break; 1519 1520 default: 1521 panic("ttyrub"); 1522 } 1523 } else if (tp->t_flags&PRTERA) { 1524 if ((tp->t_state&TS_ERASE) == 0) { 1525 (void) ttyoutput('\\', tp); 1526 tp->t_state |= TS_ERASE; 1527 } 1528 ttyecho(c, tp); 1529 } else 1530 ttyecho(tp->t_erase, tp); 1531 tp->t_rocount--; 1532 } 1533 1534 /* 1535 * Crt back over cnt chars perhaps 1536 * erasing them. 1537 */ 1538 ttyrubo(tp, cnt) 1539 register struct tty *tp; 1540 int cnt; 1541 { 1542 register char *rubostring = tp->t_flags&CRTERA ? "\b \b" : "\b"; 1543 1544 while (--cnt >= 0) 1545 ttyout(rubostring, tp); 1546 } 1547 1548 /* 1549 * Reprint the rawq line. 1550 * We assume c_cc has already been checked. 1551 */ 1552 ttyretype(tp) 1553 register struct tty *tp; 1554 { 1555 register char *cp; 1556 char *nextc(); 1557 int s; 1558 1559 if (tp->t_rprntc != 0377) 1560 ttyecho(tp->t_rprntc, tp); 1561 (void) ttyoutput('\n', tp); 1562 s = spltty(); 1563 for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp)) 1564 ttyecho(*cp, tp); 1565 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1566 ttyecho(*cp, tp); 1567 tp->t_state &= ~TS_ERASE; 1568 splx(s); 1569 tp->t_rocount = tp->t_rawq.c_cc; 1570 tp->t_rocol = 0; 1571 } 1572 1573 /* 1574 * Echo a typed character to the terminal 1575 */ 1576 ttyecho(c, tp) 1577 register c; 1578 register struct tty *tp; 1579 { 1580 1581 if ((tp->t_state&TS_CNTTB) == 0) 1582 tp->t_flags &= ~FLUSHO; 1583 if ((tp->t_flags&ECHO) == 0) 1584 return; 1585 c &= 0377; 1586 if (tp->t_flags&RAW) { 1587 (void) ttyoutput(c, tp); 1588 return; 1589 } 1590 if (c == '\r' && tp->t_flags&CRMOD) 1591 c = '\n'; 1592 if (tp->t_flags&CTLECH) { 1593 if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) { 1594 (void) ttyoutput('^', tp); 1595 c &= 0177; 1596 if (c == 0177) 1597 c = '?'; 1598 else if (tp->t_flags&LCASE) 1599 c += 'a' - 1; 1600 else 1601 c += 'A' - 1; 1602 } 1603 } 1604 (void) ttyoutput(c&0177, tp); 1605 } 1606 1607 /* 1608 * Is c a break char for tp? 1609 */ 1610 ttbreakc(c, tp) 1611 register c; 1612 register struct tty *tp; 1613 { 1614 return (c == '\n' || c == tp->t_eofc || c == tp->t_brkc || 1615 c == '\r' && (tp->t_flags&CRMOD)); 1616 } 1617 1618 /* 1619 * send string cp to tp 1620 */ 1621 ttyout(cp, tp) 1622 register char *cp; 1623 register struct tty *tp; 1624 { 1625 register char c; 1626 1627 while (c = *cp++) 1628 (void) ttyoutput(c, tp); 1629 } 1630 1631 ttwakeup(tp) 1632 struct tty *tp; 1633 { 1634 1635 if (tp->t_rsel) { 1636 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1637 tp->t_state &= ~TS_RCOLL; 1638 tp->t_rsel = 0; 1639 } 1640 if (tp->t_state & TS_ASYNC) 1641 gsignal(tp->t_pgrp, SIGIO); 1642 wakeup((caddr_t)&tp->t_rawq); 1643 } 1644