]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: terminate when following pipes and untailable non pipes
authorPádraig Brady <P@draigBrady.com>
Tue, 8 Nov 2016 17:34:44 +0000 (17:34 +0000)
committerPádraig Brady <P@draigBrady.com>
Tue, 8 Nov 2016 23:19:08 +0000 (23:19 +0000)
* 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.

NEWS
src/tail.c
tests/tail-2/pipe-f.sh

diff --git a/NEWS b/NEWS
index 200c12b906da856b8642c07d3186af3bd2653a3b..7780d528820826a9c9f549b24196c815dd3ba06d 100644 (file)
--- 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]
 
index 718fc8a347797f673ddaf706601819ae4109a6a8..96982ed5b72e7b5a765596bcb11234a33de8fc2a 100644 (file)
@@ -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;
     }
index 7abb7d6feb06a0117e9c46b45b17f4ab30da59f2..82364dacce594eed9bc973bb1efca373ae7e81ad 100755 (executable)
 . "${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