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