From 3f2f05f06763d79a7cab525a3ea2d726df3e3736 Mon Sep 17 00:00:00 2001 From: Pádraig Brady Date: Mon, 16 Feb 2015 13:19:20 +0000 Subject: tee: exit early if no more writable outputs * src/tee.c (main): Don't continue reading if we can't output anywhere. * tests/misc/tee.sh: Ensure we exit when no more outputs. * NEWS: Mention the change in behavior. --- NEWS | 2 ++ src/tee.c | 13 ++++++++++++- tests/misc/tee.sh | 25 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5bc942c52..b6795aacf 100644 --- a/NEWS +++ b/NEWS @@ -71,6 +71,8 @@ GNU coreutils NEWS -*- outline -*- insensitive file systems like HFS, mv would just remove a hardlinked 'file' if called like `mv file File`. The feature was added in coreutils-5.0.1. + tee will exit early if there are no more writable outputs. + ** Improvements cp,install,mv will convert smaller runs of NULs in the input to holes, diff --git a/src/tee.c b/src/tee.c index 04b7ec322..bfe1b6900 100644 --- a/src/tee.c +++ b/src/tee.c @@ -135,6 +135,7 @@ main (int argc, char **argv) static bool tee_files (int nfiles, const char **files) { + size_t n_outputs = 0; FILE **descriptors; char buffer[BUFSIZ]; ssize_t bytes_read; @@ -164,6 +165,7 @@ tee_files (int nfiles, const char **files) descriptors[0] = stdout; files[0] = _("standard output"); setvbuf (stdout, NULL, _IONBF, 0); + n_outputs++; for (i = 1; i <= nfiles; i++) { @@ -176,7 +178,10 @@ tee_files (int nfiles, const char **files) ok = false; } else - setvbuf (descriptors[i], NULL, _IONBF, 0); + { + setvbuf (descriptors[i], NULL, _IONBF, 0); + n_outputs++; + } } while (1) @@ -194,9 +199,15 @@ tee_files (int nfiles, const char **files) && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1) { error (0, errno, "%s", files[i]); + if (descriptors[i] == stdout) + clearerr (stdout); /* Avoid redundant close_stdout diagnostic. */ descriptors[i] = NULL; ok = false; + n_outputs--; } + + if (n_outputs == 0) + break; } if (bytes_read == -1) diff --git a/tests/misc/tee.sh b/tests/misc/tee.sh index 3c3fd11d7..5f2eeda7b 100755 --- a/tests/misc/tee.sh +++ b/tests/misc/tee.sh @@ -31,4 +31,29 @@ for n in 0 $nums; do done done + +# Ensure tee exits early if no more writable outputs +if test -w /dev/full && test -c /dev/full; then + yes | returns_ 1 timeout 10 tee /dev/full 2>err >/dev/full || fail=1 + # Ensure an error for each of the 2 outputs + # (and no redundant errors for stdout). + test $(wc -l < err) = 2 || { cat err; fail=1; } + + + # Ensure we continue with outputs that are OK + seq 10000 > multi_read || framework_failure_ + + returns_ 1 tee /dev/full out2 2>err >out1 err >/dev/full