]> git.ipfire.org Git - thirdparty/coreutils.git/commit
all: add broken pipe detection while waiting for input
authorCarl Edquist <edquist@cs.wisc.edu>
Thu, 15 Dec 2022 12:10:33 +0000 (06:10 -0600)
committerPádraig Brady <P@draigBrady.com>
Tue, 28 Feb 2023 14:02:38 +0000 (14:02 +0000)
commitb5c421a78431e707a3713df2de9e08e00f63feff
tree2d4fa780943d22a262ed3b0dae3e242e18bfcb14
parent0175e337a8bc4f390692d577cb655411bd44d53e
all: add broken pipe detection while waiting for input

When a program's output becomes a broken pipe, future attempts to write
to that ouput will fail (SIGPIPE/EPIPE).  Once it is known that all
future write attepts will fail (due to broken pipes), in many cases it
becomes pointless to wait for further input for slow devices like ttys.
Ideally, a program could use this information to exit early once it is
known that future writes will fail.

Introduce iopoll() to wait on a pair of fds (input & output) for input
to become ready or output to become a broken pipe.

This is relevant when input is intermittent (a tty, pipe, or socket);
but if input is always ready (a regular file or block device), then
a read() will not block, and write failures for a broken pipe will
happen normally.

Introduce iopoll_input_ok() to check whether an input fd is relevant
for iopoll().

Experimentally, broken pipes are only detectable immediately for pipes,
but not sockets.  Errors for other file types will be detected in the
usual way, on write failure.

Introduce iopoll_output_ok() to check whether an output fd is suitable
for iopoll() -- namely, whether it is a pipe.

iopoll() is best implemented with a native poll(2) where possible, but
fall back to a select(2)-based implementation platforms where there are
portability issues.  See also discussion in tail.c.

In general, adding a call to iopoll() before a read() in filter programs
also allows broken pipes to "propagate" backwards in a shell pipeline.

* src/iopoll.c, src/iopoll.h (iopoll): New function implementing broken
pipe detection on output while waiting for input.
(IOPOLL_BROKEN_OUTPUT, IOPOLL_ERROR): Return codes for iopoll().
(IOPOLL_USES_POLL): Macro for poll() vs select() implementation.
(iopoll_input_ok): New function to check whether an input fd is relevant
for iopoll().
(iopoll_output_ok): New function to check whether an input fd is
suitable for iopoll().
* src/local.mk (noinst_HEADERS): add src/iopoll.h.
src/iopoll.c [new file with mode: 0644]
src/iopoll.h [new file with mode: 0644]
src/local.mk