1 /* tty.c 4.33 82/10/31 */ 2 3 /* 4 * TTY subroutines common to more than one line discipline 5 */ 6 #include "../h/param.h" 7 #include "../h/systm.h" 8 #include "../h/dir.h" 9 #include "../h/user.h" 10 #include "../h/tty.h" 11 #include "../h/proc.h" 12 #include "../h/inode.h" 13 #include "../h/file.h" 14 #include "../h/reg.h" 15 #include "../h/conf.h" 16 #include "../h/buf.h" 17 #include "../h/dk.h" 18 #include "../h/uio.h" 19 #include "../h/kernel.h" 20 21 /* 22 * Table giving parity for characters and indicating 23 * character classes to tty driver. In particular, 24 * if the low 6 bits are 0, then the character needs 25 * no special processing on output. 26 */ 27 28 char partab[] = { 29 0001,0201,0201,0001,0201,0001,0001,0201, 30 0202,0004,0003,0201,0005,0206,0201,0001, 31 0201,0001,0001,0201,0001,0201,0201,0001, 32 0001,0201,0201,0001,0201,0001,0001,0201, 33 0200,0000,0000,0200,0000,0200,0200,0000, 34 0000,0200,0200,0000,0200,0000,0000,0200, 35 0000,0200,0200,0000,0200,0000,0000,0200, 36 0200,0000,0000,0200,0000,0200,0200,0000, 37 0200,0000,0000,0200,0000,0200,0200,0000, 38 0000,0200,0200,0000,0200,0000,0000,0200, 39 0000,0200,0200,0000,0200,0000,0000,0200, 40 0200,0000,0000,0200,0000,0200,0200,0000, 41 0000,0200,0200,0000,0200,0000,0000,0200, 42 0200,0000,0000,0200,0000,0200,0200,0000, 43 0200,0000,0000,0200,0000,0200,0200,0000, 44 0000,0200,0200,0000,0200,0000,0000,0201, 45 46 /* 47 * 7 bit ascii ends with the last character above, 48 * but we contine through all 256 codes for the sake 49 * of the tty output routines which use special vax 50 * instructions which need a 256 character trt table. 51 */ 52 53 0007,0007,0007,0007,0007,0007,0007,0007, 54 0007,0007,0007,0007,0007,0007,0007,0007, 55 0007,0007,0007,0007,0007,0007,0007,0007, 56 0007,0007,0007,0007,0007,0007,0007,0007, 57 0007,0007,0007,0007,0007,0007,0007,0007, 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 }; 70 71 /* 72 * Input mapping table-- if an entry is non-zero, when the 73 * corresponding character is typed preceded by "\" the escape 74 * sequence is replaced by the table value. Mostly used for 75 * upper-case only terminals. 76 */ 77 78 char maptab[] ={ 79 000,000,000,000,000,000,000,000, 80 000,000,000,000,000,000,000,000, 81 000,000,000,000,000,000,000,000, 82 000,000,000,000,000,000,000,000, 83 000,'|',000,000,000,000,000,'`', 84 '{','}',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,000,000, 88 000,000,000,000,000,000,000,000, 89 000,000,000,000,000,000,000,000, 90 000,000,000,000,000,000,'~',000, 91 000,'A','B','C','D','E','F','G', 92 'H','I','J','K','L','M','N','O', 93 'P','Q','R','S','T','U','V','W', 94 'X','Y','Z',000,000,000,000,000, 95 }; 96 97 short tthiwat[16] = 98 { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 }; 99 short ttlowat[16] = 100 { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 }; 101 102 #define OBUFSIZ 100 103 104 /* 105 * set default control characters. 106 */ 107 ttychars(tp) 108 register struct tty *tp; 109 { 110 111 tun.t_intrc = CINTR; 112 tun.t_quitc = CQUIT; 113 tun.t_startc = CSTART; 114 tun.t_stopc = CSTOP; 115 tun.t_eofc = CEOT; 116 tun.t_brkc = CBRK; 117 tp->t_erase = CERASE; 118 tp->t_kill = CKILL; 119 /* begin local */ 120 tlun.t_suspc = CTRL(z); 121 tlun.t_dsuspc = CTRL(y); 122 tlun.t_rprntc = CTRL(r); 123 tlun.t_flushc = CTRL(o); 124 tlun.t_werasc = CTRL(w); 125 tlun.t_lnextc = CTRL(v); 126 tp->t_local = 0; 127 tp->t_lstate = 0; 128 /* end local */ 129 } 130 131 /* 132 * Wait for output to drain, then flush input waiting. 133 */ 134 wflushtty(tp) 135 register struct tty *tp; 136 { 137 138 (void) spl5(); 139 while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON 140 && tp->t_oproc) { /* kludge for pty */ 141 (*tp->t_oproc)(tp); 142 tp->t_state |= TS_ASLEEP; 143 sleep((caddr_t)&tp->t_outq, TTOPRI); 144 } 145 flushtty(tp, FREAD); 146 (void) spl0(); 147 } 148 149 /* 150 * flush all TTY queues 151 */ 152 flushtty(tp, rw) 153 register struct tty *tp; 154 { 155 register s; 156 157 s = spl6(); 158 if (rw & FREAD) { 159 while (getc(&tp->t_canq) >= 0) 160 ; 161 wakeup((caddr_t)&tp->t_rawq); 162 } 163 if (rw & FWRITE) { 164 wakeup((caddr_t)&tp->t_outq); 165 tp->t_state &= ~TS_TTSTOP; 166 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 167 while (getc(&tp->t_outq) >= 0) 168 ; 169 } 170 if (rw & FREAD) { 171 while (getc(&tp->t_rawq) >= 0) 172 ; 173 tp->t_delct = 0; 174 tp->t_rocount = 0; /* local */ 175 tp->t_rocol = 0; 176 tp->t_lstate = 0; 177 } 178 splx(s); 179 } 180 181 /* 182 * Send stop character on input overflow. 183 */ 184 ttyblock(tp) 185 register struct tty *tp; 186 { 187 register x; 188 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 189 if (tp->t_rawq.c_cc > TTYHOG) { 190 flushtty(tp, FREAD|FWRITE); 191 tp->t_state &= ~TS_TBLOCK; 192 } 193 if (x >= TTYHOG/2) { 194 if (putc(tun.t_stopc, &tp->t_outq)==0) { 195 tp->t_state |= TS_TBLOCK; 196 tp->t_char++; 197 ttstart(tp); 198 } 199 } 200 } 201 202 /* 203 * Restart typewriter output following a delay 204 * timeout. 205 * The name of the routine is passed to the timeout 206 * subroutine and it is called during a clock interrupt. 207 */ 208 ttrstrt(tp) 209 register struct tty *tp; 210 { 211 212 if (tp == 0) { 213 printf("ttrstrt: arg was 0!\n"); 214 return; 215 } 216 tp->t_state &= ~TS_TIMEOUT; 217 ttstart(tp); 218 } 219 220 /* 221 * Start output on the typewriter. It is used from the top half 222 * after some characters have been put on the output queue, 223 * from the interrupt routine to transmit the next 224 * character, and after a timeout has finished. 225 */ 226 ttstart(tp) 227 register struct tty *tp; 228 { 229 register s; 230 231 s = spl5(); 232 if ((tp->t_state&(TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 && 233 tp->t_oproc) /* kludge for pty */ 234 (*tp->t_oproc)(tp); 235 splx(s); 236 } 237 238 /* 239 * Common code for tty ioctls. 240 */ 241 /*ARGSUSED*/ 242 ttioctl(tp, com, data, flag) 243 register struct tty *tp; 244 caddr_t data; 245 { 246 int dev = tp->t_dev; 247 extern int nldisp; 248 int s; 249 250 /* 251 * If the ioctl involves modification, 252 * insist on being able to write the device, 253 * and hang if in the background. 254 */ 255 switch (com) { 256 257 case TIOCSETD: 258 case TIOCSETP: 259 case TIOCSETN: 260 case TIOCFLUSH: 261 case TIOCSETC: 262 case TIOCSLTC: 263 case TIOCSPGRP: 264 case TIOCLBIS: 265 case TIOCLBIC: 266 case TIOCLSET: 267 while (tp->t_line == NTTYDISC && 268 u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 269 (u.u_procp->p_flag&SVFORK) == 0 && 270 u.u_signal[SIGTTOU] != SIG_IGN && 271 u.u_signal[SIGTTOU] != SIG_HOLD) { 272 gsignal(u.u_procp->p_pgrp, SIGTTOU); 273 sleep((caddr_t)&lbolt, TTOPRI); 274 } 275 break; 276 } 277 278 switch (com) { 279 280 /* get discipline number */ 281 case TIOCGETD: 282 *(int *)data = tp->t_line; 283 break; 284 285 /* set line discipline */ 286 case TIOCSETD: { 287 register int t = *(int *)data; 288 int error; 289 290 if (t >= nldisp) 291 return (ENXIO); 292 s = spl5(); 293 if (tp->t_line) 294 (*linesw[tp->t_line].l_close)(tp); 295 if (t) 296 error = (*linesw[t].l_open)(dev, tp); 297 splx(s); 298 if (error) 299 return (error); 300 tp->t_line = t; 301 break; 302 } 303 304 /* prevent more opens on channel */ 305 case TIOCEXCL: 306 tp->t_state |= TS_XCLUDE; 307 break; 308 309 case TIOCNXCL: 310 tp->t_state &= ~TS_XCLUDE; 311 break; 312 313 /* set new parameters */ 314 case TIOCSETP: 315 case TIOCSETN: { 316 register struct sgttyb *sg = (struct sgttyb *)data; 317 struct clist tq; 318 319 (void) spl5(); 320 if (tp->t_flags&RAW || sg->sg_flags&RAW || com == TIOCSETP) 321 wflushtty(tp); 322 else if ((tp->t_flags&CBREAK) != (sg->sg_flags&CBREAK)) { 323 if (sg->sg_flags & CBREAK) { 324 catq(&tp->t_rawq, &tp->t_canq); 325 tq = tp->t_rawq; 326 tp->t_rawq = tp->t_canq; 327 tp->t_canq = tq; 328 } else { 329 tp->t_local |= LPENDIN; 330 ttwakeup(tp); 331 } 332 } 333 tp->t_ispeed = sg->sg_ispeed; 334 tp->t_ospeed = sg->sg_ospeed; 335 tp->t_erase = sg->sg_erase; 336 tp->t_kill = sg->sg_kill; 337 tp->t_flags = sg->sg_flags; 338 if (tp->t_flags & RAW) { 339 tp->t_state &= ~TS_TTSTOP; 340 ttstart(tp); 341 } 342 (void) spl0(); 343 break; 344 } 345 346 /* send current parameters to user */ 347 case TIOCGETP: { 348 register struct sgttyb *sg = (struct sgttyb *)data; 349 350 sg->sg_ispeed = tp->t_ispeed; 351 sg->sg_ospeed = tp->t_ospeed; 352 sg->sg_erase = tp->t_erase; 353 sg->sg_kill = tp->t_kill; 354 sg->sg_flags = tp->t_flags; 355 break; 356 } 357 358 /* hang up line on last close */ 359 case TIOCHPCL: 360 tp->t_state |= TS_HUPCLS; 361 break; 362 363 case TIOCFLUSH: { 364 register int flags = *(int *)data; 365 366 if (flags == 0) 367 flags = FREAD|FWRITE; 368 else 369 flags &= FREAD|FWRITE; 370 flushtty(tp, flags); 371 break; 372 } 373 374 case FIONBIO: 375 if (*(int *)data) 376 tp->t_state |= TS_NBIO; 377 else 378 tp->t_state &= ~TS_NBIO; 379 break; 380 381 case FIOASYNC: 382 if (*(int *)data) 383 tp->t_state |= TS_ASYNC; 384 else 385 tp->t_state &= ~TS_ASYNC; 386 break; 387 388 /* set and fetch special characters */ 389 case TIOCSETC: 390 bcopy(data, (caddr_t)&tun, sizeof (struct tchars)); 391 break; 392 393 case TIOCGETC: 394 bcopy((caddr_t)&tun, data, sizeof (struct tchars)); 395 break; 396 397 /* set/get local special characters */ 398 case TIOCSLTC: 399 bcopy(data, (caddr_t)&tlun, sizeof (struct ltchars)); 400 break; 401 402 case TIOCGLTC: 403 bcopy((caddr_t)&tlun, data, sizeof (struct ltchars)); 404 break; 405 406 /* return number of characters immediately available */ 407 case FIONREAD: 408 *(off_t *)data = ttnread(tp); 409 break; 410 411 /* should allow SPGRP and GPGRP only if tty open for reading */ 412 case TIOCSPGRP: 413 tp->t_pgrp = *(int *)data; 414 break; 415 416 case TIOCGPGRP: 417 *(int *)data = tp->t_pgrp; 418 break; 419 420 /* Modify local mode word */ 421 case TIOCLBIS: 422 tp->t_local |= *(int *)data; 423 break; 424 425 case TIOCLBIC: 426 tp->t_local &= ~(*(int *)data); 427 break; 428 429 case TIOCLSET: 430 tp->t_local = *(int *)data; 431 break; 432 433 case TIOCLGET: 434 *(int *)data = tp->t_local; 435 break; 436 437 case TIOCSTOP: 438 s = spl5(); 439 if ((tp->t_state & TS_TTSTOP) == 0) { 440 tp->t_state |= TS_TTSTOP; 441 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 442 } 443 splx(s); 444 break; 445 446 case TIOCSTART: 447 s = spl5(); 448 if ((tp->t_state & TS_TTSTOP) || (tp->t_local & LFLUSHO)) { 449 tp->t_state &= ~TS_TTSTOP; 450 tp->t_local &= ~LFLUSHO; 451 ttstart(tp); 452 } 453 splx(s); 454 break; 455 456 default: 457 return (-1); 458 } 459 return (0); 460 } 461 462 ttnread(tp) 463 struct tty *tp; 464 { 465 int nread = 0; 466 467 if (tp->t_local & LPENDIN) 468 ttypend(tp); 469 nread = tp->t_canq.c_cc; 470 if (tp->t_flags & (RAW|CBREAK)) 471 nread += tp->t_rawq.c_cc; 472 return (nread); 473 } 474 475 ttselect(dev, rw) 476 dev_t dev; 477 int rw; 478 { 479 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 480 int nread; 481 int s = spl5(); 482 483 switch (rw) { 484 485 case FREAD: 486 nread = ttnread(tp); 487 if (nread > 0) 488 goto win; 489 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 490 tp->t_state |= TS_RCOLL; 491 else 492 tp->t_rsel = u.u_procp; 493 break; 494 495 case FWRITE: 496 if (tp->t_outq.c_cc <= TTLOWAT(tp)) 497 goto win; 498 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 499 tp->t_state |= TS_WCOLL; 500 else 501 tp->t_wsel = u.u_procp; 502 break; 503 } 504 splx(s); 505 return (0); 506 win: 507 splx(s); 508 return (1); 509 } 510 511 #define OBUFSIZ 100 512 513 /* 514 * routine called on opens while tp->t_line == NTTYDISC 515 * establishes a process group for distribution of 516 * quits and interrupts from the tty. 517 * (actually, pp->p_pgrp can't be 0 when this routine 518 * is called since NTTYDISC is not the default discipline) 519 */ 520 ttyopen(dev, tp) 521 dev_t dev; 522 register struct tty *tp; 523 { 524 register struct proc *pp; 525 526 pp = u.u_procp; 527 tp->t_dev = dev; 528 if (pp->p_pgrp == 0) { 529 u.u_ttyp = tp; 530 u.u_ttyd = dev; 531 if (tp->t_pgrp == 0) 532 tp->t_pgrp = pp->p_pid; 533 pp->p_pgrp = tp->t_pgrp; 534 } 535 tp->t_state &= ~TS_WOPEN; 536 tp->t_state |= TS_ISOPEN; 537 if (tp->t_line != NTTYDISC) 538 wflushtty(tp); 539 return (0); 540 } 541 542 /* 543 * clean tp on last close 544 */ 545 ttyclose(tp) 546 register struct tty *tp; 547 { 548 549 if (tp->t_line) { 550 wflushtty(tp); 551 tp->t_line = 0; 552 return; 553 } 554 tp->t_pgrp = 0; 555 wflushtty(tp); 556 tp->t_state = 0; 557 } 558 559 /* 560 * reinput pending characters after state switch 561 * call at spl5(). 562 */ 563 ttypend(tp) 564 register struct tty *tp; 565 { 566 struct clist tq; 567 register c; 568 569 tp->t_local &= ~LPENDIN; 570 tp->t_lstate |= LSTYPEN; 571 tq = tp->t_rawq; 572 tp->t_rawq.c_cc = 0; 573 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 574 while ((c = getc(&tq)) >= 0) 575 ttyinput(c, tp); 576 tp->t_lstate &= ~LSTYPEN; 577 } 578 579 /* 580 * Place a character on raw TTY input queue, putting in delimiters 581 * and waking up top half as needed. 582 * Also echo if required. 583 * The arguments are the character and the appropriate 584 * tty structure. 585 */ 586 ttyinput(c, tp) 587 register c; 588 register struct tty *tp; 589 { 590 register int t_flags; 591 int i; 592 593 if (tp->t_local&LPENDIN) 594 ttypend(tp); 595 tk_nin++; 596 c &= 0377; 597 t_flags = tp->t_flags; 598 if (t_flags&TANDEM) 599 ttyblock(tp); 600 if ((t_flags&RAW)==0) { 601 if ((tp->t_lstate&LSTYPEN) == 0) 602 c &= 0177; 603 /* check for literal nexting very first */ 604 if (tp->t_lstate&LSLNCH) { 605 c |= 0200; 606 tp->t_lstate &= ~LSLNCH; 607 } 608 if (tp->t_line == NTTYDISC && c==tlun.t_lnextc) { 609 if (tp->t_flags&ECHO) 610 ttyout("^\b", tp); 611 tp->t_lstate |= LSLNCH; 612 /* check for output control functions */ 613 } else if (c==tun.t_stopc) { 614 if ((tp->t_state&TS_TTSTOP)==0) { 615 tp->t_state |= TS_TTSTOP; 616 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 617 return; 618 } 619 if (c!=tun.t_startc) 620 return; 621 } else if (c==tun.t_startc) { 622 tp->t_state &= ~TS_TTSTOP; 623 tp->t_local &= ~LFLUSHO; 624 ttstart(tp); 625 return; 626 } else if (tp->t_line == NTTYDISC && c==tlun.t_flushc) { 627 if (tp->t_local & LFLUSHO) 628 tp->t_local &= ~LFLUSHO; 629 else { 630 flushtty(tp, FWRITE); 631 ttyecho(c, tp); 632 if (tp->t_rawq.c_cc+tp->t_canq.c_cc) 633 ttyretype(tp); 634 tp->t_local |= LFLUSHO; 635 } 636 ttstart(tp); 637 return; 638 } else if (c==tun.t_intrc || c==tun.t_quitc || 639 (tp->t_line == NTTYDISC && c==tlun.t_suspc)) { 640 if ((tp->t_local & LNOFLSH) == 0) 641 flushtty(tp, 642 c==tlun.t_suspc ? FREAD : FREAD|FWRITE); 643 ttyecho(c, tp); 644 c = c==tun.t_intrc ? SIGINT : 645 ((c==tun.t_quitc) ? SIGQUIT : SIGTSTP); 646 ttsignal(tp, c); 647 /* check for buffer editing functions - cooked mode */ 648 } else if ((t_flags&CBREAK) == 0) { 649 if ((tp->t_lstate&LSQUOT) && 650 (c==tp->t_erase||c==tp->t_kill)) { 651 ttyrub(unputc(&tp->t_rawq), tp); 652 c |= 0200; 653 } 654 if (c==tp->t_erase) { 655 if (tp->t_rawq.c_cc) 656 ttyrub(unputc(&tp->t_rawq), tp); 657 } else if (c==tp->t_kill) { 658 if (tp->t_local&LCRTKIL && 659 tp->t_rawq.c_cc == tp->t_rocount) { 660 while (tp->t_rawq.c_cc) 661 ttyrub(unputc(&tp->t_rawq), tp); 662 } else { 663 ttyecho(c, tp); 664 ttyecho('\n', tp); 665 while (getc(&tp->t_rawq) > 0) 666 ; 667 tp->t_rocount = 0; 668 } 669 tp->t_lstate = 0; 670 } else if (tp->t_line == NTTYDISC && c==tlun.t_werasc) { 671 if (tp->t_rawq.c_cc == 0) 672 goto out; 673 do { 674 c = unputc(&tp->t_rawq); 675 if (c != ' ' && c != '\t') 676 goto erasenb; 677 ttyrub(c, tp); 678 } while (tp->t_rawq.c_cc); 679 goto out; 680 erasenb: 681 do { 682 ttyrub(c, tp); 683 if (tp->t_rawq.c_cc == 0) 684 goto out; 685 c = unputc(&tp->t_rawq); 686 } while (c != ' ' && c != '\t'); 687 (void) putc(c, &tp->t_rawq); 688 } else if (tp->t_line == NTTYDISC && c==tlun.t_rprntc) { 689 ttyretype(tp); 690 /* check for cooked mode input buffer overflow */ 691 } else if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 692 ; 693 /* put data char in q for user and wakeup if a break char */ 694 } else if (putc(c, &tp->t_rawq) >= 0) { 695 if (tp->t_rawq.c_cc+tp->t_canq.c_cc==TTYHOG 696 && tp->t_line == NTTYDISC) 697 (void) ttyoutput(CTRL(g), tp); 698 if (!ttbreakc(c, tp)) { 699 if (tp->t_rocount++ == 0) 700 tp->t_rocol = tp->t_col; 701 } else { 702 tp->t_rocount = 0; 703 catq(&tp->t_rawq, &tp->t_canq); 704 /* IF (TP->T_CHAN) (VOID) SDATA(TP->T_CHAN); */ 705 ttwakeup(tp); 706 } 707 tp->t_lstate &= ~LSQUOT; 708 if (c == '\\') 709 tp->t_lstate |= LSQUOT; 710 if (tp->t_lstate&LSERASE) { 711 tp->t_lstate &= ~LSERASE; 712 (void) ttyoutput('/', tp); 713 } 714 i = tp->t_col; 715 ttyecho(c, tp); 716 if (c==tun.t_eofc && tp->t_flags&ECHO) { 717 i = MIN(2, tp->t_col - i); 718 while (i > 0) { 719 (void) ttyoutput('\b', tp); 720 i--; 721 } 722 } 723 } 724 /* CBREAK mode */ 725 } else if (tp->t_rawq.c_cc > TTYHOG) { 726 if (tp->t_outq.c_cc < TTHIWAT(tp) && 727 tp->t_line == NTTYDISC) 728 (void) ttyoutput(CTRL(g), tp); 729 } else if (putc(c, &tp->t_rawq) >= 0) { 730 ttwakeup(tp); 731 ttyecho(c, tp); 732 } 733 /* RAW mode */ 734 } else if (tp->t_rawq.c_cc > TTYHOG) 735 flushtty(tp, FREAD|FWRITE); 736 else { 737 if (putc(c, &tp->t_rawq) >= 0) 738 ttwakeup(tp); 739 ttyecho(c, tp); 740 } 741 out: 742 if (tp->t_local & LDECCTQ && tp->t_state & TS_TTSTOP && 743 tun.t_startc != tun.t_stopc) 744 return; 745 tp->t_state &= ~TS_TTSTOP; 746 tp->t_local &= ~LFLUSHO; 747 ttstart(tp); 748 } 749 750 /* 751 * put character on TTY output queue, adding delays, 752 * expanding tabs, and handling the CR/NL bit. 753 * It is called both from the top half for output, and from 754 * interrupt level for echoing. 755 * The arguments are the character and the tty structure. 756 * Returns < 0 if putc succeeds, otherwise returns char to resend 757 * Must be recursive. 758 */ 759 ttyoutput(c, tp) 760 register c; 761 register struct tty *tp; 762 { 763 register char *colp; 764 register ctype; 765 766 if (tp->t_flags&RAW || tp->t_local&LLITOUT) { 767 if (tp->t_local&LFLUSHO) 768 return (-1); 769 if (putc(c, &tp->t_outq)) 770 return (c); 771 tk_nout++; 772 return (-1); 773 } 774 /* 775 * Ignore EOT in normal mode to avoid hanging up 776 * certain terminals. 777 */ 778 c &= 0177; 779 if (c==CEOT && (tp->t_flags&CBREAK)==0) 780 return (-1); 781 /* 782 * Turn tabs to spaces as required 783 */ 784 if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) { 785 register int s; 786 787 c = 8 - (tp->t_col&7); 788 if ((tp->t_local&LFLUSHO) == 0) { 789 s = spl5(); /* don't interrupt tabs */ 790 c -= b_to_q(" ", c, &tp->t_outq); 791 tk_nout += c; 792 splx(s); 793 } 794 tp->t_col += c; 795 return (c ? -1 : '\t'); 796 } 797 tk_nout++; 798 /* 799 * for upper-case-only terminals, 800 * generate escapes. 801 */ 802 if (tp->t_flags&LCASE) { 803 colp = "({)}!|^~'`"; 804 while (*colp++) 805 if (c == *colp++) { 806 if (ttyoutput('\\', tp) >= 0) 807 return (c); 808 c = colp[-2]; 809 break; 810 } 811 if ('A'<=c && c<='Z') { 812 if (ttyoutput('\\', tp) >= 0) 813 return (c); 814 } else if ('a'<=c && c<='z') 815 c += 'A' - 'a'; 816 } 817 /* 818 * turn <nl> to <cr><lf> if desired. 819 */ 820 if (c=='\n' && tp->t_flags&CRMOD) 821 if (ttyoutput('\r', tp) >= 0) 822 return (c); 823 if (c=='~' && tp->t_local<ILDE) 824 c = '`'; 825 if ((tp->t_local&LFLUSHO) == 0 && putc(c, &tp->t_outq)) 826 return (c); 827 /* 828 * Calculate delays. 829 * The numbers here represent clock ticks 830 * and are not necessarily optimal for all terminals. 831 * The delays are indicated by characters above 0200. 832 * In raw mode there are no delays and the 833 * transmission path is 8 bits wide. 834 */ 835 colp = &tp->t_col; 836 ctype = partab[c]; 837 c = 0; 838 switch (ctype&077) { 839 840 case ORDINARY: 841 (*colp)++; 842 843 case CONTROL: 844 break; 845 846 case BACKSPACE: 847 if (*colp) 848 (*colp)--; 849 break; 850 851 case NEWLINE: 852 ctype = (tp->t_flags >> 8) & 03; 853 if (ctype == 1) { /* tty 37 */ 854 if (*colp) 855 c = max(((unsigned)*colp>>4) + 3, (unsigned)6); 856 } else 857 if (ctype == 2) { /* vt05 */ 858 c = 6; 859 } 860 *colp = 0; 861 break; 862 863 case TAB: 864 ctype = (tp->t_flags >> 10) & 03; 865 if (ctype == 1) { /* tty 37 */ 866 c = 1 - (*colp | ~07); 867 if (c < 5) 868 c = 0; 869 } 870 *colp |= 07; 871 (*colp)++; 872 break; 873 874 case VTAB: 875 if (tp->t_flags & VTDELAY) /* tty 37 */ 876 c = 0177; 877 break; 878 879 case RETURN: 880 ctype = (tp->t_flags >> 12) & 03; 881 if (ctype == 1) { /* tn 300 */ 882 c = 5; 883 } else if (ctype == 2) { /* ti 700 */ 884 c = 10; 885 } else if (ctype == 3) { /* concept 100 */ 886 int i; 887 if ((i = *colp) >= 0) 888 for (; i<9; i++) 889 (void) putc(0177, &tp->t_outq); 890 } 891 *colp = 0; 892 } 893 if (c && (tp->t_local&LFLUSHO) == 0) 894 (void) putc(c|0200, &tp->t_outq); 895 return (-1); 896 } 897 898 /* 899 * Called from device's read routine after it has 900 * calculated the tty-structure given as argument. 901 */ 902 ttread(tp, uio) 903 register struct tty *tp; 904 struct uio *uio; 905 { 906 register struct clist *qp; 907 register c, first; 908 int error = 0; 909 910 if ((tp->t_state&TS_CARR_ON)==0) 911 return (EIO); 912 loop: 913 (void) spl5(); 914 if (tp->t_local&LPENDIN) 915 ttypend(tp); 916 (void) spl0(); 917 while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 918 if (u.u_signal[SIGTTIN] == SIG_IGN || 919 u.u_signal[SIGTTIN] == SIG_HOLD || 920 /* 921 (u.u_procp->p_flag&SDETACH) || 922 */ 923 u.u_procp->p_flag&SVFORK) 924 return (EIO); 925 gsignal(u.u_procp->p_pgrp, SIGTTIN); 926 sleep((caddr_t)&lbolt, TTIPRI); 927 } 928 if (tp->t_flags&RAW) { 929 (void) spl5(); 930 if (tp->t_rawq.c_cc <= 0) { 931 if ((tp->t_state&TS_CARR_ON)==0 || 932 (tp->t_state&TS_NBIO)) { 933 (void) spl0(); 934 return (EWOULDBLOCK); 935 } 936 sleep((caddr_t)&tp->t_rawq, TTIPRI); 937 (void) spl0(); 938 goto loop; 939 } 940 (void) spl0(); 941 while (tp->t_rawq.c_cc && uio->uio_iovcnt) { 942 error = passuc(getc(&tp->t_rawq), uio); 943 if (error) 944 break; 945 } 946 return (error); 947 } else { 948 qp = tp->t_flags & CBREAK ? &tp->t_rawq : &tp->t_canq; 949 (void) spl5(); 950 if (qp->c_cc <= 0) { 951 if ((tp->t_state&TS_CARR_ON)==0 || 952 (tp->t_state&TS_NBIO)) { 953 (void) spl0(); 954 return (EWOULDBLOCK); 955 } 956 sleep((caddr_t)&tp->t_rawq, TTIPRI); 957 (void) spl0(); 958 goto loop; 959 } 960 (void) spl0(); 961 first = 1; 962 while ((c = getc(qp)) >= 0) { 963 if (tp->t_flags&CRMOD && c == '\r') 964 c = '\n'; 965 if (tp->t_flags&LCASE && c <= 0177) 966 if (tp->t_lstate&LSBKSL) { 967 if (maptab[c]) 968 c = maptab[c]; 969 tp->t_lstate &= ~LSBKSL; 970 } else if (c >= 'A' && c <= 'Z') 971 c += 'a' - 'A'; 972 else if (c == '\\') { 973 tp->t_lstate |= LSBKSL; 974 continue; 975 } 976 if (tp->t_line == NTTYDISC && c == tlun.t_dsuspc) { 977 ttsignal(tp, SIGTSTP); 978 if (first) { 979 sleep((caddr_t)&lbolt, TTIPRI); 980 goto loop; 981 } 982 break; 983 } 984 if (c == tun.t_eofc && (tp->t_flags&CBREAK)==0) 985 break; 986 error = passuc(c & 0177, uio); 987 if (error) 988 break; 989 if (uio->uio_iovcnt == 0) 990 break; 991 if ((tp->t_flags&CBREAK)==0 && ttbreakc(c, tp)) 992 break; 993 first = 0; 994 } 995 tp->t_lstate &= ~LSBKSL; 996 } 997 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) { 998 if (putc(tun.t_startc, &tp->t_outq)==0) { 999 tp->t_state &= ~TS_TBLOCK; 1000 ttstart(tp); 1001 } 1002 tp->t_char = 0; 1003 } 1004 return (error); 1005 } 1006 1007 /* 1008 * Called from the device's write routine after it has 1009 * calculated the tty-structure given as argument. 1010 */ 1011 ttwrite(tp, uio) 1012 register struct tty *tp; 1013 struct uio *uio; 1014 { 1015 #ifdef vax 1016 /* 1017 * THE POSITIONING OF CP, CC, AND CE ARE CRITICAL 1018 * AND MUST NOT BE CHANGED WITHOUT PATCHING 1019 * THE 'ASM' INLINES BELOW. WATCH OUT. 1020 */ 1021 #endif 1022 register char *cp; 1023 register int cc, ce; 1024 register i; 1025 char obuf[OBUFSIZ]; 1026 register c; 1027 int hiwat = TTHIWAT(tp); 1028 int cnt = uio->uio_resid; 1029 int error = 0; 1030 1031 if ((tp->t_state&TS_CARR_ON)==0) 1032 return (EIO); 1033 loop: 1034 while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 1035 (tp->t_local<OSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1036 u.u_signal[SIGTTOU] != SIG_IGN && 1037 u.u_signal[SIGTTOU] != SIG_HOLD 1038 /* 1039 && 1040 (u.u_procp->p_flag&SDETACH)==0) { 1041 */ 1042 ) { 1043 gsignal(u.u_procp->p_pgrp, SIGTTOU); 1044 sleep((caddr_t)&lbolt, TTIPRI); 1045 } 1046 while (uio->uio_resid > 0) { 1047 cc = uio->uio_iov->iov_len; 1048 if (cc == 0) { 1049 uio->uio_iovcnt--; 1050 uio->uio_iov++; 1051 if (uio->uio_iovcnt < 0) 1052 panic("ttwrite"); 1053 continue; 1054 } 1055 if (cc > OBUFSIZ) 1056 cc = OBUFSIZ; 1057 cp = obuf; 1058 error = uiomove(cp, cc, UIO_WRITE, uio); 1059 if (error) 1060 break; 1061 if (tp->t_outq.c_cc > hiwat) 1062 goto ovhiwat; 1063 if (tp->t_local&LFLUSHO) 1064 continue; 1065 if (tp->t_flags&LCASE || tp->t_local<ILDE) { 1066 while (cc) { 1067 c = *cp++; 1068 tp->t_rocount = 0; 1069 while ((c = ttyoutput(c, tp)) >= 0) { 1070 /* out of clists, wait a bit */ 1071 ttstart(tp); 1072 sleep((caddr_t)&lbolt, TTOPRI); 1073 tp->t_rocount = 0; 1074 } 1075 --cc; 1076 if (tp->t_outq.c_cc > hiwat) 1077 goto ovhiwat; 1078 } 1079 continue; 1080 } 1081 while (cc) { 1082 if (tp->t_flags&RAW || tp->t_local&LLITOUT) 1083 ce = cc; 1084 else { 1085 #ifdef vax 1086 asm(" scanc r9,(r10),_partab,$077"); 1087 asm(" subl3 r0,r9,r8"); 1088 #else 1089 ce=0; 1090 while (((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce<cc)) 1091 ce++; 1092 #endif 1093 if (ce==0) { 1094 tp->t_rocount = 0; 1095 if (ttyoutput(*cp, tp) >= 0) { 1096 ttstart(tp); 1097 sleep((caddr_t)&lbolt, TTOPRI); 1098 continue; 1099 } 1100 cp++; 1101 cc--; 1102 if (tp->t_outq.c_cc > hiwat) 1103 goto ovhiwat; 1104 } 1105 } 1106 tp->t_rocount = 0; 1107 i=b_to_q(cp,ce,&tp->t_outq); 1108 ce-=i; 1109 tk_nout+=ce; 1110 tp->t_col+=ce; 1111 cp+=ce; 1112 cc-=ce; 1113 if (i) { 1114 ttstart(tp); 1115 sleep((caddr_t)&lbolt, TTOPRI); 1116 } 1117 if (ce || tp->t_outq.c_cc > hiwat) 1118 goto ovhiwat; 1119 } 1120 } 1121 ttstart(tp); 1122 return (error); 1123 1124 ovhiwat: 1125 (void) spl5(); 1126 uio->uio_iov->iov_base -= cc; 1127 uio->uio_iov->iov_len += cc; 1128 uio->uio_resid += cc; 1129 uio->uio_offset -= cc; 1130 if (tp->t_outq.c_cc <= hiwat) { 1131 (void) spl0(); 1132 goto loop; 1133 } 1134 ttstart(tp); 1135 if (tp->t_state & TS_NBIO) { 1136 if (uio->uio_resid == cnt) 1137 return (EWOULDBLOCK); 1138 return (0); 1139 } 1140 tp->t_state |= TS_ASLEEP; 1141 sleep((caddr_t)&tp->t_outq, TTOPRI); 1142 (void) spl0(); 1143 goto loop; 1144 } 1145 1146 /* 1147 * Rubout one character from the rawq of tp 1148 * as cleanly as possible. 1149 */ 1150 ttyrub(c, tp) 1151 register c; 1152 register struct tty *tp; 1153 { 1154 register char *cp; 1155 register int savecol; 1156 int s; 1157 char *nextc(); 1158 1159 if ((tp->t_flags&ECHO)==0) 1160 return; 1161 tp->t_local &= ~LFLUSHO; 1162 c &= 0377; 1163 if (tp->t_local&LCRTBS) { 1164 if (tp->t_rocount == 0) { 1165 /* 1166 * Screwed by ttwrite; retype 1167 */ 1168 ttyretype(tp); 1169 return; 1170 } 1171 if (c==('\t'|0200) || c==('\n'|0200)) 1172 ttyrubo(tp, 2); 1173 else switch (partab[c&=0177] & 0177) { 1174 1175 case ORDINARY: 1176 if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z') 1177 ttyrubo(tp, 2); 1178 else 1179 ttyrubo(tp, 1); 1180 break; 1181 1182 case VTAB: 1183 case BACKSPACE: 1184 case CONTROL: 1185 case RETURN: 1186 if (tp->t_local & LCTLECH) 1187 ttyrubo(tp, 2); 1188 break; 1189 1190 case TAB: 1191 if (tp->t_rocount < tp->t_rawq.c_cc) { 1192 ttyretype(tp); 1193 return; 1194 } 1195 s = spl5(); 1196 savecol = tp->t_col; 1197 tp->t_lstate |= LSCNTTB; 1198 tp->t_local |= LFLUSHO; 1199 tp->t_col = tp->t_rocol; 1200 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1201 ttyecho(*cp, tp); 1202 tp->t_local &= ~LFLUSHO; 1203 tp->t_lstate &= ~LSCNTTB; 1204 splx(s); 1205 /* 1206 * savecol will now be length of the tab 1207 */ 1208 savecol -= tp->t_col; 1209 tp->t_col += savecol; 1210 if (savecol > 8) 1211 savecol = 8; /* overflow screw */ 1212 while (--savecol >= 0) 1213 (void) ttyoutput('\b', tp); 1214 break; 1215 1216 default: 1217 panic("ttyrub"); 1218 } 1219 } else if (tp->t_local&LPRTERA) { 1220 if ((tp->t_lstate&LSERASE) == 0) { 1221 (void) ttyoutput('\\', tp); 1222 tp->t_lstate |= LSERASE; 1223 } 1224 ttyecho(c, tp); 1225 } else 1226 ttyecho(tp->t_erase, tp); 1227 tp->t_rocount--; 1228 } 1229 1230 /* 1231 * Crt back over cnt chars perhaps 1232 * erasing them. 1233 */ 1234 ttyrubo(tp, cnt) 1235 register struct tty *tp; 1236 int cnt; 1237 { 1238 1239 while (--cnt >= 0) 1240 ttyout(tp->t_local&LCRTERA ? "\b \b" : "\b", tp); 1241 } 1242 1243 /* 1244 * Reprint the rawq line. 1245 * We assume c_cc has already been checked. 1246 */ 1247 ttyretype(tp) 1248 register struct tty *tp; 1249 { 1250 register char *cp; 1251 char *nextc(); 1252 int s; 1253 1254 if (tlun.t_rprntc != 0377) 1255 ttyecho(tlun.t_rprntc, tp); 1256 (void) ttyoutput('\n', tp); 1257 s = spl5(); 1258 for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp)) 1259 ttyecho(*cp, tp); 1260 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1261 ttyecho(*cp, tp); 1262 tp->t_lstate &= ~LSERASE; 1263 splx(s); 1264 tp->t_rocount = tp->t_rawq.c_cc; 1265 tp->t_rocol = 0; 1266 } 1267 1268 /* 1269 * Echo a typed character to the terminal 1270 */ 1271 ttyecho(c, tp) 1272 register c; 1273 register struct tty *tp; 1274 { 1275 1276 if ((tp->t_lstate & LSCNTTB) == 0) 1277 tp->t_local &= ~LFLUSHO; 1278 if ((tp->t_flags&ECHO) == 0) 1279 return; 1280 c &= 0377; 1281 if (tp->t_flags&RAW) { 1282 (void) ttyoutput(c, tp); 1283 return; 1284 } 1285 if (c == '\r' && tp->t_flags&CRMOD) 1286 c = '\n'; 1287 if (tp->t_local&LCTLECH) { 1288 if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) { 1289 (void) ttyoutput('^', tp); 1290 c &= 0177; 1291 if (c == 0177) 1292 c = '?'; 1293 else if (tp->t_flags&LCASE) 1294 c += 'a' - 1; 1295 else 1296 c += 'A' - 1; 1297 } 1298 } 1299 if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z')) 1300 c += 'a' - 'A'; 1301 (void) ttyoutput(c & 0177, tp); 1302 } 1303 1304 /* 1305 * Is c a break char for tp? 1306 */ 1307 ttbreakc(c, tp) 1308 register c; 1309 register struct tty *tp; 1310 { 1311 return (c == '\n' || c == tun.t_eofc || c == tun.t_brkc || 1312 c == '\r' && (tp->t_flags&CRMOD)); 1313 } 1314 1315 /* 1316 * send string cp to tp 1317 */ 1318 ttyout(cp, tp) 1319 register char *cp; 1320 register struct tty *tp; 1321 { 1322 register char c; 1323 1324 while (c = *cp++) 1325 (void) ttyoutput(c, tp); 1326 } 1327 1328 ttwakeup(tp) 1329 struct tty *tp; 1330 { 1331 1332 if (tp->t_rsel) { 1333 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1334 tp->t_state &= ~TS_RCOLL; 1335 tp->t_rsel = 0; 1336 } 1337 wakeup((caddr_t)&tp->t_rawq); 1338 } 1339 1340 ttsignal(tp, signo) 1341 struct tty *tp; 1342 int signo; 1343 { 1344 1345 gsignal(tp->t_pgrp, signo); 1346 } 1347