summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2023-02-01 20:41:31 +0000
committerPádraig Brady <P@draigBrady.com>2023-02-06 16:28:53 +0000
commitd195e3863cdba55bd851dac44dbf4f0bcb89a4fe (patch)
treeb741556028702428f57549a2c68235cd2310d83c
parentc0c63e9735908a9579f8735001957db6bd81afc3 (diff)
downloadcoreutils-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--NEWS4
-rw-r--r--THANKS.in1
-rw-r--r--src/tail.c14
3 files changed, 17 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index eb8380e11..04088af70 100644
--- a/NEWS
+++ b/NEWS
@@ -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]
diff --git a/THANKS.in b/THANKS.in
index a3d179a55..8d903268e 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -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;
}