1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)tty.c 7.11 (Berkeley) 04/08/88 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 #define TTYDEFCHARS 18 #include "ttydefaults.h" 19 #undef TTYDEFCHARS 20 #include "termios.h" 21 #include "proc.h" 22 #include "file.h" 23 #include "conf.h" 24 #include "dkstat.h" 25 #include "uio.h" 26 #include "kernel.h" 27 #include "syslog.h" 28 29 /* 30 * Table giving parity for characters and indicating 31 * character classes to tty driver. In particular, 32 * if the low 6 bits are 0, then the character needs 33 * no special processing on output. 34 */ 35 36 char partab[] = { 37 0001,0201,0201,0001,0201,0001,0001,0201, 38 0202,0004,0003,0201,0005,0206,0201,0001, 39 0201,0001,0001,0201,0001,0201,0201,0001, 40 0001,0201,0201,0001,0201,0001,0001,0201, 41 0200,0000,0000,0200,0000,0200,0200,0000, 42 0000,0200,0200,0000,0200,0000,0000,0200, 43 0000,0200,0200,0000,0200,0000,0000,0200, 44 0200,0000,0000,0200,0000,0200,0200,0000, 45 0200,0000,0000,0200,0000,0200,0200,0000, 46 0000,0200,0200,0000,0200,0000,0000,0200, 47 0000,0200,0200,0000,0200,0000,0000,0200, 48 0200,0000,0000,0200,0000,0200,0200,0000, 49 0000,0200,0200,0000,0200,0000,0000,0200, 50 0200,0000,0000,0200,0000,0200,0200,0000, 51 0200,0000,0000,0200,0000,0200,0200,0000, 52 0000,0200,0200,0000,0200,0000,0000,0201, 53 54 /* 55 * 7 bit ascii ends with the last character above, 56 * but we contine through all 256 codes for the sake 57 * of the tty output routines which use special vax 58 * instructions which need a 256 character trt table. 59 */ 60 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 0007,0007,0007,0007,0007,0007,0007,0007, 75 0007,0007,0007,0007,0007,0007,0007,0007, 76 0007,0007,0007,0007,0007,0007,0007,0007 77 }; 78 79 /* 80 * Input mapping table-- if an entry is non-zero, when the 81 * corresponding character is typed preceded by "\" the escape 82 * sequence is replaced by the table value. Mostly used for 83 * upper-case only terminals. 84 */ 85 char maptab[] ={ 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,'`', 91 '{','}',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,000, 95 000,000,000,000,000,000,000,000, 96 000,000,000,000,000,000,000,000, 97 000,000,000,000,000,000,'~',000, 98 000,'A','B','C','D','E','F','G', 99 'H','I','J','K','L','M','N','O', 100 'P','Q','R','S','T','U','V','W', 101 'X','Y','Z',000,000,000,000,000, 102 }; 103 104 short tthiwat[16] = 105 { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 }; 106 short ttlowat[16] = 107 { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 }; 108 109 extern struct tty *constty; /* temporary virtual console */ 110 extern char partab[], maptab[]; 111 112 /* 113 * Debugging aids 114 */ 115 #define dprintf if (tp->t_trace & TTRACE_IO)printf 116 117 /* 118 * Is 'c' a line delimiter ("break" character)? 119 */ 120 #define ttbreakc(c) (c == '\n' || CCEQ(cc[VEOF], c) || \ 121 CCEQ(cc[VEOL], c) || CCEQ(cc[VEOL2], c)) 122 123 ttychars(tp) 124 struct tty *tp; 125 { 126 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars)); 127 } 128 129 /* 130 * 131 * Wait for output to drain, then flush input waiting. 132 */ 133 ttywflush(tp) 134 register struct tty *tp; 135 { 136 137 ttywait(tp); 138 ttyflush(tp, FREAD); 139 } 140 141 /* 142 * Wait for output to drain. 143 */ 144 ttywait(tp) 145 register struct tty *tp; 146 { 147 register int s = spltty(); 148 149 while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) && 150 tp->t_state&TS_CARR_ON && tp->t_oproc) { 151 (*tp->t_oproc)(tp); 152 tp->t_state |= TS_ASLEEP; 153 sleep((caddr_t)&tp->t_outq, TTOPRI); 154 } 155 splx(s); 156 } 157 158 /* 159 * Flush all TTY queues 160 */ 161 ttyflush(tp, rw) 162 register struct tty *tp; 163 { 164 register s; 165 166 s = spltty(); 167 if (rw & FREAD) { 168 while (getc(&tp->t_canq) >= 0) 169 ; 170 wakeup((caddr_t)&tp->t_rawq); 171 } 172 if (rw & FWRITE) { 173 wakeup((caddr_t)&tp->t_outq); 174 tp->t_state &= ~TS_TTSTOP; 175 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw); 176 while (getc(&tp->t_outq) >= 0) 177 ; 178 } 179 if (rw & FREAD) { 180 while (getc(&tp->t_rawq) >= 0) 181 ; 182 tp->t_rocount = 0; 183 tp->t_rocol = 0; 184 tp->t_state &= ~TS_LOCAL; 185 } 186 splx(s); 187 } 188 189 /* 190 * Send stop character on input overflow. 191 */ 192 ttyblock(tp) 193 register struct tty *tp; 194 { 195 register x; 196 197 x = tp->t_rawq.c_cc + tp->t_canq.c_cc; 198 if (tp->t_rawq.c_cc > TTYHOG) { 199 ttyflush(tp, FREAD|FWRITE); 200 tp->t_state &= ~TS_TBLOCK; 201 } 202 /* 203 * Block further input iff: 204 * Current input > threshold AND input is available to user program 205 */ 206 if (x >= TTYHOG/2 && 207 (!(tp->t_lflag&ICANON)) || (tp->t_canq.c_cc > 0) && 208 tp->t_cc[VSTOP] != POSIX_V_DISABLE) { 209 if (putc(tp->t_cc[VSTOP], &tp->t_outq)==0) { 210 tp->t_state |= TS_TBLOCK; 211 ttstart(tp); 212 } 213 } 214 } 215 216 /* 217 * Restart typewriter output following a delay 218 * timeout. 219 * The name of the routine is passed to the timeout 220 * subroutine and it is called during a clock interrupt. 221 */ 222 ttrstrt(tp) 223 register struct tty *tp; 224 { 225 226 if (tp == 0) 227 panic("ttrstrt"); 228 tp->t_state &= ~TS_TIMEOUT; 229 ttstart(tp); 230 } 231 232 /* 233 * Start output on the typewriter. It is used from the top half 234 * after some characters have been put on the output queue, 235 * from the interrupt routine to transmit the next 236 * character, and after a timeout has finished. 237 */ 238 ttstart(tp) 239 register struct tty *tp; 240 { 241 242 if (tp->t_oproc) /* kludge for pty */ 243 (*tp->t_oproc)(tp); 244 } 245 246 /* 247 * Common code for tty ioctls. 248 */ 249 /*ARGSUSED*/ 250 ttioctl(tp, com, data, flag) 251 register struct tty *tp; 252 caddr_t data; 253 { 254 extern int nldisp; 255 int soft; 256 int s; 257 258 259 /* 260 * If the ioctl involves modification, 261 * hang if in the background. 262 */ 263 switch (com) { 264 265 case TIOCSETD: 266 case TIOCFLUSH: 267 case TIOCSPGRP: 268 case TIOCSTI: 269 case TIOCSWINSZ: 270 case TIOCSETA: 271 case TIOCSETAW: 272 case TIOCSETAF: 273 case TIOCSETAS: 274 case TIOCSETAWS: 275 case TIOCSETAFS: 276 while (tp->t_line == POSXDISC && 277 u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 278 (u.u_procp->p_flag&SVFORK) == 0 && 279 !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) && 280 !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) { 281 gsignal(u.u_procp->p_pgrp, SIGTTOU); 282 sleep((caddr_t)&lbolt, TTOPRI); 283 } 284 break; 285 } 286 287 /* 288 * Process the ioctl. 289 */ 290 switch (com) { 291 292 /* get discipline number */ 293 case TIOCGETD: 294 *(int *)data = tp->t_line; 295 break; 296 297 /* set line discipline */ 298 case TIOCSETD: { 299 register int t = *(int *)data; 300 dev_t dev = tp->t_dev; 301 int error = 0; 302 303 if ((unsigned) t >= nldisp) 304 return (ENXIO); 305 if (t != tp->t_line) { 306 s = spltty(); 307 (*linesw[tp->t_line].l_close)(tp); 308 error = (*linesw[t].l_open)(dev, tp); 309 if (error) { 310 (void)(*linesw[tp->t_line].l_open)(dev, tp); 311 splx(s); 312 return (error); 313 } 314 tp->t_line = t; 315 splx(s); 316 } 317 if (tp->t_trace & TTRACE_STATE) 318 ttytrace(com, tp); 319 break; 320 } 321 322 /* prevent more opens on channel */ 323 case TIOCEXCL: 324 tp->t_state |= TS_XCLUDE; 325 break; 326 327 case TIOCNXCL: 328 tp->t_state &= ~TS_XCLUDE; 329 break; 330 331 case TIOCHPCL: 332 tp->t_cflag |= HUPCL; 333 break; 334 335 case TIOCFLUSH: { 336 register int flags = *(int *)data; 337 338 if (flags == 0) 339 flags = FREAD|FWRITE; 340 else 341 flags &= FREAD|FWRITE; 342 ttyflush(tp, flags); 343 break; 344 } 345 346 /* return number of characters immediately available */ 347 case FIONREAD: 348 *(off_t *)data = ttnread(tp); 349 break; 350 351 case TIOCOUTQ: 352 *(int *)data = tp->t_outq.c_cc; 353 break; 354 355 case TIOCSTOP: 356 s = spltty(); 357 if ((tp->t_state&TS_TTSTOP) == 0) { 358 tp->t_state |= TS_TTSTOP; 359 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 360 } 361 splx(s); 362 break; 363 364 case TIOCSTART: 365 s = spltty(); 366 if ((tp->t_state&TS_TTSTOP) || (tp->t_lflag&FLUSHO)) { 367 tp->t_state &= ~TS_TTSTOP; 368 tp->t_lflag &= ~FLUSHO; 369 ttstart(tp); 370 } 371 splx(s); 372 break; 373 374 /* 375 * Simulate typing of a character at the terminal. 376 */ 377 case TIOCSTI: 378 if (u.u_uid && (flag & FREAD) == 0) 379 return (EPERM); 380 if (u.u_uid && u.u_ttyp != tp) 381 return (EACCES); 382 (*linesw[tp->t_line].l_rint)(*(char *)data, tp); 383 break; 384 385 case TIOCGETA: { 386 struct termios *t = (struct termios *)data; 387 bcopy(&tp->t_termio, t, sizeof(struct termios)); 388 if (tp->t_trace & TTRACE_STATE) 389 ttytrace(com, tp); 390 break; 391 } 392 393 case TIOCSETAS: 394 case TIOCSETAWS: 395 case TIOCSETAFS: 396 soft = 1; 397 goto set; 398 case TIOCSETA: 399 case TIOCSETAW: 400 case TIOCSETAF: 401 soft = 0; 402 set: 403 { 404 register struct termios *t = (struct termios *)data; 405 406 s = spltty(); 407 if (com == TIOCSETAF || com == TIOCSETAFS) 408 ttywflush(tp); 409 else { 410 if (com == TIOCSETAW || com == TIOCSETAWS) 411 ttywait(tp); 412 if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON)) 413 if (t->c_lflag&ICANON) { 414 tp->t_lflag |= PENDIN; 415 ttwakeup(tp); 416 } 417 else { 418 struct clist tq; 419 420 catq(&tp->t_rawq, &tp->t_canq); 421 tq = tp->t_rawq; 422 tp->t_rawq = tp->t_canq; 423 tp->t_canq = tq; 424 } 425 } 426 tp->t_iflag = t->c_iflag; 427 tp->t_oflag = t->c_oflag; 428 tp->t_lflag = t->c_lflag; 429 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 430 if (!soft) { 431 tp->t_cflag = t->c_cflag; 432 tp->t_ispeed = t->c_ispeed; 433 tp->t_ospeed = t->c_ospeed; 434 } 435 splx(s); 436 if (tp->t_trace & TTRACE_STATE) 437 ttytrace(com, tp); 438 break; 439 } 440 441 case TIOCTRACE: 442 tp->t_trace = *(int *)data; 443 break; 444 445 case FIONBIO: 446 if (*(int *)data) 447 tp->t_state |= TS_NBIO; 448 else 449 tp->t_state &= ~TS_NBIO; 450 break; 451 452 case FIOASYNC: 453 if (*(int *)data) 454 tp->t_state |= TS_ASYNC; 455 else 456 tp->t_state &= ~TS_ASYNC; 457 break; 458 459 460 /* 461 * Allow SPGRP only if tty is open for reading. 462 * Quick check: if we can find a process in the new pgrp, 463 * this user must own that process. 464 * SHOULD VERIFY THAT PGRP IS IN USE AND IS THIS USER'S. 465 */ 466 case TIOCSPGRP: { 467 struct proc *p; 468 int pgrp = *(int *)data; 469 470 if (u.u_uid && (flag & FREAD) == 0) 471 return (EPERM); 472 p = pfind(pgrp); 473 if (p && p->p_pgrp == pgrp && 474 p->p_uid != u.u_uid && u.u_uid && !inferior(p)) 475 return (EPERM); 476 tp->t_pgrp = pgrp; 477 break; 478 } 479 480 case TIOCGPGRP: 481 *(int *)data = tp->t_pgrp; 482 break; 483 484 case TIOCSWINSZ: 485 if (bcmp((caddr_t)&tp->t_winsize, data, 486 sizeof (struct winsize))) { 487 tp->t_winsize = *(struct winsize *)data; 488 gsignal(tp->t_pgrp, SIGWINCH); 489 } 490 break; 491 492 case TIOCGWINSZ: 493 *(struct winsize *)data = tp->t_winsize; 494 break; 495 496 case TIOCCONS: 497 if (*(int *)data) { 498 if (constty != NULL) 499 return (EBUSY); 500 #ifndef UCONSOLE 501 if (!suser()) 502 return (EPERM); 503 #endif 504 constty = tp; 505 } else if (tp == constty) 506 constty = NULL; 507 break; 508 509 /* allow old ioctls for now */ 510 case TIOCGETP: 511 case TIOCSETP: 512 case TIOCSETN: 513 case TIOCGETC: 514 case TIOCSETC: 515 case TIOCSLTC: 516 case TIOCGLTC: 517 case TIOCLBIS: 518 case TIOCLBIC: 519 case TIOCLSET: 520 case TIOCLGET: 521 return(ottioctl(tp, com, data, flag)); 522 523 default: 524 return (-1); 525 } 526 return (0); 527 } 528 529 /* 530 * DEBUG - to be removed 531 */ 532 ttytrace(ioc, tp) 533 struct tty *tp; 534 { 535 register u_char *cc = tp->t_cc; 536 char comm[MAXCOMLEN+1]; 537 static int seq = 0; 538 539 bcopy(u.u_comm, comm, MAXCOMLEN+1); 540 comm[MAXCOMLEN] = '\0'; 541 542 /* trace changes to line disciplines */ 543 if (ioc == TIOCSETD) { 544 log(LOG_LOCAL4|LOG_DEBUG, "%s:%x:%x:%x:%x\n", 545 comm, ioc, u.u_procp->p_pid, tp->t_dev, tp->t_line); 546 return; 547 } 548 549 /* 550 * format for the trace record is: 551 * 552 * u_comm:ioctl:pid:dev_t:ldisc:iflag:oflag:lflag:cflag:ispeed: 553 * ospeed:cc's...:seq 554 * 555 * u_comm is a string and all other values are hex. "cc's..." 556 * stands for control chars 0 through NCC-1. seq is a sequence # 557 * to force syslogd to log every entry (rather than hold them to 558 * print "last message repeated...". 559 */ 560 log(LOG_LOCAL4|LOG_DEBUG, "%s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n", 561 comm, ioc, u.u_procp->p_pid, tp->t_dev, tp->t_line, 562 tp->t_iflag, tp->t_oflag, tp->t_lflag, tp->t_cflag, 563 tp->t_ispeed, tp->t_ospeed, cc[0], cc[1], cc[2], cc[3], 564 cc[4], cc[5], cc[6], cc[7], cc[8], cc[9], cc[10], cc[11], 565 cc[12], cc[13], cc[14], cc[15], cc[16], cc[17], cc[18], 566 cc[19], seq++); 567 } 568 569 ttnread(tp) 570 struct tty *tp; 571 { 572 int nread = 0; 573 574 if (tp->t_lflag & PENDIN) 575 ttypend(tp); 576 nread = tp->t_canq.c_cc; 577 if (tp->t_lflag & ICANON == 0) 578 nread += tp->t_rawq.c_cc; 579 return (nread); 580 } 581 582 ttselect(dev, rw) 583 dev_t dev; 584 int rw; 585 { 586 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)]; 587 int nread; 588 int s = spltty(); 589 590 switch (rw) { 591 592 case FREAD: 593 nread = ttnread(tp); 594 if (nread > 0 || (tp->t_state & TS_CARR_ON) == 0) 595 goto win; 596 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait) 597 tp->t_state |= TS_RCOLL; 598 else 599 tp->t_rsel = u.u_procp; 600 break; 601 602 case FWRITE: 603 if (tp->t_outq.c_cc <= TTLOWAT(tp)) 604 goto win; 605 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait) 606 tp->t_state |= TS_WCOLL; 607 else 608 tp->t_wsel = u.u_procp; 609 break; 610 } 611 splx(s); 612 return (0); 613 win: 614 splx(s); 615 return (1); 616 } 617 618 /* 619 * Initial open of tty, or (re)entry to line discipline. 620 * Establish a process group for distribution of 621 * quits and interrupts from the tty. 622 */ 623 ttyopen(dev, tp) 624 dev_t dev; 625 register struct tty *tp; 626 { 627 register struct proc *pp; 628 629 pp = u.u_procp; 630 tp->t_dev = dev; 631 if (pp->p_pgrp == 0) { /* XXX - this has got to change */ 632 u.u_ttyp = tp; 633 u.u_ttyd = dev; 634 if (tp->t_pgrp == 0) 635 tp->t_pgrp = pp->p_pid; 636 pp->p_pgrp = tp->t_pgrp; 637 } 638 tp->t_state &= ~TS_WOPEN; 639 if ((tp->t_state & TS_ISOPEN) == 0) { 640 tp->t_state |= TS_ISOPEN; 641 bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize)); 642 /* 643 * CHANGE: used to do a ttywflush() if it was the 644 * old (old) line discipline. 645 */ 646 } 647 return (0); 648 } 649 650 /* 651 * "close" a line discipline 652 */ 653 ttylclose(tp) 654 register struct tty *tp; 655 { 656 657 ttywflush(tp); 658 } 659 660 /* 661 * clean tp on last close 662 */ 663 ttyclose(tp) 664 register struct tty *tp; 665 { 666 667 if (constty == tp) 668 constty = NULL; 669 ttyflush(tp, FREAD|FWRITE); 670 tp->t_pgrp = 0; 671 tp->t_state = 0; 672 } 673 674 /* 675 * Handle modem control transition on a tty. 676 * Flag indicates new state of carrier. 677 * Returns 0 if the line should be turned off, otherwise 1. 678 */ 679 ttymodem(tp, flag) 680 register struct tty *tp; 681 { 682 683 if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag & MDMBUF)) { 684 /* 685 * MDMBUF: do flow control according to carrier flag 686 */ 687 if (flag) { 688 tp->t_state &= ~TS_TTSTOP; 689 ttstart(tp); 690 } else if ((tp->t_state&TS_TTSTOP) == 0) { 691 tp->t_state |= TS_TTSTOP; 692 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 693 } 694 } else if (flag == 0) { 695 /* 696 * Lost carrier. 697 */ 698 tp->t_state &= ~TS_CARR_ON; 699 if (tp->t_state & TS_ISOPEN) { 700 if ((tp->t_lflag & NOHANG) == 0) { 701 gsignal(tp->t_pgrp, SIGHUP); 702 gsignal(tp->t_pgrp, SIGCONT); 703 ttyflush(tp, FREAD|FWRITE); 704 return (0); 705 } 706 } 707 } else { 708 /* 709 * Carrier now on. 710 */ 711 tp->t_state |= TS_CARR_ON; 712 wakeup((caddr_t)&tp->t_rawq); 713 } 714 return (1); 715 } 716 717 /* 718 * Default modem control routine (for other line disciplines). 719 * Return argument flag, to turn off device on carrier drop. 720 */ 721 nullmodem(tp, flag) 722 register struct tty *tp; 723 int flag; 724 { 725 726 if (flag) 727 tp->t_state |= TS_CARR_ON; 728 else 729 tp->t_state &= ~TS_CARR_ON; 730 return (flag); 731 } 732 733 /* 734 * reinput pending characters after state switch 735 * call at spltty(). 736 */ 737 ttypend(tp) 738 register struct tty *tp; 739 { 740 struct clist tq; 741 register c; 742 743 tp->t_lflag &= ~PENDIN; 744 tp->t_state |= TS_TYPEN; 745 tq = tp->t_rawq; 746 tp->t_rawq.c_cc = 0; 747 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 748 while ((c = getc(&tq)) >= 0) 749 ttyinput(c, tp); 750 tp->t_state &= ~TS_TYPEN; 751 } 752 753 /* 754 * 755 * Place a character on raw TTY input queue, 756 * putting in delimiters and waking up top 757 * half as needed. Also echo if required. 758 * The arguments are the character and the 759 * appropriate tty structure. 760 */ 761 ttyinput(c, tp) 762 register c; 763 register struct tty *tp; 764 { 765 register int iflag = tp->t_iflag; 766 register int lflag = tp->t_lflag; 767 register u_char *cc = tp->t_cc; 768 int i, err; 769 770 /* 771 * If input is pending take it first. 772 */ 773 if (lflag&PENDIN) 774 ttypend(tp); 775 776 tk_nin++; 777 778 /* 779 * Handle exceptional conditions (break, parity, framing). 780 */ 781 if (err = (c&TTY_ERRORMASK)) { 782 c &= TTY_CHARMASK; 783 if (err&TTY_FE && !c) { /* break */ 784 if (iflag&IGNBRK) 785 goto endcase; 786 else if (iflag&BRKINT && lflag&ISIG && 787 (cc[VINTR] != POSIX_V_DISABLE)) 788 c = cc[VINTR]; 789 else 790 c = 0; 791 } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) { 792 if (iflag&IGNPAR) 793 goto endcase; 794 else if (iflag&PARMRK) { 795 ttyinput(0377, tp); 796 ttyinput(0, tp); 797 } else 798 c = 0; 799 } 800 } 801 802 dprintf("<%o>\n", c); 803 804 /* 805 * In tandem mode, check high water mark. 806 */ 807 if (iflag&IXOFF) 808 ttyblock(tp); 809 810 /* 811 * Ignore any high bit added during 812 * previous ttyinput processing. 813 */ 814 if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP)) 815 c &= 0177; 816 /* 817 * Check for literal nexting very first 818 */ 819 if (tp->t_state&TS_LNCH) { 820 c |= 0200; 821 tp->t_state &= ~TS_LNCH; 822 } 823 824 /* 825 * Scan for special characters. This code 826 * is really just a big case statement with 827 * non-constant cases. The bottom of the 828 * case statement is labeled ``endcase'', so goto 829 * it after a case match, or similar. 830 */ 831 832 /* 833 * Extensions to POSIX input modes which aren't controlled 834 * by ICANON, ISIG, or IXON. 835 */ 836 if (iflag&IEXTEN) { 837 if (CCEQ(cc[VLNEXT],c) && (iflag&ISTRIP)) { 838 if (lflag&ECHO) 839 ttyout("^\b", tp); /*XXX - presumes too much */ 840 tp->t_state |= TS_LNCH; 841 goto endcase; 842 } 843 if (CCEQ(cc[VFLUSHO],c)) { 844 if (lflag&FLUSHO) 845 tp->t_lflag &= ~FLUSHO; 846 else { 847 ttyflush(tp, FWRITE); 848 ttyecho(c, tp); 849 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 850 ttyretype(tp); 851 tp->t_lflag |= FLUSHO; 852 } 853 goto startoutput; 854 } 855 } 856 857 /* 858 * Signals. 859 */ 860 if (lflag&ISIG) { 861 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 862 if ((lflag&NOFLSH) == 0) 863 ttyflush(tp, FREAD|FWRITE); 864 ttyecho(c, tp); 865 gsignal(tp->t_pgrp, CCEQ(cc[VINTR],c) ? 866 SIGINT : SIGQUIT); 867 goto endcase; 868 } 869 if (CCEQ(cc[VSUSP],c)) { 870 if ((lflag&NOFLSH) == 0) 871 ttyflush(tp, FREAD); 872 ttyecho(c, tp); 873 gsignal(tp->t_pgrp, SIGTSTP); 874 goto endcase; 875 } 876 } 877 878 /* 879 * Handle start/stop characters. 880 */ 881 if (iflag&IXON) { 882 if (CCEQ(cc[VSTOP],c)) { 883 if ((tp->t_state&TS_TTSTOP) == 0) { 884 tp->t_state |= TS_TTSTOP; 885 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); 886 return; 887 } 888 if (!CCEQ(cc[VSTART], c)) 889 return; 890 /* 891 * if VSTART == VSTOP we toggle 892 */ 893 goto endcase; 894 } 895 if (CCEQ(cc[VSTART], c)) 896 goto restartoutput; 897 } 898 899 /* 900 * IGNCR, ICRNL, & INLCR 901 */ 902 if (c == '\r') { 903 if (iflag&IGNCR) 904 goto endcase; 905 else if (iflag&ICRNL) 906 c = '\n'; 907 } 908 else if (c == '\n' && iflag&INLCR) 909 c = '\r'; 910 911 #ifdef notdef 912 /* 913 * We'd like to completely remove it. 914 */ 915 if (tp->t_flags & LCASE && c <= 0177) { 916 if (tp->t_state&TS_BKSL) { 917 ttyrub(unputc(&tp->t_rawq), tp); 918 if (maptab[c]) 919 c = maptab[c]; 920 c |= 0200; 921 tp->t_state &= ~(TS_BKSL|TS_QUOT); 922 } else if (c >= 'A' && c <= 'Z') 923 c += 'a' - 'A'; 924 else if (c == '\\') 925 tp->t_state |= TS_BKSL; 926 } 927 #endif /*notdef*/ 928 929 /* 930 * Non canonical mode, don't process line editing 931 * characters; check high water mark for wakeup. 932 * 933 */ 934 if (!(lflag&ICANON)) { 935 if (tp->t_rawq.c_cc > TTYHOG) { 936 if (iflag&IMAXBEL) { 937 if (tp->t_outq.c_cc < TTHIWAT(tp)) 938 (void) ttyoutput(CTRL('g'), tp); 939 } else 940 ttyflush(tp, FREAD | FWRITE); 941 } else if (putc(c, &tp->t_rawq) >= 0) { 942 ttwakeup(tp); 943 ttyecho(c, tp); 944 } 945 goto endcase; 946 } 947 948 /* 949 * From here on down canonical mode character 950 * processing takes place. 951 */ 952 953 /* 954 * Oldstyle quoting of erase, kill, and eof chars. 955 * 956 * Historically is '\' , but can be changed (read: disabled) 957 * with the VQUOTE subscript. 958 */ 959 if ((tp->t_state&TS_QUOT) && 960 (CCEQ(cc[VERASE], c) || CCEQ(cc[VKILL], c) || CCEQ(cc[VEOF], c))) { 961 ttyrub(unputc(&tp->t_rawq), tp); 962 c |= 0200; 963 } 964 965 /* 966 * erase (^H / ^?) 967 */ 968 if (CCEQ(cc[VERASE], c)) { 969 if (tp->t_rawq.c_cc) 970 ttyrub(unputc(&tp->t_rawq), tp); 971 goto endcase; 972 } 973 /* 974 * kill (^X / ^U) 975 */ 976 if (CCEQ(cc[VKILL], c)) { 977 if (lflag&ECHOKE && 978 tp->t_rawq.c_cc == tp->t_rocount) { 979 while (tp->t_rawq.c_cc) 980 ttyrub(unputc(&tp->t_rawq), tp); 981 } else { 982 ttyecho(c, tp); 983 if (lflag&ECHOK || lflag&ECHOKE) 984 ttyecho('\n', tp); 985 while (getc(&tp->t_rawq) > 0) 986 ; 987 tp->t_rocount = 0; 988 } 989 tp->t_state &= ~TS_LOCAL; 990 goto endcase; 991 } 992 993 /* 994 * word erase (^W) 995 */ 996 if (CCEQ(cc[VWERASE], c)) { 997 if (tp->t_rawq.c_cc == 0) 998 goto endcase; 999 do { 1000 c = unputc(&tp->t_rawq); 1001 if (c != ' ' && c != '\t') 1002 goto erasenb; 1003 ttyrub(c, tp); 1004 } while (tp->t_rawq.c_cc); 1005 goto endcase; 1006 erasenb: 1007 do { 1008 ttyrub(c, tp); 1009 if (tp->t_rawq.c_cc == 0) 1010 goto endcase; 1011 c = unputc(&tp->t_rawq); 1012 } while (c != ' ' && c != '\t'); 1013 (void) putc(c, &tp->t_rawq); 1014 goto endcase; 1015 } 1016 /* 1017 * reprint line (^R) 1018 */ 1019 if (CCEQ(cc[VREPRINT], c)) { 1020 ttyretype(tp); 1021 goto endcase; 1022 } 1023 1024 /* 1025 * Check for input buffer overflow 1026 */ 1027 if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) { 1028 if (iflag&IMAXBEL) { 1029 if (tp->t_outq.c_cc < TTHIWAT(tp)) 1030 (void) ttyoutput(CTRL('g'), tp); 1031 } else 1032 ttyflush(tp, FREAD | FWRITE); 1033 goto endcase; 1034 } 1035 1036 /* 1037 * Put data char in q for user and 1038 * wakeup on seeing a line delimiter. 1039 */ 1040 if (putc(c, &tp->t_rawq) >= 0) { 1041 if (ttbreakc(c)) { 1042 tp->t_rocount = 0; 1043 catq(&tp->t_rawq, &tp->t_canq); 1044 ttwakeup(tp); 1045 } else if (tp->t_rocount++ == 0) 1046 tp->t_rocol = tp->t_col; 1047 tp->t_state &= ~TS_QUOT; 1048 if (CCEQ(cc[VQUOTE], c) && (iflag&ISTRIP)) 1049 tp->t_state |= TS_QUOT; /* '\' escape */ 1050 if (tp->t_state&TS_ERASE) { 1051 /* 1052 * end of prterase \.../ 1053 */ 1054 tp->t_state &= ~TS_ERASE; 1055 (void) ttyoutput('/', tp); 1056 } 1057 i = tp->t_col; 1058 ttyecho(c, tp); 1059 if (CCEQ(cc[VEOF], c) && lflag&ECHO) { 1060 /* 1061 * Place the cursor over the '^' of the ^D. 1062 */ 1063 i = MIN(2, tp->t_col - i); 1064 while (i > 0) { 1065 (void) ttyoutput('\b', tp); 1066 i--; 1067 } 1068 } 1069 } 1070 endcase: 1071 /* 1072 * IXANY means allow any character to restart output. 1073 */ 1074 if (tp->t_state&TS_TTSTOP && (iflag&IXANY == 0) 1075 && cc[VSTART] != cc[VSTOP]) 1076 return; 1077 1078 restartoutput: 1079 tp->t_state &= ~TS_TTSTOP; 1080 tp->t_lflag &= ~FLUSHO; 1081 startoutput: 1082 ttstart(tp); 1083 } 1084 1085 /* 1086 * Put character on TTY output queue, adding delays, 1087 * expanding tabs, and handling the CR/NL bit. 1088 * This is called both from the top half for output, 1089 * and from interrupt level for echoing. 1090 * The arguments are the character and the tty structure. 1091 * Returns < 0 if putc succeeds, otherwise returns char to resend 1092 * Must be recursive. 1093 */ 1094 ttyoutput(c, tp) 1095 register c; 1096 register struct tty *tp; 1097 { 1098 register char *colp; 1099 register ctype; 1100 1101 if (!(tp->t_oflag&OPOST)) { 1102 if (tp->t_lflag&FLUSHO) 1103 return (-1); 1104 if (putc(c, &tp->t_outq)) 1105 return (c); 1106 tk_nout++; 1107 return (-1); 1108 } 1109 c &= 0377; 1110 /* 1111 * Turn tabs to spaces as required 1112 */ 1113 if (c == '\t' && tp->t_oflag&OXTABS ) { 1114 register int s; 1115 1116 c = 8 - (tp->t_col&7); 1117 if ((tp->t_lflag&FLUSHO) == 0) { 1118 s = spltty(); /* don't interrupt tabs */ 1119 c -= b_to_q(" ", c, &tp->t_outq); 1120 tk_nout += c; 1121 splx(s); 1122 } 1123 tp->t_col += c; 1124 return (c ? -1 : '\t'); 1125 } 1126 tk_nout++; 1127 #ifdef notdef 1128 /* 1129 * for upper-case-only terminals, 1130 * generate escapes. 1131 */ 1132 if (tp->t_flags&LCASE) { 1133 colp = "({)}!|^~'`"; 1134 while (*colp++) 1135 if (c == *colp++) { 1136 if (ttyoutput('\\', tp) >= 0) 1137 return (c); 1138 c = colp[-2]; 1139 break; 1140 } 1141 if ('A' <= c && c <= 'Z') { 1142 if (ttyoutput('\\', tp) >= 0) 1143 return (c); 1144 } else if ('a' <= c && c <= 'z') 1145 c += 'A' - 'a'; 1146 } 1147 #endif 1148 1149 /* 1150 * turn <nl> to <cr><lf> if desired. 1151 */ 1152 if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0) 1153 return (c); 1154 #ifdef notdef 1155 if (c == '~' && tp->t_flags&TILDE) 1156 c = '`'; 1157 #endif 1158 if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq)) 1159 return (c); 1160 /* 1161 * Calculate delays. 1162 * The numbers here represent clock ticks 1163 * and are not necessarily optimal for all terminals. 1164 * The delays are indicated by characters above 0200. 1165 * In raw mode there are no delays and the 1166 * transmission path is 8 bits wide. 1167 * 1168 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS 1169 */ 1170 colp = &tp->t_col; 1171 ctype = partab[c]; 1172 c = 0; 1173 switch (ctype&077) { 1174 1175 case ORDINARY: 1176 (*colp)++; 1177 1178 case CONTROL: 1179 break; 1180 1181 case BACKSPACE: 1182 if (*colp) 1183 (*colp)--; 1184 break; 1185 1186 /* 1187 * This macro is close enough to the correct thing; 1188 * it should be replaced by real user settable delays 1189 * in any event... 1190 */ 1191 #define mstohz(ms) (((ms) * hz) >> 10) 1192 case NEWLINE: 1193 ctype = (tp->t_flags >> 8) & 03; 1194 if (ctype == 1) { /* tty 37 */ 1195 if (*colp > 0) { 1196 c = (((unsigned)*colp) >> 4) + 3; 1197 if ((unsigned)c > 6) 1198 c = 6; 1199 } 1200 } else if (ctype == 2) /* vt05 */ 1201 c = mstohz(100); 1202 *colp = 0; 1203 break; 1204 1205 case TAB: 1206 ctype = (tp->t_flags >> 10) & 03; 1207 if (ctype == 1) { /* tty 37 */ 1208 c = 1 - (*colp | ~07); 1209 if (c < 5) 1210 c = 0; 1211 } 1212 *colp |= 07; 1213 (*colp)++; 1214 break; 1215 1216 case VTAB: 1217 if (tp->t_flags&VTDELAY) /* tty 37 */ 1218 c = 0177; 1219 break; 1220 1221 case RETURN: 1222 ctype = (tp->t_flags >> 12) & 03; 1223 if (ctype == 1) /* tn 300 */ 1224 c = mstohz(83); 1225 else if (ctype == 2) /* ti 700 */ 1226 c = mstohz(166); 1227 else if (ctype == 3) { /* concept 100 */ 1228 int i; 1229 1230 if ((i = *colp) >= 0) 1231 for (; i < 9; i++) 1232 (void) putc(0177, &tp->t_outq); 1233 } 1234 *colp = 0; 1235 } 1236 if (c && (tp->t_lflag&FLUSHO) == 0) 1237 (void) putc(c|0200, &tp->t_outq); 1238 return (-1); 1239 } 1240 #undef mstohz 1241 1242 /* 1243 * Called from device's read routine after it has 1244 * calculated the tty-structure given as argument. 1245 */ 1246 ttread(tp, uio) 1247 register struct tty *tp; 1248 struct uio *uio; 1249 { 1250 register struct clist *qp; 1251 register int c, t_flags; 1252 register long lflag = tp->t_lflag; 1253 register long iflag = tp->t_iflag; 1254 register u_char *cc = tp->t_cc; 1255 int s, first, error = 0; 1256 1257 1258 loop: 1259 /* 1260 * Take any pending input first. 1261 */ 1262 s = spltty(); 1263 if (tp->t_lflag&PENDIN) 1264 ttypend(tp); 1265 splx(s); 1266 1267 if ((tp->t_state&TS_CARR_ON)==0) 1268 return (EIO); 1269 1270 /* 1271 * Hang process if it's in the background. 1272 */ 1273 if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 1274 if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 1275 (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || 1276 u.u_procp->p_flag&SVFORK) 1277 return (EIO); 1278 gsignal(u.u_procp->p_pgrp, SIGTTIN); 1279 sleep((caddr_t)&lbolt, TTIPRI); 1280 goto loop; 1281 } 1282 t_flags = tp->t_flags; 1283 1284 /* 1285 * If canonical, use the canonical queue, 1286 * else use the raw queue. 1287 */ 1288 qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq; 1289 1290 /* 1291 * No input, sleep on rawq awaiting hardware 1292 * receipt and notification. 1293 */ 1294 s = spltty(); 1295 if (qp->c_cc <= 0) { 1296 if ((tp->t_state&TS_CARR_ON) == 0 || 1297 (tp->t_state&TS_NBIO)) { 1298 splx(s); 1299 return (EWOULDBLOCK); 1300 } 1301 sleep((caddr_t)&tp->t_rawq, TTIPRI); 1302 splx(s); 1303 goto loop; 1304 } 1305 splx(s); 1306 1307 /* 1308 * Input present, check for input mapping and processing. 1309 */ 1310 first = 1; 1311 while ((c = getc(qp)) >= 0) { 1312 /* 1313 * delayed suspend (^Y) 1314 */ 1315 if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) { 1316 gsignal(tp->t_pgrp, SIGTSTP); 1317 if (first) { 1318 sleep((caddr_t)&lbolt, TTIPRI); 1319 goto loop; 1320 } 1321 break; 1322 } 1323 /* 1324 * Interpret EOF only in canonical mode. 1325 */ 1326 if (CCEQ(cc[VEOF], c) && lflag&ICANON) 1327 break; 1328 /* 1329 * Give user character. 1330 */ 1331 error = ureadc(iflag&ISTRIP ? c & 0177 : c , uio); 1332 if (error) 1333 break; 1334 if (uio->uio_resid == 0) 1335 break; 1336 /* 1337 * In canonical mode check for a "break character" 1338 * marking the end of a "line of input". 1339 */ 1340 if (lflag&ICANON && ttbreakc(c)) { 1341 break; 1342 } 1343 first = 0; 1344 } 1345 1346 checktandem: 1347 /* 1348 * Look to unblock output now that (presumably) 1349 * the input queue has gone down. 1350 */ 1351 if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) { 1352 if (cc[VSTART] != POSIX_V_DISABLE 1353 && putc(cc[VSTART], &tp->t_outq) == 0) { 1354 tp->t_state &= ~TS_TBLOCK; 1355 ttstart(tp); 1356 } 1357 } 1358 return (error); 1359 } 1360 1361 /* 1362 * Check the output queue on tp for space for a kernel message 1363 * (from uprintf/tprintf). Allow some space over the normal 1364 * hiwater mark so we don't lose messages due to normal flow 1365 * control, but don't let the tty run amok. 1366 * Sleeps here are not interruptible, but we return prematurely 1367 * if new signals come in. 1368 */ 1369 ttycheckoutq(tp, wait) 1370 register struct tty *tp; 1371 int wait; 1372 { 1373 int hiwat, s, oldsig; 1374 1375 hiwat = TTHIWAT(tp); 1376 s = spltty(); 1377 oldsig = u.u_procp->p_sig; 1378 if (tp->t_outq.c_cc > hiwat + 200) 1379 while (tp->t_outq.c_cc > hiwat) { 1380 ttstart(tp); 1381 if (wait == 0 || u.u_procp->p_sig != oldsig) { 1382 splx(s); 1383 return (0); 1384 } 1385 timeout(wakeup, (caddr_t)&tp->t_outq, hz); 1386 tp->t_state |= TS_ASLEEP; 1387 sleep((caddr_t)&tp->t_outq, PZERO - 1); 1388 } 1389 splx(s); 1390 return (1); 1391 } 1392 1393 /* 1394 * Called from the device's write routine after it has 1395 * calculated the tty-structure given as argument. 1396 */ 1397 ttwrite(tp, uio) 1398 register struct tty *tp; 1399 register struct uio *uio; 1400 { 1401 register char *cp; 1402 register int cc, ce, c; 1403 int i, hiwat, cnt, error, s; 1404 char obuf[OBUFSIZ]; 1405 1406 hiwat = TTHIWAT(tp); 1407 cnt = uio->uio_resid; 1408 error = 0; 1409 loop: 1410 if ((tp->t_state&TS_CARR_ON) == 0) 1411 return (EIO); 1412 /* 1413 * Hang the process if it's in the background. 1414 */ 1415 if (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp && 1416 (tp->t_lflag&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 && 1417 !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) && 1418 !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) { 1419 gsignal(u.u_procp->p_pgrp, SIGTTOU); 1420 sleep((caddr_t)&lbolt, TTIPRI); 1421 goto loop; 1422 } 1423 1424 /* 1425 * Process the user's data in at most OBUFSIZ 1426 * chunks. Perform lower case simulation and 1427 * similar hacks. Keep track of high water 1428 * mark, sleep on overflow awaiting device aid 1429 * in acquiring new space. 1430 */ 1431 while (uio->uio_resid > 0) { 1432 if (tp->t_outq.c_cc > hiwat) { 1433 cc = 0; 1434 goto ovhiwat; 1435 } 1436 /* 1437 * Grab a hunk of data from the user. 1438 */ 1439 cc = uio->uio_iov->iov_len; 1440 if (cc == 0) { 1441 uio->uio_iovcnt--; 1442 uio->uio_iov++; 1443 if (uio->uio_iovcnt <= 0) 1444 panic("ttwrite"); 1445 continue; 1446 } 1447 if (cc > OBUFSIZ) 1448 cc = OBUFSIZ; 1449 cp = obuf; 1450 error = uiomove(cp, cc, UIO_WRITE, uio); 1451 if (error) 1452 break; 1453 if (tp->t_lflag&FLUSHO) 1454 continue; 1455 #ifdef notdef 1456 /* 1457 * If we're mapping lower case or kludging tildes, 1458 * then we've got to look at each character, so 1459 * just feed the stuff to ttyoutput... 1460 */ 1461 if (tp->t_flags & (LCASE|TILDE)) { 1462 while (cc > 0) { 1463 c = *cp++; 1464 tp->t_rocount = 0; 1465 while ((c = ttyoutput(c, tp)) >= 0) { 1466 /* out of clists, wait a bit */ 1467 ttstart(tp); 1468 sleep((caddr_t)&lbolt, TTOPRI); 1469 tp->t_rocount = 0; 1470 if (cc != 0) { 1471 uio->uio_iov->iov_base -= cc; 1472 uio->uio_iov->iov_len += cc; 1473 uio->uio_resid += cc; 1474 uio->uio_offset -= cc; 1475 } 1476 goto loop; 1477 } 1478 --cc; 1479 if (tp->t_outq.c_cc > hiwat) 1480 goto ovhiwat; 1481 } 1482 continue; 1483 } 1484 #endif 1485 /* 1486 * If nothing fancy need be done, grab those characters we 1487 * can handle without any of ttyoutput's processing and 1488 * just transfer them to the output q. For those chars 1489 * which require special processing (as indicated by the 1490 * bits in partab), call ttyoutput. After processing 1491 * a hunk of data, look for FLUSHO so ^O's will take effect 1492 * immediately. 1493 */ 1494 while (cc > 0) { 1495 if (!(tp->t_oflag&OPOST)) 1496 ce = cc; 1497 else { 1498 ce = cc - scanc((unsigned)cc, (caddr_t)cp, 1499 (caddr_t)partab, 077); 1500 /* 1501 * If ce is zero, then we're processing 1502 * a special character through ttyoutput. 1503 */ 1504 if (ce == 0) { 1505 tp->t_rocount = 0; 1506 if (ttyoutput(*cp, tp) >= 0) { 1507 /* no c-lists, wait a bit */ 1508 ttstart(tp); 1509 sleep((caddr_t)&lbolt, TTOPRI); 1510 if (cc != 0) { 1511 uio->uio_iov->iov_base -= cc; 1512 uio->uio_iov->iov_len += cc; 1513 uio->uio_resid += cc; 1514 uio->uio_offset -= cc; 1515 } 1516 goto loop; 1517 } 1518 cp++, cc--; 1519 if (tp->t_lflag&FLUSHO || 1520 tp->t_outq.c_cc > hiwat) 1521 goto ovhiwat; 1522 continue; 1523 } 1524 } 1525 /* 1526 * A bunch of normal characters have been found, 1527 * transfer them en masse to the output queue and 1528 * continue processing at the top of the loop. 1529 * If there are any further characters in this 1530 * <= OBUFSIZ chunk, the first should be a character 1531 * requiring special handling by ttyoutput. 1532 */ 1533 tp->t_rocount = 0; 1534 i = b_to_q(cp, ce, &tp->t_outq); 1535 ce -= i; 1536 tp->t_col += ce; 1537 cp += ce, cc -= ce, tk_nout += ce; 1538 if (i > 0) { 1539 /* out of c-lists, wait a bit */ 1540 ttstart(tp); 1541 sleep((caddr_t)&lbolt, TTOPRI); 1542 uio->uio_iov->iov_base -= cc; 1543 uio->uio_iov->iov_len += cc; 1544 uio->uio_resid += cc; 1545 uio->uio_offset -= cc; 1546 goto loop; 1547 } 1548 if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat) 1549 goto ovhiwat; 1550 } 1551 ttstart(tp); 1552 } 1553 return (error); 1554 1555 ovhiwat: 1556 if (cc != 0) { 1557 uio->uio_iov->iov_base -= cc; 1558 uio->uio_iov->iov_len += cc; 1559 uio->uio_resid += cc; 1560 uio->uio_offset -= cc; 1561 } 1562 ttstart(tp); 1563 s = spltty(); 1564 /* 1565 * This can only occur if FLUSHO is set in t_lflag, 1566 * or if ttstart/oproc is synchronous (or very fast). 1567 */ 1568 if (tp->t_outq.c_cc <= hiwat) { 1569 splx(s); 1570 goto loop; 1571 } 1572 if (tp->t_state&TS_NBIO) { 1573 splx(s); 1574 if (uio->uio_resid == cnt) 1575 return (EWOULDBLOCK); 1576 return (0); 1577 } 1578 tp->t_state |= TS_ASLEEP; 1579 sleep((caddr_t)&tp->t_outq, TTOPRI); 1580 splx(s); 1581 goto loop; 1582 } 1583 1584 /* 1585 * Rubout one character from the rawq of tp 1586 * as cleanly as possible. 1587 */ 1588 ttyrub(c, tp) 1589 register c; 1590 register struct tty *tp; 1591 { 1592 register char *cp; 1593 register int savecol; 1594 int s; 1595 char *nextc(); 1596 1597 if ((tp->t_lflag&ECHO) == 0) 1598 return; 1599 tp->t_lflag &= ~FLUSHO; 1600 c &= 0377; 1601 if (tp->t_lflag&ECHOE) { 1602 if (tp->t_rocount == 0) { 1603 /* 1604 * Screwed by ttwrite; retype 1605 */ 1606 ttyretype(tp); 1607 return; 1608 } 1609 /* if tab or newline was escaped - XXX - not 8bit */ 1610 if (c == ('\t'|0200) || c == ('\n'|0200)) 1611 ttyrubo(tp, 2); 1612 else switch (partab[c&=0177]&0177) { 1613 1614 case ORDINARY: 1615 #ifdef notdef 1616 if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z') 1617 ttyrubo(tp, 2); 1618 else 1619 #endif 1620 ttyrubo(tp, 1); 1621 break; 1622 1623 case VTAB: 1624 case BACKSPACE: 1625 case CONTROL: 1626 case RETURN: 1627 if (tp->t_lflag&ECHOCTL) 1628 ttyrubo(tp, 2); 1629 break; 1630 1631 case TAB: 1632 if (tp->t_rocount < tp->t_rawq.c_cc) { 1633 ttyretype(tp); 1634 return; 1635 } 1636 s = spltty(); 1637 savecol = tp->t_col; 1638 tp->t_state |= TS_CNTTB; 1639 tp->t_lflag |= FLUSHO; 1640 tp->t_col = tp->t_rocol; 1641 cp = tp->t_rawq.c_cf; 1642 for (; cp; cp = nextc(&tp->t_rawq, cp)) 1643 ttyecho(*cp, tp); 1644 tp->t_lflag &= ~FLUSHO; 1645 tp->t_state &= ~TS_CNTTB; 1646 splx(s); 1647 /* 1648 * savecol will now be length of the tab 1649 */ 1650 savecol -= tp->t_col; 1651 tp->t_col += savecol; 1652 if (savecol > 8) 1653 savecol = 8; /* overflow screw */ 1654 while (--savecol >= 0) 1655 (void) ttyoutput('\b', tp); 1656 break; 1657 1658 default: 1659 panic("ttyrub"); 1660 } 1661 } else if (tp->t_lflag&ECHOPRT) { 1662 if ((tp->t_state&TS_ERASE) == 0) { 1663 (void) ttyoutput('\\', tp); 1664 tp->t_state |= TS_ERASE; 1665 } 1666 ttyecho(c, tp); 1667 } else 1668 ttyecho(tp->t_cc[VERASE], tp); 1669 tp->t_rocount--; 1670 } 1671 1672 /* 1673 * Crt back over cnt chars perhaps 1674 * erasing them. 1675 */ 1676 ttyrubo(tp, cnt) 1677 register struct tty *tp; 1678 int cnt; 1679 { 1680 register char *rubostring = tp->t_lflag&ECHOE ? "\b \b" : "\b"; 1681 1682 while (--cnt >= 0) 1683 ttyout(rubostring, tp); 1684 } 1685 1686 /* 1687 * Reprint the rawq line. 1688 * We assume c_cc has already been checked. 1689 */ 1690 ttyretype(tp) 1691 register struct tty *tp; 1692 { 1693 register char *cp; 1694 char *nextc(); 1695 int s; 1696 1697 if (tp->t_cc[VREPRINT] != POSIX_V_DISABLE) 1698 ttyecho(tp->t_cc[VREPRINT], tp); 1699 (void) ttyoutput('\n', tp); 1700 s = spltty(); 1701 for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp)) 1702 ttyecho(*cp, tp); 1703 for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp)) 1704 ttyecho(*cp, tp); 1705 tp->t_state &= ~TS_ERASE; 1706 splx(s); 1707 tp->t_rocount = tp->t_rawq.c_cc; 1708 tp->t_rocol = 0; 1709 } 1710 1711 /* 1712 * Echo a typed character to the terminal. 1713 */ 1714 ttyecho(c, tp) 1715 register c; 1716 register struct tty *tp; 1717 { 1718 1719 c &= 0377; 1720 if ((tp->t_state&TS_CNTTB) == 0) 1721 tp->t_lflag &= ~FLUSHO; 1722 if ((tp->t_lflag&ECHO) == 0 && !(tp->t_lflag&ECHONL && c == '\n')) 1723 return; 1724 if (tp->t_lflag&ECHOCTL) { 1725 if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) { 1726 (void) ttyoutput('^', tp); 1727 c &= 0177; 1728 if (c == 0177) 1729 c = '?'; 1730 #ifdef notdef 1731 else if (tp->t_flags&LCASE) 1732 c += 'a' - 1; 1733 #endif 1734 else 1735 c += 'A' - 1; 1736 } 1737 } 1738 (void) ttyoutput(c&0177, tp); 1739 } 1740 1741 /* 1742 * send string cp to tp 1743 */ 1744 ttyout(cp, tp) 1745 register char *cp; 1746 register struct tty *tp; 1747 { 1748 register char c; 1749 1750 while (c = *cp++) 1751 (void) ttyoutput(c, tp); 1752 } 1753 1754 ttwakeup(tp) 1755 struct tty *tp; 1756 { 1757 1758 if (tp->t_rsel) { 1759 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL); 1760 tp->t_state &= ~TS_RCOLL; 1761 tp->t_rsel = 0; 1762 } 1763 if (tp->t_state & TS_ASYNC) 1764 gsignal(tp->t_pgrp, SIGIO); 1765 wakeup((caddr_t)&tp->t_rawq); 1766 } 1767