[PATCH] input: Fix tee(2) error handling
Herbert Xu <[email protected]> Sun, 3 May 2026 12:19:16 +0800
| Newsgroups | org.kernel.vger.dash |
|---|---|
| Message-ID | <[email protected]> |
Matt Whitlock <[email protected]> wrote: > Dash 0.5.13.3: > > $ /bin/dash -c '{ echo 1; sleep 1; echo 2; } | while read -r line; do echo "${line}" & done' > 1 > ^C Thanks, this is a regression in the tee error handling code: ---8<--- The variable fd should only switch to the tee pipe if the tee(2) call succeeded, otherwise the retry will read the wrong file descriptor. Also remove the stdin_istty check in stdin_tee as the fallback path now requries setting errno to EINVAL. Instead of optimising for the rare case of a non-canonical input tty, just let the tee(2) call fail instead. Finally switch from pipe to sh_pipe. The pipe(2) call should never fail, and if it does, just abort the shell. Fixes: 41457be81fa7 ("input: Fix EINTR handling when reading from a pipe") Reported-by: Matt Whitlock <[email protected]> Signed-off-by: Herbert Xu <[email protected]> diff --git a/src/input.c b/src/input.c index 4e30010..591f28a 100644 --- a/src/input.c +++ b/src/input.c @@ -166,13 +166,8 @@ static int stdin_tee(void *buf, int nr) { int err; - if (stdin_istty) - return 0; - if (!stdin_state.pip[0]) { - err = pipe(stdin_state.pip); - if (err < 0) - return err; + sh_pipe(stdin_state.pip, 0); if (stdin_state.pip[0] < 10) stdin_state.pip[0] = savefd(stdin_state.pip[0], stdin_state.pip[0]); @@ -276,6 +271,7 @@ preadfd(void) { char *buf = parsefile->buf; int fd = parsefile->fd; + bool use_tee; int unget; int pnr; int nr; @@ -295,6 +291,12 @@ preadfd(void) if (!IS_DEFINED_SMALL && !nr) return nr; + use_tee = likely(!fd) && +#ifndef SMALL + !el && +#endif + !stdin_bufferable(); + pnr = nr; retry: nr = pnr; @@ -326,12 +328,13 @@ retry: } #endif - if (!fd && !stdin_bufferable()) { + if (likely(use_tee)) { nr = stdin_tee(buf, nr); - fd = stdin_state.pip[0]; - if (nr < 0 && errno == EINVAL) { - fd = 0; - nr = 1; + if (nr >= 0) + fd = stdin_state.pip[0]; + else if (errno == EINVAL) { + use_tee = false; + nr = pnr = 1; } } -- Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt