* Just like the old TTY implementation, we need to copy data in chunks * into a temporary buffer. One of the reasons why we need to do this, * is because output processing (only TAB3 though) may allow the buffer * to grow eight times. */
| 452 | * to grow eight times. |
| 453 | */ |
| 454 | int |
| 455 | ttydisc_write(struct tty *tp, struct uio *uio, int ioflag) |
| 456 | { |
| 457 | char ob[TTY_STACKBUF]; |
| 458 | char *obstart; |
| 459 | int error = 0; |
| 460 | unsigned int oblen = 0; |
| 461 | |
| 462 | tty_assert_locked(tp); |
| 463 | |
| 464 | if (tp->t_flags & TF_ZOMBIE) |
| 465 | return (EIO); |
| 466 | |
| 467 | /* |
| 468 | * We don't need to check whether the process is the foreground |
| 469 | * process group or if we have a carrier. This is already done |
| 470 | * in ttydev_write(). |
| 471 | */ |
| 472 | |
| 473 | while (uio->uio_resid > 0) { |
| 474 | unsigned int nlen; |
| 475 | |
| 476 | MPASS(oblen == 0); |
| 477 | |
| 478 | if (CMP_FLAG(l, FLUSHO)) { |
| 479 | uio->uio_offset += uio->uio_resid; |
| 480 | uio->uio_resid = 0; |
| 481 | return (0); |
| 482 | } |
| 483 | |
| 484 | /* Step 1: read data. */ |
| 485 | obstart = ob; |
| 486 | nlen = MIN(uio->uio_resid, sizeof ob); |
| 487 | tty_unlock(tp); |
| 488 | error = uiomove(ob, nlen, uio); |
| 489 | tty_lock(tp); |
| 490 | if (error != 0) |
| 491 | break; |
| 492 | oblen = nlen; |
| 493 | |
| 494 | if (tty_gone(tp)) { |
| 495 | error = ENXIO; |
| 496 | break; |
| 497 | } |
| 498 | |
| 499 | MPASS(oblen > 0); |
| 500 | |
| 501 | /* Step 2: process data. */ |
| 502 | do { |
| 503 | unsigned int plen, wlen; |
| 504 | |
| 505 | if (CMP_FLAG(l, FLUSHO)) { |
| 506 | uio->uio_offset += uio->uio_resid; |
| 507 | uio->uio_resid = 0; |
| 508 | return (0); |
| 509 | } |
| 510 | |
| 511 | /* Search for special characters for post processing. */ |
no test coverage detected