1 /*- 2 * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Portions of this software were developed under sponsorship from Snow 6 * B.V., the Netherlands. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/fcntl.h> 35 #include <sys/filio.h> 36 #include <sys/kernel.h> 37 #include <sys/signal.h> 38 #include <sys/sysctl.h> 39 #include <sys/systm.h> 40 #include <sys/tty.h> 41 #include <sys/ttycom.h> 42 #include <sys/ttydefaults.h> 43 #include <sys/uio.h> 44 #include <sys/vnode.h> 45 46 /* 47 * Standard TTYDISC `termios' line discipline. 48 */ 49 50 /* Statistics. */ 51 static unsigned long tty_nin = 0; 52 SYSCTL_ULONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD, 53 &tty_nin, 0, "Total amount of bytes received"); 54 static unsigned long tty_nout = 0; 55 SYSCTL_ULONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD, 56 &tty_nout, 0, "Total amount of bytes transmitted"); 57 58 /* termios comparison macro's. */ 59 #define CMP_CC(v,c) (tp->t_termios.c_cc[v] != _POSIX_VDISABLE && \ 60 tp->t_termios.c_cc[v] == (c)) 61 #define CMP_FLAG(field,opt) (tp->t_termios.c_ ## field ## flag & (opt)) 62 63 /* Characters that cannot be modified through c_cc. */ 64 #define CTAB '\t' 65 #define CNL '\n' 66 #define CCR '\r' 67 68 /* Character is a control character. */ 69 #define CTL_VALID(c) ((c) == 0x7f || (unsigned char)(c) < 0x20) 70 /* Control character should be processed on echo. */ 71 #define CTL_ECHO(c,q) (!(q) && ((c) == CERASE2 || (c) == CTAB || \ 72 (c) == CNL || (c) == CCR)) 73 /* Control character should be printed using ^X notation. */ 74 #define CTL_PRINT(c,q) ((c) == 0x7f || ((unsigned char)(c) < 0x20 && \ 75 ((q) || ((c) != CTAB && (c) != CNL)))) 76 /* Character is whitespace. */ 77 #define CTL_WHITE(c) ((c) == ' ' || (c) == CTAB) 78 /* Character is alphanumeric. */ 79 #define CTL_ALNUM(c) (((c) >= '0' && (c) <= '9') || \ 80 ((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 81 82 #define TTY_STACKBUF 256 83 84 void 85 ttydisc_open(struct tty *tp) 86 { 87 ttydisc_optimize(tp); 88 } 89 90 void 91 ttydisc_close(struct tty *tp) 92 { 93 94 /* Clean up our flags when leaving the discipline. */ 95 tp->t_flags &= ~(TF_STOPPED|TF_HIWAT|TF_ZOMBIE); 96 97 /* POSIX states we should flush when close() is called. */ 98 ttyinq_flush(&tp->t_inq); 99 ttyoutq_flush(&tp->t_outq); 100 101 if (!tty_gone(tp)) { 102 ttydevsw_inwakeup(tp); 103 ttydevsw_outwakeup(tp); 104 } 105 106 if (ttyhook_hashook(tp, close)) 107 ttyhook_close(tp); 108 } 109 110 static int 111 ttydisc_read_canonical(struct tty *tp, struct uio *uio, int ioflag) 112 { 113 char breakc[4] = { CNL }; /* enough to hold \n, VEOF and VEOL. */ 114 int error; 115 size_t clen, flen = 0, n = 1; 116 unsigned char lastc = _POSIX_VDISABLE; 117 118 #define BREAK_ADD(c) do { \ 119 if (tp->t_termios.c_cc[c] != _POSIX_VDISABLE) \ 120 breakc[n++] = tp->t_termios.c_cc[c]; \ 121 } while (0) 122 /* Determine which characters we should trigger on. */ 123 BREAK_ADD(VEOF); 124 BREAK_ADD(VEOL); 125 #undef BREAK_ADD 126 breakc[n] = '\0'; 127 128 do { 129 /* 130 * Quite a tricky case: unlike the old TTY 131 * implementation, this implementation copies data back 132 * to userspace in large chunks. Unfortunately, we can't 133 * calculate the line length on beforehand if it crosses 134 * ttyinq_block boundaries, because multiple reads could 135 * then make this code read beyond the newline. 136 * 137 * This is why we limit the read to: 138 * - The size the user has requested 139 * - The blocksize (done in tty_inq.c) 140 * - The amount of bytes until the newline 141 * 142 * This causes the line length to be recalculated after 143 * each block has been copied to userspace. This will 144 * cause the TTY layer to return data in chunks using 145 * the blocksize (except the first and last blocks). 146 */ 147 clen = ttyinq_findchar(&tp->t_inq, breakc, uio->uio_resid, 148 &lastc); 149 150 /* No more data. */ 151 if (clen == 0) { 152 if (tp->t_flags & TF_ZOMBIE) 153 return (0); 154 else if (ioflag & IO_NDELAY) 155 return (EWOULDBLOCK); 156 157 error = tty_wait(tp, &tp->t_inwait); 158 if (error) 159 return (error); 160 continue; 161 } 162 163 /* Don't send the EOF char back to userspace. */ 164 if (CMP_CC(VEOF, lastc)) 165 flen = 1; 166 167 MPASS(flen <= clen); 168 169 /* Read and throw away the EOF character. */ 170 error = ttyinq_read_uio(&tp->t_inq, tp, uio, clen, flen); 171 if (error) 172 return (error); 173 174 } while (uio->uio_resid > 0 && lastc == _POSIX_VDISABLE); 175 176 return (0); 177 } 178 179 static int 180 ttydisc_read_raw_no_timer(struct tty *tp, struct uio *uio, int ioflag) 181 { 182 size_t vmin = tp->t_termios.c_cc[VMIN]; 183 ssize_t oresid = uio->uio_resid; 184 int error; 185 186 MPASS(tp->t_termios.c_cc[VTIME] == 0); 187 188 /* 189 * This routine implements the easy cases of read()s while in 190 * non-canonical mode, namely case B and D, where we don't have 191 * any timers at all. 192 */ 193 194 for (;;) { 195 error = ttyinq_read_uio(&tp->t_inq, tp, uio, 196 uio->uio_resid, 0); 197 if (error) 198 return (error); 199 if (uio->uio_resid == 0 || (oresid - uio->uio_resid) >= vmin) 200 return (0); 201 202 /* We have to wait for more. */ 203 if (tp->t_flags & TF_ZOMBIE) 204 return (0); 205 else if (ioflag & IO_NDELAY) 206 return (EWOULDBLOCK); 207 208 error = tty_wait(tp, &tp->t_inwait); 209 if (error) 210 return (error); 211 } 212 } 213 214 static int 215 ttydisc_read_raw_read_timer(struct tty *tp, struct uio *uio, int ioflag, 216 int oresid) 217 { 218 size_t vmin = MAX(tp->t_termios.c_cc[VMIN], 1); 219 unsigned int vtime = tp->t_termios.c_cc[VTIME]; 220 struct timeval end, now, left; 221 int error, hz; 222 223 MPASS(tp->t_termios.c_cc[VTIME] != 0); 224 225 /* Determine when the read should be expired. */ 226 end.tv_sec = vtime / 10; 227 end.tv_usec = (vtime % 10) * 100000; 228 getmicrotime(&now); 229 timevaladd(&end, &now); 230 231 for (;;) { 232 error = ttyinq_read_uio(&tp->t_inq, tp, uio, 233 uio->uio_resid, 0); 234 if (error) 235 return (error); 236 if (uio->uio_resid == 0 || (oresid - uio->uio_resid) >= vmin) 237 return (0); 238 239 /* Calculate how long we should wait. */ 240 getmicrotime(&now); 241 if (timevalcmp(&now, &end, >)) 242 return (0); 243 left = end; 244 timevalsub(&left, &now); 245 hz = tvtohz(&left); 246 247 /* 248 * We have to wait for more. If the timer expires, we 249 * should return a 0-byte read. 250 */ 251 if (tp->t_flags & TF_ZOMBIE) 252 return (0); 253 else if (ioflag & IO_NDELAY) 254 return (EWOULDBLOCK); 255 256 error = tty_timedwait(tp, &tp->t_inwait, hz); 257 if (error) 258 return (error == EWOULDBLOCK ? 0 : error); 259 } 260 261 return (0); 262 } 263 264 static int 265 ttydisc_read_raw_interbyte_timer(struct tty *tp, struct uio *uio, int ioflag) 266 { 267 size_t vmin = tp->t_termios.c_cc[VMIN]; 268 ssize_t oresid = uio->uio_resid; 269 int error; 270 271 MPASS(tp->t_termios.c_cc[VMIN] != 0); 272 MPASS(tp->t_termios.c_cc[VTIME] != 0); 273 274 /* 275 * When using the interbyte timer, the timer should be started 276 * after the first byte has been received. We just call into the 277 * generic read timer code after we've received the first byte. 278 */ 279 280 for (;;) { 281 error = ttyinq_read_uio(&tp->t_inq, tp, uio, 282 uio->uio_resid, 0); 283 if (error) 284 return (error); 285 if (uio->uio_resid == 0 || (oresid - uio->uio_resid) >= vmin) 286 return (0); 287 288 /* 289 * Not enough data, but we did receive some, which means 290 * we'll now start using the interbyte timer. 291 */ 292 if (oresid != uio->uio_resid) 293 break; 294 295 /* We have to wait for more. */ 296 if (tp->t_flags & TF_ZOMBIE) 297 return (0); 298 else if (ioflag & IO_NDELAY) 299 return (EWOULDBLOCK); 300 301 error = tty_wait(tp, &tp->t_inwait); 302 if (error) 303 return (error); 304 } 305 306 return ttydisc_read_raw_read_timer(tp, uio, ioflag, oresid); 307 } 308 309 int 310 ttydisc_read(struct tty *tp, struct uio *uio, int ioflag) 311 { 312 int error; 313 314 tty_lock_assert(tp, MA_OWNED); 315 316 if (uio->uio_resid == 0) 317 return (0); 318 319 if (CMP_FLAG(l, ICANON)) 320 error = ttydisc_read_canonical(tp, uio, ioflag); 321 else if (tp->t_termios.c_cc[VTIME] == 0) 322 error = ttydisc_read_raw_no_timer(tp, uio, ioflag); 323 else if (tp->t_termios.c_cc[VMIN] == 0) 324 error = ttydisc_read_raw_read_timer(tp, uio, ioflag, 325 uio->uio_resid); 326 else 327 error = ttydisc_read_raw_interbyte_timer(tp, uio, ioflag); 328 329 if (ttyinq_bytesleft(&tp->t_inq) >= tp->t_inlow || 330 ttyinq_bytescanonicalized(&tp->t_inq) == 0) { 331 /* Unset the input watermark when we've got enough space. */ 332 tty_hiwat_in_unblock(tp); 333 } 334 335 return (error); 336 } 337 338 static __inline unsigned int 339 ttydisc_findchar(const char *obstart, unsigned int oblen) 340 { 341 const char *c = obstart; 342 343 while (oblen--) { 344 if (CTL_VALID(*c)) 345 break; 346 c++; 347 } 348 349 return (c - obstart); 350 } 351 352 static int 353 ttydisc_write_oproc(struct tty *tp, char c) 354 { 355 unsigned int scnt, error; 356 357 MPASS(CMP_FLAG(o, OPOST)); 358 MPASS(CTL_VALID(c)); 359 360 #define PRINT_NORMAL() ttyoutq_write_nofrag(&tp->t_outq, &c, 1) 361 switch (c) { 362 case CEOF: 363 /* End-of-text dropping. */ 364 if (CMP_FLAG(o, ONOEOT)) 365 return (0); 366 return PRINT_NORMAL(); 367 368 case CERASE2: 369 /* Handle backspace to fix tab expansion. */ 370 if (PRINT_NORMAL() != 0) 371 return (-1); 372 if (tp->t_column > 0) 373 tp->t_column--; 374 return (0); 375 376 case CTAB: 377 /* Tab expansion. */ 378 scnt = 8 - (tp->t_column & 7); 379 if (CMP_FLAG(o, TAB3)) { 380 error = ttyoutq_write_nofrag(&tp->t_outq, 381 " ", scnt); 382 } else { 383 error = PRINT_NORMAL(); 384 } 385 if (error) 386 return (-1); 387 388 tp->t_column += scnt; 389 MPASS((tp->t_column % 8) == 0); 390 return (0); 391 392 case CNL: 393 /* Newline conversion. */ 394 if (CMP_FLAG(o, ONLCR)) { 395 /* Convert \n to \r\n. */ 396 error = ttyoutq_write_nofrag(&tp->t_outq, "\r\n", 2); 397 } else { 398 error = PRINT_NORMAL(); 399 } 400 if (error) 401 return (-1); 402 403 if (CMP_FLAG(o, ONLCR|ONLRET)) { 404 tp->t_column = tp->t_writepos = 0; 405 ttyinq_reprintpos_set(&tp->t_inq); 406 } 407 return (0); 408 409 case CCR: 410 /* Carriage return to newline conversion. */ 411 if (CMP_FLAG(o, OCRNL)) 412 c = CNL; 413 /* Omit carriage returns on column 0. */ 414 if (CMP_FLAG(o, ONOCR) && tp->t_column == 0) 415 return (0); 416 if (PRINT_NORMAL() != 0) 417 return (-1); 418 419 tp->t_column = tp->t_writepos = 0; 420 ttyinq_reprintpos_set(&tp->t_inq); 421 return (0); 422 } 423 424 /* 425 * Invisible control character. Print it, but don't 426 * increase the column count. 427 */ 428 return PRINT_NORMAL(); 429 #undef PRINT_NORMAL 430 } 431 432 /* 433 * Just like the old TTY implementation, we need to copy data in chunks 434 * into a temporary buffer. One of the reasons why we need to do this, 435 * is because output processing (only TAB3 though) may allow the buffer 436 * to grow eight times. 437 */ 438 int 439 ttydisc_write(struct tty *tp, struct uio *uio, int ioflag) 440 { 441 char ob[TTY_STACKBUF]; 442 char *obstart; 443 int error = 0; 444 unsigned int oblen = 0; 445 446 tty_lock_assert(tp, MA_OWNED); 447 448 if (tp->t_flags & TF_ZOMBIE) 449 return (EIO); 450 451 /* 452 * We don't need to check whether the process is the foreground 453 * process group or if we have a carrier. This is already done 454 * in ttydev_write(). 455 */ 456 457 while (uio->uio_resid > 0) { 458 unsigned int nlen; 459 460 MPASS(oblen == 0); 461 462 /* Step 1: read data. */ 463 obstart = ob; 464 nlen = MIN(uio->uio_resid, sizeof ob); 465 tty_unlock(tp); 466 error = uiomove(ob, nlen, uio); 467 tty_lock(tp); 468 if (error != 0) 469 break; 470 oblen = nlen; 471 472 if (tty_gone(tp)) { 473 error = ENXIO; 474 break; 475 } 476 477 MPASS(oblen > 0); 478 479 /* Step 2: process data. */ 480 do { 481 unsigned int plen, wlen; 482 483 /* Search for special characters for post processing. */ 484 if (CMP_FLAG(o, OPOST)) { 485 plen = ttydisc_findchar(obstart, oblen); 486 } else { 487 plen = oblen; 488 } 489 490 if (plen == 0) { 491 /* 492 * We're going to process a character 493 * that needs processing 494 */ 495 if (ttydisc_write_oproc(tp, *obstart) == 0) { 496 obstart++; 497 oblen--; 498 499 tp->t_writepos = tp->t_column; 500 ttyinq_reprintpos_set(&tp->t_inq); 501 continue; 502 } 503 } else { 504 /* We're going to write regular data. */ 505 wlen = ttyoutq_write(&tp->t_outq, obstart, plen); 506 obstart += wlen; 507 oblen -= wlen; 508 tp->t_column += wlen; 509 510 tp->t_writepos = tp->t_column; 511 ttyinq_reprintpos_set(&tp->t_inq); 512 513 if (wlen == plen) 514 continue; 515 } 516 517 /* Watermark reached. Try to sleep. */ 518 tp->t_flags |= TF_HIWAT_OUT; 519 520 if (ioflag & IO_NDELAY) { 521 error = EWOULDBLOCK; 522 goto done; 523 } 524 525 /* 526 * The driver may write back the data 527 * synchronously. Be sure to check the high 528 * water mark before going to sleep. 529 */ 530 ttydevsw_outwakeup(tp); 531 if ((tp->t_flags & TF_HIWAT_OUT) == 0) 532 continue; 533 534 error = tty_wait(tp, &tp->t_outwait); 535 if (error) 536 goto done; 537 538 if (tp->t_flags & TF_ZOMBIE) { 539 error = EIO; 540 goto done; 541 } 542 } while (oblen > 0); 543 } 544 545 done: 546 if (!tty_gone(tp)) 547 ttydevsw_outwakeup(tp); 548 549 /* 550 * Add the amount of bytes that we didn't process back to the 551 * uio counters. We need to do this to make sure write() doesn't 552 * count the bytes we didn't store in the queue. 553 */ 554 uio->uio_resid += oblen; 555 return (error); 556 } 557 558 void 559 ttydisc_optimize(struct tty *tp) 560 { 561 tty_lock_assert(tp, MA_OWNED); 562 563 if (ttyhook_hashook(tp, rint_bypass)) { 564 tp->t_flags |= TF_BYPASS; 565 } else if (ttyhook_hashook(tp, rint)) { 566 tp->t_flags &= ~TF_BYPASS; 567 } else if (!CMP_FLAG(i, ICRNL|IGNCR|IMAXBEL|INLCR|ISTRIP|IXON) && 568 (!CMP_FLAG(i, BRKINT) || CMP_FLAG(i, IGNBRK)) && 569 (!CMP_FLAG(i, PARMRK) || 570 CMP_FLAG(i, IGNPAR|IGNBRK) == (IGNPAR|IGNBRK)) && 571 !CMP_FLAG(l, ECHO|ICANON|IEXTEN|ISIG|PENDIN)) { 572 tp->t_flags |= TF_BYPASS; 573 } else { 574 tp->t_flags &= ~TF_BYPASS; 575 } 576 } 577 578 void 579 ttydisc_modem(struct tty *tp, int open) 580 { 581 582 tty_lock_assert(tp, MA_OWNED); 583 584 if (open) 585 cv_broadcast(&tp->t_dcdwait); 586 587 /* 588 * Ignore modem status lines when CLOCAL is turned on, but don't 589 * enter the zombie state when the TTY isn't opened, because 590 * that would cause the TTY to be in zombie state after being 591 * opened. 592 */ 593 if (!tty_opened(tp) || CMP_FLAG(c, CLOCAL)) 594 return; 595 596 if (open == 0) { 597 /* 598 * Lost carrier. 599 */ 600 tp->t_flags |= TF_ZOMBIE; 601 602 tty_signal_sessleader(tp, SIGHUP); 603 tty_flush(tp, FREAD|FWRITE); 604 } else { 605 /* 606 * Carrier is back again. 607 */ 608 609 /* XXX: what should we do here? */ 610 } 611 } 612 613 static int 614 ttydisc_echo_force(struct tty *tp, char c, int quote) 615 { 616 617 if (CMP_FLAG(o, OPOST) && CTL_ECHO(c, quote)) { 618 /* 619 * Only perform postprocessing when OPOST is turned on 620 * and the character is an unquoted BS/TB/NL/CR. 621 */ 622 return ttydisc_write_oproc(tp, c); 623 } else if (CMP_FLAG(l, ECHOCTL) && CTL_PRINT(c, quote)) { 624 /* 625 * Only use ^X notation when ECHOCTL is turned on and 626 * we've got an quoted control character. 627 * 628 * Print backspaces when echoing an end-of-file. 629 */ 630 char ob[4] = "^?\b\b"; 631 632 /* Print ^X notation. */ 633 if (c != 0x7f) 634 ob[1] = c + 'A' - 1; 635 636 if (!quote && CMP_CC(VEOF, c)) { 637 return ttyoutq_write_nofrag(&tp->t_outq, ob, 4); 638 } else { 639 tp->t_column += 2; 640 return ttyoutq_write_nofrag(&tp->t_outq, ob, 2); 641 } 642 } else { 643 /* Can just be printed. */ 644 tp->t_column++; 645 return ttyoutq_write_nofrag(&tp->t_outq, &c, 1); 646 } 647 } 648 649 static int 650 ttydisc_echo(struct tty *tp, char c, int quote) 651 { 652 653 /* 654 * Only echo characters when ECHO is turned on, or ECHONL when 655 * the character is an unquoted newline. 656 */ 657 if (!CMP_FLAG(l, ECHO) && 658 (!CMP_FLAG(l, ECHONL) || c != CNL || quote)) 659 return (0); 660 661 return ttydisc_echo_force(tp, c, quote); 662 } 663 664 static void 665 ttydisc_reprint_char(void *d, char c, int quote) 666 { 667 struct tty *tp = d; 668 669 ttydisc_echo(tp, c, quote); 670 } 671 672 static void 673 ttydisc_reprint(struct tty *tp) 674 { 675 cc_t c; 676 677 /* Print ^R\n, followed by the line. */ 678 c = tp->t_termios.c_cc[VREPRINT]; 679 if (c != _POSIX_VDISABLE) 680 ttydisc_echo(tp, c, 0); 681 ttydisc_echo(tp, CNL, 0); 682 ttyinq_reprintpos_reset(&tp->t_inq); 683 684 ttyinq_line_iterate_from_linestart(&tp->t_inq, ttydisc_reprint_char, tp); 685 } 686 687 struct ttydisc_recalc_length { 688 struct tty *tp; 689 unsigned int curlen; 690 }; 691 692 static void 693 ttydisc_recalc_charlength(void *d, char c, int quote) 694 { 695 struct ttydisc_recalc_length *data = d; 696 struct tty *tp = data->tp; 697 698 if (CTL_PRINT(c, quote)) { 699 if (CMP_FLAG(l, ECHOCTL)) 700 data->curlen += 2; 701 } else if (c == CTAB) { 702 data->curlen += 8 - (data->curlen & 7); 703 } else { 704 data->curlen++; 705 } 706 } 707 708 static unsigned int 709 ttydisc_recalc_linelength(struct tty *tp) 710 { 711 struct ttydisc_recalc_length data = { tp, tp->t_writepos }; 712 713 ttyinq_line_iterate_from_reprintpos(&tp->t_inq, 714 ttydisc_recalc_charlength, &data); 715 return (data.curlen); 716 } 717 718 static int 719 ttydisc_rubchar(struct tty *tp) 720 { 721 char c; 722 int quote; 723 unsigned int prevpos, tablen; 724 725 if (ttyinq_peekchar(&tp->t_inq, &c, "e) != 0) 726 return (-1); 727 ttyinq_unputchar(&tp->t_inq); 728 729 if (CMP_FLAG(l, ECHO)) { 730 /* 731 * Remove the character from the screen. This is even 732 * safe for characters that span multiple characters 733 * (tabs, quoted, etc). 734 */ 735 if (tp->t_writepos >= tp->t_column) { 736 /* Retype the sentence. */ 737 ttydisc_reprint(tp); 738 } else if (CMP_FLAG(l, ECHOE)) { 739 if (CTL_PRINT(c, quote)) { 740 /* Remove ^X formatted chars. */ 741 if (CMP_FLAG(l, ECHOCTL)) { 742 tp->t_column -= 2; 743 ttyoutq_write_nofrag(&tp->t_outq, 744 "\b\b \b\b", 6); 745 } 746 } else if (c == ' ') { 747 /* Space character needs no rubbing. */ 748 tp->t_column -= 1; 749 ttyoutq_write_nofrag(&tp->t_outq, "\b", 1); 750 } else if (c == CTAB) { 751 /* 752 * Making backspace work with tabs is 753 * quite hard. Recalculate the length of 754 * this character and remove it. 755 * 756 * Because terminal settings could be 757 * changed while the line is being 758 * inserted, the calculations don't have 759 * to be correct. Make sure we keep the 760 * tab length within proper bounds. 761 */ 762 prevpos = ttydisc_recalc_linelength(tp); 763 if (prevpos >= tp->t_column) 764 tablen = 1; 765 else 766 tablen = tp->t_column - prevpos; 767 if (tablen > 8) 768 tablen = 8; 769 770 tp->t_column = prevpos; 771 ttyoutq_write_nofrag(&tp->t_outq, 772 "\b\b\b\b\b\b\b\b", tablen); 773 return (0); 774 } else { 775 /* 776 * Remove a regular character by 777 * punching a space over it. 778 */ 779 tp->t_column -= 1; 780 ttyoutq_write_nofrag(&tp->t_outq, "\b \b", 3); 781 } 782 } else { 783 /* Don't print spaces. */ 784 ttydisc_echo(tp, tp->t_termios.c_cc[VERASE], 0); 785 } 786 } 787 788 return (0); 789 } 790 791 static void 792 ttydisc_rubword(struct tty *tp) 793 { 794 char c; 795 int quote, alnum; 796 797 /* Strip whitespace first. */ 798 for (;;) { 799 if (ttyinq_peekchar(&tp->t_inq, &c, "e) != 0) 800 return; 801 if (!CTL_WHITE(c)) 802 break; 803 ttydisc_rubchar(tp); 804 } 805 806 /* 807 * Record whether the last character from the previous iteration 808 * was alphanumeric or not. We need this to implement ALTWERASE. 809 */ 810 alnum = CTL_ALNUM(c); 811 for (;;) { 812 ttydisc_rubchar(tp); 813 814 if (ttyinq_peekchar(&tp->t_inq, &c, "e) != 0) 815 return; 816 if (CTL_WHITE(c)) 817 return; 818 if (CMP_FLAG(l, ALTWERASE) && CTL_ALNUM(c) != alnum) 819 return; 820 } 821 } 822 823 int 824 ttydisc_rint(struct tty *tp, char c, int flags) 825 { 826 int signal, quote = 0; 827 char ob[3] = { 0xff, 0x00 }; 828 size_t ol; 829 830 tty_lock_assert(tp, MA_OWNED); 831 832 atomic_add_long(&tty_nin, 1); 833 834 if (ttyhook_hashook(tp, rint)) 835 return ttyhook_rint(tp, c, flags); 836 837 if (tp->t_flags & TF_BYPASS) 838 goto processed; 839 840 if (flags) { 841 if (flags & TRE_BREAK) { 842 if (CMP_FLAG(i, IGNBRK)) { 843 /* Ignore break characters. */ 844 return (0); 845 } else if (CMP_FLAG(i, BRKINT)) { 846 /* Generate SIGINT on break. */ 847 tty_flush(tp, FREAD|FWRITE); 848 tty_signal_pgrp(tp, SIGINT); 849 return (0); 850 } else { 851 /* Just print it. */ 852 goto parmrk; 853 } 854 } else if (flags & TRE_FRAMING || 855 (flags & TRE_PARITY && CMP_FLAG(i, INPCK))) { 856 if (CMP_FLAG(i, IGNPAR)) { 857 /* Ignore bad characters. */ 858 return (0); 859 } else { 860 /* Just print it. */ 861 goto parmrk; 862 } 863 } 864 } 865 866 /* Allow any character to perform a wakeup. */ 867 if (CMP_FLAG(i, IXANY)) 868 tp->t_flags &= ~TF_STOPPED; 869 870 /* Remove the top bit. */ 871 if (CMP_FLAG(i, ISTRIP)) 872 c &= ~0x80; 873 874 /* Skip input processing when we want to print it literally. */ 875 if (tp->t_flags & TF_LITERAL) { 876 tp->t_flags &= ~TF_LITERAL; 877 quote = 1; 878 goto processed; 879 } 880 881 /* Special control characters that are implementation dependent. */ 882 if (CMP_FLAG(l, IEXTEN)) { 883 /* Accept the next character as literal. */ 884 if (CMP_CC(VLNEXT, c)) { 885 if (CMP_FLAG(l, ECHO)) { 886 if (CMP_FLAG(l, ECHOE)) 887 ttyoutq_write_nofrag(&tp->t_outq, "^\b", 2); 888 else 889 ttydisc_echo(tp, c, 0); 890 } 891 tp->t_flags |= TF_LITERAL; 892 return (0); 893 } 894 } 895 896 /* 897 * Handle signal processing. 898 */ 899 if (CMP_FLAG(l, ISIG)) { 900 if (CMP_FLAG(l, ICANON|IEXTEN) == (ICANON|IEXTEN)) { 901 if (CMP_CC(VSTATUS, c)) { 902 tty_signal_pgrp(tp, SIGINFO); 903 return (0); 904 } 905 } 906 907 /* 908 * When compared to the old implementation, this 909 * implementation also flushes the output queue. POSIX 910 * is really brief about this, but does makes us assume 911 * we have to do so. 912 */ 913 signal = 0; 914 if (CMP_CC(VINTR, c)) { 915 signal = SIGINT; 916 } else if (CMP_CC(VQUIT, c)) { 917 signal = SIGQUIT; 918 } else if (CMP_CC(VSUSP, c)) { 919 signal = SIGTSTP; 920 } 921 922 if (signal != 0) { 923 /* 924 * Echo the character before signalling the 925 * processes. 926 */ 927 if (!CMP_FLAG(l, NOFLSH)) 928 tty_flush(tp, FREAD|FWRITE); 929 ttydisc_echo(tp, c, 0); 930 tty_signal_pgrp(tp, signal); 931 return (0); 932 } 933 } 934 935 /* 936 * Handle start/stop characters. 937 */ 938 if (CMP_FLAG(i, IXON)) { 939 if (CMP_CC(VSTOP, c)) { 940 /* Stop it if we aren't stopped yet. */ 941 if ((tp->t_flags & TF_STOPPED) == 0) { 942 tp->t_flags |= TF_STOPPED; 943 return (0); 944 } 945 /* 946 * Fallthrough: 947 * When VSTART == VSTOP, we should make this key 948 * toggle it. 949 */ 950 if (!CMP_CC(VSTART, c)) 951 return (0); 952 } 953 if (CMP_CC(VSTART, c)) { 954 tp->t_flags &= ~TF_STOPPED; 955 return (0); 956 } 957 } 958 959 /* Conversion of CR and NL. */ 960 switch (c) { 961 case CCR: 962 if (CMP_FLAG(i, IGNCR)) 963 return (0); 964 if (CMP_FLAG(i, ICRNL)) 965 c = CNL; 966 break; 967 case CNL: 968 if (CMP_FLAG(i, INLCR)) 969 c = CCR; 970 break; 971 } 972 973 /* Canonical line editing. */ 974 if (CMP_FLAG(l, ICANON)) { 975 if (CMP_CC(VERASE, c) || CMP_CC(VERASE2, c)) { 976 ttydisc_rubchar(tp); 977 return (0); 978 } else if (CMP_CC(VKILL, c)) { 979 while (ttydisc_rubchar(tp) == 0); 980 return (0); 981 } else if (CMP_FLAG(l, IEXTEN)) { 982 if (CMP_CC(VWERASE, c)) { 983 ttydisc_rubword(tp); 984 return (0); 985 } else if (CMP_CC(VREPRINT, c)) { 986 ttydisc_reprint(tp); 987 return (0); 988 } 989 } 990 } 991 992 processed: 993 if (CMP_FLAG(i, PARMRK) && (unsigned char)c == 0xff) { 994 /* Print 0xff 0xff. */ 995 ob[1] = 0xff; 996 ol = 2; 997 quote = 1; 998 } else { 999 ob[0] = c; 1000 ol = 1; 1001 } 1002 1003 goto print; 1004 1005 parmrk: 1006 if (CMP_FLAG(i, PARMRK)) { 1007 /* Prepend 0xff 0x00 0x.. */ 1008 ob[2] = c; 1009 ol = 3; 1010 quote = 1; 1011 } else { 1012 ob[0] = c; 1013 ol = 1; 1014 } 1015 1016 print: 1017 /* See if we can store this on the input queue. */ 1018 if (ttyinq_write_nofrag(&tp->t_inq, ob, ol, quote) != 0) { 1019 if (CMP_FLAG(i, IMAXBEL)) 1020 ttyoutq_write_nofrag(&tp->t_outq, "\a", 1); 1021 1022 /* 1023 * Prevent a deadlock here. It may be possible that a 1024 * user has entered so much data, there is no data 1025 * available to read(), but the buffers are full anyway. 1026 * 1027 * Only enter the high watermark if the device driver 1028 * can actually transmit something. 1029 */ 1030 if (ttyinq_bytescanonicalized(&tp->t_inq) == 0) 1031 return (0); 1032 1033 tty_hiwat_in_block(tp); 1034 return (-1); 1035 } 1036 1037 /* 1038 * In raw mode, we canonicalize after receiving a single 1039 * character. Otherwise, we canonicalize when we receive a 1040 * newline, VEOL or VEOF, but only when it isn't quoted. 1041 */ 1042 if (!CMP_FLAG(l, ICANON) || 1043 (!quote && (c == CNL || CMP_CC(VEOL, c) || CMP_CC(VEOF, c)))) { 1044 ttyinq_canonicalize(&tp->t_inq); 1045 } 1046 1047 ttydisc_echo(tp, c, quote); 1048 1049 return (0); 1050 } 1051 1052 size_t 1053 ttydisc_rint_simple(struct tty *tp, const void *buf, size_t len) 1054 { 1055 const char *cbuf; 1056 1057 if (ttydisc_can_bypass(tp)) 1058 return (ttydisc_rint_bypass(tp, buf, len)); 1059 1060 for (cbuf = buf; len-- > 0; cbuf++) { 1061 if (ttydisc_rint(tp, *cbuf, 0) != 0) 1062 break; 1063 } 1064 1065 return (cbuf - (const char *)buf); 1066 } 1067 1068 size_t 1069 ttydisc_rint_bypass(struct tty *tp, const void *buf, size_t len) 1070 { 1071 size_t ret; 1072 1073 tty_lock_assert(tp, MA_OWNED); 1074 1075 MPASS(tp->t_flags & TF_BYPASS); 1076 1077 atomic_add_long(&tty_nin, len); 1078 1079 if (ttyhook_hashook(tp, rint_bypass)) 1080 return ttyhook_rint_bypass(tp, buf, len); 1081 1082 ret = ttyinq_write(&tp->t_inq, buf, len, 0); 1083 ttyinq_canonicalize(&tp->t_inq); 1084 if (ret < len) 1085 tty_hiwat_in_block(tp); 1086 1087 return (ret); 1088 } 1089 1090 void 1091 ttydisc_rint_done(struct tty *tp) 1092 { 1093 1094 tty_lock_assert(tp, MA_OWNED); 1095 1096 if (ttyhook_hashook(tp, rint_done)) 1097 ttyhook_rint_done(tp); 1098 1099 /* Wake up readers. */ 1100 tty_wakeup(tp, FREAD); 1101 /* Wake up driver for echo. */ 1102 ttydevsw_outwakeup(tp); 1103 } 1104 1105 size_t 1106 ttydisc_rint_poll(struct tty *tp) 1107 { 1108 size_t l; 1109 1110 tty_lock_assert(tp, MA_OWNED); 1111 1112 if (ttyhook_hashook(tp, rint_poll)) 1113 return ttyhook_rint_poll(tp); 1114 1115 /* 1116 * XXX: Still allow character input when there's no space in the 1117 * buffers, but we haven't entered the high watermark. This is 1118 * to allow backspace characters to be inserted when in 1119 * canonical mode. 1120 */ 1121 l = ttyinq_bytesleft(&tp->t_inq); 1122 if (l == 0 && (tp->t_flags & TF_HIWAT_IN) == 0) 1123 return (1); 1124 1125 return (l); 1126 } 1127 1128 static void 1129 ttydisc_wakeup_watermark(struct tty *tp) 1130 { 1131 size_t c; 1132 1133 c = ttyoutq_bytesleft(&tp->t_outq); 1134 if (tp->t_flags & TF_HIWAT_OUT) { 1135 /* Only allow us to run when we're below the watermark. */ 1136 if (c < tp->t_outlow) 1137 return; 1138 1139 /* Reset the watermark. */ 1140 tp->t_flags &= ~TF_HIWAT_OUT; 1141 } else { 1142 /* Only run when we have data at all. */ 1143 if (c == 0) 1144 return; 1145 } 1146 tty_wakeup(tp, FWRITE); 1147 } 1148 1149 size_t 1150 ttydisc_getc(struct tty *tp, void *buf, size_t len) 1151 { 1152 1153 tty_lock_assert(tp, MA_OWNED); 1154 1155 if (tp->t_flags & TF_STOPPED) 1156 return (0); 1157 1158 if (ttyhook_hashook(tp, getc_inject)) 1159 return ttyhook_getc_inject(tp, buf, len); 1160 1161 len = ttyoutq_read(&tp->t_outq, buf, len); 1162 1163 if (ttyhook_hashook(tp, getc_capture)) 1164 ttyhook_getc_capture(tp, buf, len); 1165 1166 ttydisc_wakeup_watermark(tp); 1167 atomic_add_long(&tty_nout, len); 1168 1169 return (len); 1170 } 1171 1172 int 1173 ttydisc_getc_uio(struct tty *tp, struct uio *uio) 1174 { 1175 int error = 0; 1176 ssize_t obytes = uio->uio_resid; 1177 size_t len; 1178 char buf[TTY_STACKBUF]; 1179 1180 tty_lock_assert(tp, MA_OWNED); 1181 1182 if (tp->t_flags & TF_STOPPED) 1183 return (0); 1184 1185 /* 1186 * When a TTY hook is attached, we cannot perform unbuffered 1187 * copying to userspace. Just call ttydisc_getc() and 1188 * temporarily store data in a shadow buffer. 1189 */ 1190 if (ttyhook_hashook(tp, getc_capture) || 1191 ttyhook_hashook(tp, getc_inject)) { 1192 while (uio->uio_resid > 0) { 1193 /* Read to shadow buffer. */ 1194 len = ttydisc_getc(tp, buf, 1195 MIN(uio->uio_resid, sizeof buf)); 1196 if (len == 0) 1197 break; 1198 1199 /* Copy to userspace. */ 1200 tty_unlock(tp); 1201 error = uiomove(buf, len, uio); 1202 tty_lock(tp); 1203 1204 if (error != 0) 1205 break; 1206 } 1207 } else { 1208 error = ttyoutq_read_uio(&tp->t_outq, tp, uio); 1209 1210 ttydisc_wakeup_watermark(tp); 1211 atomic_add_long(&tty_nout, obytes - uio->uio_resid); 1212 } 1213 1214 return (error); 1215 } 1216 1217 size_t 1218 ttydisc_getc_poll(struct tty *tp) 1219 { 1220 1221 tty_lock_assert(tp, MA_OWNED); 1222 1223 if (tp->t_flags & TF_STOPPED) 1224 return (0); 1225 1226 if (ttyhook_hashook(tp, getc_poll)) 1227 return ttyhook_getc_poll(tp); 1228 1229 return ttyoutq_bytesused(&tp->t_outq); 1230 } 1231 1232 /* 1233 * XXX: not really related to the TTYDISC, but we'd better put 1234 * tty_putchar() here, because we need to perform proper output 1235 * processing. 1236 */ 1237 1238 int 1239 tty_putchar(struct tty *tp, char c) 1240 { 1241 tty_lock_assert(tp, MA_OWNED); 1242 1243 if (tty_gone(tp)) 1244 return (-1); 1245 1246 ttydisc_echo_force(tp, c, 0); 1247 tp->t_writepos = tp->t_column; 1248 ttyinq_reprintpos_set(&tp->t_inq); 1249 1250 ttydevsw_outwakeup(tp); 1251 return (0); 1252 } 1253