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