1
0
mirror of https://git.savannah.gnu.org/git/coreutils.git synced 2026-10-24 02:08:57 +03:00

tail: without inotify, ensure prompt output

This was seen with a NetBSD failure in the pipe-f2.sh test
due to it clearing the EOF indication on a fifo, and thus
blocking in the subsequent read.  That was discussed at:
https://lists.gnu.org/r/coreutils/2026-04/msg00129.html
https://bugs.gnu.org/81923
Note the NetBSD issue may be addressed in NetBSD 12 as
discussed in the bug above.

This is more defensive/consistent in the case
where a subsequent read on a file blocks.
We might be operating on non fifos after all.

* src/tail.c (tail_forever): Flush output before we might block.
* tests/tail/pipe-f2.sh: Test non inotify path on all platforms.
* NEWS: Mention the improvement.
This commit is contained in:
Pádraig Brady
2026-09-24 19:33:23 +01:00
parent a5052b771f
commit 49efaeaaab
3 changed files with 20 additions and 9 deletions

4
NEWS
View File

@@ -17,6 +17,10 @@ GNU coreutils NEWS -*- outline -*-
'od' allocates half the memory when -v,--output-duplicates is specified.
'tail' ensures prompt output when inotify is not being used, and when
initial reads finish, but subsequent reads might block, which was seen
e.g. with fifos on NetBSD 10.
** Build-related
gzip-compressed tarballs are no longer distributed,

View File

@@ -1177,6 +1177,10 @@ tail_forever (struct File_spec *f, int n_files, double sleep_interval)
static bool debugged;
/* Flush initial output, in case reading blocks below. */
if (fflush (stdout) < 0)
write_error ();
while (true)
{
/* Use blocking I/O as an optimization, when it's easy. */

View File

@@ -21,7 +21,6 @@ print_ver_ tail
mkfifo_or_skip_ fifo
echo 1 > fifo &
echo 1 > exp || framework_failure_
# Terminate any background tail process
@@ -30,18 +29,22 @@ cleanup_() { kill $pid 2>/dev/null && wait $pid; }
# Speedup the non inotify case
fastpoll='-s.1 --max-unchanged-stats=1'
timeout 10 tail $fastpoll -f fifo > out & pid=$!
check_tail_output() { sleep $1; test -s out; }
# Wait 12.7s for tail to write something.
retry_delay_ check_tail_output .1 7 || fail=1
for mode in '' '---disable-inotify'; do
rm -f out || framework_failure_
echo 1 > fifo &
timeout 10 tail $fastpoll -f $mode fifo > out & pid=$!
compare exp out || fail=1
# Wait 12.7s for tail to write something.
retry_delay_ check_tail_output .1 7 || fail=1
# Ensure tail is still running
kill -0 $pid || fail=1
compare exp out || fail=1
cleanup_
# Ensure tail is still running
kill -0 $pid || fail=1
cleanup_
done
Exit $fail