]> git.ipfire.org Git - thirdparty/coreutils.git/commit
tee: support non blocking outputs
authorPádraig Brady <P@draigBrady.com>
Sun, 5 Mar 2023 15:51:32 +0000 (15:51 +0000)
committerPádraig Brady <P@draigBrady.com>
Wed, 8 Mar 2023 18:32:05 +0000 (18:32 +0000)
commit16000805eb1bcdf25360471b8bbc8ec3f025e035
tree62f3c3de4d34462cac20967433b827bc4cf9cb1e
parent176b74f0e7360d94450c5aa3cf7db2ab86ed28c8
tee: support non blocking outputs

Non blocking outputs can be seen for example
when piping telnet through tee to a terminal.
In that case telnet sets its input to nonblocking mode,
which results in tee's output being nonblocking,
in which case in may receive an EAGAIN error upon write().
The same issue was seen with mpirun.
The following can be used to reproduce this
locally at a terminal (in most invocations):

  $ { dd iflag=nonblock count=0 status=none;
      dd bs=10K count=10 if=/dev/zero status=none; } |
    tee || echo fail >/dev/tty

* src/iopoll.c (iopoll_internal): A new function refactored from
iopoll(), to also support a mode where we check the output
descriptor is writeable.
(iopoll): Now refactored to just call iopoll_internal().
(fwait_for_nonblocking_write): A new internal function which
uses iopoll_internal() to wait for writeable output
if an EAGAIN or EWOULDBLOCK was received.
(fwrite_nonblock): An fwrite() wrapper which uses
fwait_for_nonblocking_write() to handle EAGAIN.
(fclose_nonblock): Likewise.
src/iopoll.h: Add fclose_nonblock, fwrite_nonblock.
src/tee.c: Call fclose_nonblock() and fwrite_nonblock wrappers,
instead of the standard functions.
* tests/misc/tee.sh: Add a test case.
* NEWS: Mention the improvement.

The idea was suggested by Kamil Dudka in
https://bugzilla.redhat.com/1615467
NEWS
src/iopoll.c
src/iopoll.h
src/tee.c
tests/misc/tee.sh