diff options
author | Pádraig Brady <P@draigBrady.com> | 2023-02-01 20:41:31 +0000 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2023-02-06 16:28:53 +0000 |
commit | d195e3863cdba55bd851dac44dbf4f0bcb89a4fe (patch) | |
tree | b741556028702428f57549a2c68235cd2310d83c | |
parent | c0c63e9735908a9579f8735001957db6bd81afc3 (diff) | |
download | coreutils-d195e3863cdba55bd851dac44dbf4f0bcb89a4fe.tar.gz |
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.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | THANKS.in | 1 | ||||
-rw-r--r-- | src/tail.c | 14 |
3 files changed, 17 insertions, 2 deletions
@@ -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] @@ -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 diff --git a/src/tail.c b/src/tail.c index 03061e8bf..e2e7f4690 100644 --- a/src/tail.c +++ b/src/tail.c @@ -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; } |