From: Pádraig Brady
Date: Tue, 8 Nov 2016 17:34:44 +0000 (+0000) Subject: tail: terminate when following pipes and untailable non pipes X-Git-Tag: v8.26~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a809125299261db9db9b97e93b5885223c6e9d3;p=thirdparty%2Fcoreutils.git tail: terminate when following pipes and untailable non pipes * src/tail.c (ignore_pipe_or_fifo): Mark the descriptor as -1 for pipes so that any_live_files() detects correctly that the entry is no longer live. * tests/tail-2/pipe-f.sh: Add a test case. * NEWS: Mention the fix. Fixes http://bugs.gnu.org/24903 which was detected using Symbolic Execution techniques developed in the course of the SYMBIOSYS research project at COMSYS, RWTH Aachen University. --- diff --git a/NEWS b/NEWS index 200c12b906..7780d52882 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,10 @@ GNU coreutils NEWS -*- outline -*- and is now handled correctly in all cases. [bug introduced in fileutils-4.0h] + tail -f - 'untailable file' will now terminate when there is no more data + to read from stdin. Previously it behaved as if --retry was specified. + [This bug was present in "the beginning".] + yes now handles short writes, rather than assuming all writes complete. [bug introduced in coreutils-8.24] diff --git a/src/tail.c b/src/tail.c index 718fc8a347..96982ed5b7 100644 --- a/src/tail.c +++ b/src/tail.c @@ -2212,7 +2212,10 @@ ignore_fifo_and_pipe (struct File_spec *f, size_t n_files) && (S_ISFIFO (f[i].mode) || (HAVE_FIFO_PIPES != 1 && isapipe (f[i].fd)))); if (is_a_fifo_or_pipe) - f[i].ignore = true; + { + f[i].fd = -1; + f[i].ignore = true; + } else ++n_viable; } diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh index 7abb7d6feb..82364dacce 100755 --- a/tests/tail-2/pipe-f.sh +++ b/tests/tail-2/pipe-f.sh @@ -19,9 +19,18 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ tail +echo oo > exp || framework_failure_ echo foo | timeout 10 tail -f -c3 > out || fail=1 -echo oo > exp || fail=1 +compare exp out || fail=1 + +cat <<\EOF > exp +==> standard input <== +ar +==> missing <== +EOF +mkdir missing || framework_failure_ +echo bar | returns_ 1 timeout 10 tail -f -c3 - missing > out || fail=1 compare exp out || fail=1 Exit $fail