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