* 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. */
| 473 | * to grow eight times. |
| 474 | */ |
| 475 | int ttydisc_write(struct lwp_tty *tp, struct uio *uio, int ioflag) |
| 476 | { |
| 477 | char ob[TTY_STACKBUF]; |
| 478 | char *obstart; |
| 479 | int error = 0; |
| 480 | unsigned int oblen = 0; |
| 481 | |
| 482 | tty_assert_locked(tp); |
| 483 | |
| 484 | if (tp->t_flags & TF_ZOMBIE) |
| 485 | return -EIO; |
| 486 | |
| 487 | /* |
| 488 | * We don't need to check whether the process is the foreground |
| 489 | * process group or if we have a carrier. This is already done |
| 490 | * in ttydev_write(). |
| 491 | */ |
| 492 | |
| 493 | while (uio->uio_resid > 0) |
| 494 | { |
| 495 | unsigned int nlen; |
| 496 | |
| 497 | MPASS(oblen == 0); |
| 498 | |
| 499 | if (CMP_FLAG(l, FLUSHO)) |
| 500 | { |
| 501 | uio->uio_offset += uio->uio_resid; |
| 502 | uio->uio_resid = 0; |
| 503 | return 0; |
| 504 | } |
| 505 | |
| 506 | /* Step 1: read data. */ |
| 507 | obstart = ob; |
| 508 | nlen = MIN(uio->uio_resid, sizeof ob); |
| 509 | tty_unlock(tp); |
| 510 | error = uiomove(ob, nlen, uio); |
| 511 | tty_lock(tp); |
| 512 | if (error != 0) |
| 513 | break; |
| 514 | oblen = nlen; |
| 515 | |
| 516 | if (tty_gone(tp)) |
| 517 | { |
| 518 | error = -ENXIO; |
| 519 | break; |
| 520 | } |
| 521 | |
| 522 | MPASS(oblen > 0); |
| 523 | |
| 524 | /* Step 2: process data. */ |
| 525 | do |
| 526 | { |
| 527 | unsigned int plen, wlen; |
| 528 | |
| 529 | if (CMP_FLAG(l, FLUSHO)) |
| 530 | { |
| 531 | uio->uio_offset += uio->uio_resid; |
| 532 | uio->uio_resid = 0; |
no test coverage detected