diff options
-rw-r--r-- | src/tail.c | 31 | ||||
-rw-r--r-- | tests/tail-2/retry.sh | 18 |
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. |