tail: improve --follow=name with single non regular files

* src/tail (tail_forever): Attempt to read() from non blocking
single non regular file, which shouldn't block, but also
read data even when the mtime doesn't change.
* NEWS: Mention the improvement.
* THANKS.in: Thanks for detailed testing.
This commit is contained in:
Pádraig Brady 2023-02-01 20:41:31 +00:00
parent c0c63e9735
commit d195e3863c
3 changed files with 17 additions and 2 deletions

4
NEWS
View File

@ -131,6 +131,10 @@ GNU coreutils NEWS -*- outline -*-
when removing directories. For example EIO will be faithfully
diagnosed, rather than being conflated with ENOTEMPTY.
tail --follow=name now works with single non regular files even
when their modification time doesn't change when new data is available.
Previously tail would not show any new data in this case.
* Noteworthy changes in release 9.1 (2022-04-15) [stable]

View File

@ -230,6 +230,7 @@ Gerald Pfeifer gerald@pfeifer.com
Gerhard Poul gpoul@gnu.org
Germano Leichsenring germano@jedi.cs.kobe-u.ac.jp
Glen Lenker glen.lenker@gmail.com
Glenn Golden gdg@zplane.com
GOTO Masanori gotom@debian.or.jp
Greg Louis glouis@dynamicro.on.ca
Greg McGary gkm@gnu.org

View File

@ -1222,6 +1222,7 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
f[i].blocking = blocking;
}
bool read_unchanged = false;
if (!f[i].blocking)
{
if (fstat (fd, &stats) != 0)
@ -1244,9 +1245,14 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
recheck (&f[i], f[i].blocking);
f[i].n_unchanged_stats = 0;
}
continue;
if (fd != f[i].fd || S_ISREG (stats.st_mode) || 1 < n_files)
continue;
else
read_unchanged = true;
}
assert (fd == f[i].fd);
/* This file has changed. Print out what we can, and
then keep looping. */
@ -1254,7 +1260,8 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
f[i].mode = stats.st_mode;
/* reset counter */
f[i].n_unchanged_stats = 0;
if (! read_unchanged)
f[i].n_unchanged_stats = 0;
/* XXX: This is only a heuristic, as the file may have also
been truncated and written to if st_size >= size
@ -1289,6 +1296,9 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
bytes_read = dump_remainder (false, name, fd, bytes_to_read);
if (read_unchanged && bytes_read)
f[i].n_unchanged_stats = 0;
any_input |= (bytes_read != 0);
f[i].size += bytes_read;
}