summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tail.c31
-rw-r--r--tests/tail-2/retry.sh18
2 files changed, 43 insertions, 6 deletions
diff --git a/src/tail.c b/src/tail.c
index 373575705..6bbc7251f 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -1052,16 +1052,32 @@ recheck (struct File_spec *f, bool blocking)
}
/* Return true if any of the N_FILES files in F are live, i.e., have
- open file descriptors. */
+ open file descriptors, or should be checked again (see --retry).
+ When following descriptors, checking should only continue when any
+ of the files is not yet ignored. */
static bool
any_live_files (const struct File_spec *f, size_t n_files)
{
size_t i;
+ if (reopen_inaccessible_files && follow_mode == Follow_name)
+ return true; /* continue following for -F option */
+
for (i = 0; i < n_files; i++)
- if (0 <= f[i].fd)
- return true;
+ {
+ if (0 <= f[i].fd)
+ {
+ return true;
+ }
+ else
+ {
+ if (reopen_inaccessible_files && follow_mode == Follow_descriptor)
+ if (! f[i].ignore)
+ return true;
+ }
+ }
+
return false;
}
@@ -1189,7 +1205,7 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
f[i].size += bytes_read;
}
- if (! any_live_files (f, n_files) && ! reopen_inaccessible_files)
+ if (! any_live_files (f, n_files))
{
error (0, 0, _("no files remaining"));
break;
@@ -2031,8 +2047,11 @@ parse_options (int argc, char **argv,
if (reopen_inaccessible_files)
{
if (!forever)
- error (0, 0, _("warning: --retry ignored; --retry is useful"
- " only when following"));
+ {
+ reopen_inaccessible_files = false;
+ error (0, 0, _("warning: --retry ignored; --retry is useful"
+ " only when following"));
+ }
else if (follow_mode == Follow_descriptor)
error (0, 0, _("warning: --retry only effective for the initial open"));
}
diff --git a/tests/tail-2/retry.sh b/tests/tail-2/retry.sh
index 71d101556..d56d4c169 100644
--- a/tests/tail-2/retry.sh
+++ b/tests/tail-2/retry.sh
@@ -76,6 +76,24 @@ grep '^X$' out || { fail=1; cat out; }
rm -f missing out || fail=1
# === Test:
+# Ensure that tail --follow=descriptor --retry exits when the file appears
+# untailable. Expect exit status 1.
+timeout 10 tail -s.1 --follow=descriptor --retry missing >out 2>&1 & pid=$!
+retry_delay_ wait4lines_ .1 6 2 || fail=1 # Wait for "cannot open" error.
+mkdir missing || fail=1 # Create untailable 'missing'.
+retry_delay_ wait4lines_ .1 6 4 || fail=1 # Wait for the expected output.
+wait $pid
+rc=$?
+[ $( wc -l < out ) = 4 ] || { fail=1; cat out; }
+grep -F 'retry only effective for the initial open' out \
+ || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'replaced with an untailable file' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+[ $rc = 1 ] || { fail=1; cat out; }
+rm -fd missing out || fail=1
+
+# === 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.