1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-02-18 21:32:12 +02:00

tail: ensure -f --retry 'missing' handles truncation

* src/tail.c (tail_forever): The BLOCKING optimization is only
enabled for non regular files (which can't be truncated), so ensure
we don't enable that unless we've a valid file descriptor.
* tests/tail-2/retry.sh: Add a test case.
* NEWS: Mention the bug fix.
This commit is contained in:
Pádraig Brady
2016-11-09 17:51:13 +00:00
parent 7fc7206b03
commit 659060233f
3 changed files with 14 additions and 5 deletions

4
NEWS
View File

@@ -59,6 +59,10 @@ GNU coreutils NEWS -*- outline -*-
file systems that misreport file sizes through stale metadata.
[This bug was present in "the beginning" but exacerbated in coreutils-8.24]
tail -f --retry 'missing file' will now process truncations of that file.
Previously truncation was ignored thus not outputting new data in the file.
[bug introduced in coreutils-5.3.0]
yes now handles short writes, rather than assuming all writes complete.
[bug introduced in coreutils-8.24]

View File

@@ -1111,7 +1111,7 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
{
/* Use blocking I/O as an optimization, when it's easy. */
bool blocking = (pid == 0 && follow_mode == Follow_descriptor
&& n_files == 1 && ! S_ISREG (f[0].mode));
&& n_files == 1 && f[0].fd != -1 && ! S_ISREG (f[0].mode));
size_t last;
bool writer_is_dead = false;

View File

@@ -83,17 +83,22 @@ timeout 10 \
tail $mode $fastpoll --follow=descriptor --retry missing >out 2>&1 & pid=$!
# Wait for "cannot open" error.
retry_delay_ wait4lines_ .1 6 2 || { cat out; fail=1; }
echo "X" > missing || framework_failure_
echo "X1" > missing || framework_failure_
# Wait for the expected output.
retry_delay_ wait4lines_ .1 6 4 || { cat out; fail=1; }
# Ensure truncation is detected
# tail-8.25 failed at this (as assumed non file and went into blocking mode)
echo "X" > missing || framework_failure_
retry_delay_ wait4lines_ .1 6 6 || { cat out; fail=1; }
cleanup_
# Expect 4 lines in the output file.
[ "$(countlines_)" = 4 ] || { fail=1; cat out; }
[ "$(countlines_)" = 6 ] || { 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 'has appeared' out || { fail=1; cat out; }
grep '^X$' out || { fail=1; cat out; }
grep '^X1$' out || { fail=1; cat out; }
grep -F 'file truncated' out || { fail=1; cat out; }
grep '^X$' out || { fail=1; cat out; }
rm -f missing out || framework_failure_
# === Test: