]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: only retry file open if --retry specifed
authorPádraig Brady <P@draigBrady.com>
Wed, 9 Nov 2016 19:28:23 +0000 (19:28 +0000)
committerPádraig Brady <P@draigBrady.com>
Thu, 10 Nov 2016 12:43:42 +0000 (12:43 +0000)
* src/tail.c (tail_file): On failure to open a file,
set ignore=true when --retry is not specified.
* tests/tail-2/assert-2.sh: Adjust to the new behavior.
* tests/tail-2/retry.sh: Add a test case.  Also change
from `tail ... && fail=1` to the more robust `returns_ 1 ...`
construct which detects segfaults etc.
* NEWS: Document the fix.

NEWS
src/tail.c
tests/tail-2/assert-2.sh
tests/tail-2/retry.sh

diff --git a/NEWS b/NEWS
index d88fbd9d4d433045799cea81ba9efa194e8a4bd4..6dd6772dbb1dfd1a6290267a796550df0ef30713 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -63,6 +63,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   Previously truncation was ignored thus not outputting new data in the file.
   [bug introduced in coreutils-5.3.0]
 
+  tail -f will no longer continually try to open inaccessible files,
+  only doing so if --retry is 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 66aad5b7894e3373b5c02e8dabb455af7f86d48c..193e4fd7d21327bd9744a3391a2d389cfcd0732c 100644 (file)
@@ -1909,7 +1909,7 @@ tail_file (struct File_spec *f, uintmax_t n_units)
         {
           f->fd = -1;
           f->errnum = errno;
-          f->ignore = false;
+          f->ignore = ! reopen_inaccessible_files;
           f->ino = 0;
           f->dev = 0;
         }
index 79d4254ccd322b756aa0c1644e8b92f3499470c6..03ba8e2e6269b7efa44b22f58452f11a48e83865 100755 (executable)
@@ -38,7 +38,7 @@ for mode in '' '---disable-inotify'; do
   rm -f a foo out
   touch a || framework_failure_
 
-  tail $mode --follow=name $fastpoll a foo > out 2>&1 & pid=$!
+  tail $mode $fastpoll -F a foo > out 2>&1 & pid=$!
 
   # Wait up to 12.7s for tail to start.
   echo x > a || framework_failure_
index 858909f65f0f0905844fa31c505cf31302c611ee..7829923566c1660972b78616726e93445acd76ec 100755 (executable)
@@ -51,7 +51,7 @@ grep -F 'tail: warning: --retry ignored' out || { cat out; fail=1; }
 
 # === Test:
 # The same with a missing file: expect error message and exit 1.
-tail --retry missing > out 2>&1 && fail=1
+returns_ 1 tail --retry missing > out 2>&1 || fail=1
 [ "$(countlines_)" = 2 ]                     || { cat out; fail=1; }
 grep -F 'tail: warning: --retry ignored' out || { cat out; fail=1; }
 
@@ -122,18 +122,36 @@ grep -F 'no files remaining' out               || { fail=1; cat out; }
 [ $rc = 1 ]                                    || { fail=1; cat out; }
 rm -fd missing out                             || framework_failure_
 
+# === Test:
+# Ensure that --follow=descriptor (without --retry) does *not* try
+# to open a file after an initial fail, even when there are other
+# tailable files.  This was an issue in <= 8.25.
+touch existing || framework_failure_
+tail $mode $fastpoll --follow=descriptor missing existing >out 2>&1 & pid=$!
+retry_delay_ wait4lines_ .1 6 2  || { cat out; fail=1; }
+[ "$(countlines_)" = 2 ]         || { fail=1; cat out; }
+grep -F 'cannot open' out        || { fail=1; cat out; }
+echo "Y" > missing               || framework_failure_
+echo "X" > existing              || framework_failure_
+retry_delay_ wait4lines_ .1 6 3  || { cat out; fail=1; }
+[ "$(countlines_)" = 3 ]         || { fail=1; cat out; }
+grep '^X$' out                   || { fail=1; cat out; }
+grep '^Y$' out                   && { fail=1; cat out; }
+cleanup_
+rm -f missing out existing       || framework_failure_
+
 # === Test:
 # Ensure that --follow=descriptor (without --retry) does *not wait* for the
 # file to appear.  Expect 2 lines in the output file ("cannot open" +
 # "no files remaining") and exit status 1.
-tail $mode --follow=descriptor missing >out 2>&1 && fail=1
+returns_ 1 tail $mode --follow=descriptor missing >out 2>&1 || fail=1
 [ "$(countlines_)" = 2 ]         || { fail=1; cat out; }
 grep -F 'cannot open' out        || { fail=1; cat out; }
 grep -F 'no files remaining' out || { fail=1; cat out; }
 
 # === Test:
 # Likewise for --follow=name (without --retry).
-tail $mode --follow=name missing >out 2>&1 && fail=1
+returns_ 1 tail $mode --follow=name missing >out 2>&1 || fail=1
 [ "$(countlines_)" = 2 ]         || { fail=1; cat out; }
 grep -F 'cannot open' out        || { fail=1; cat out; }
 grep -F 'no files remaining' out || { fail=1; cat out; }