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