]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: improve --follow=name with single non regular files
authorPádraig Brady <P@draigBrady.com>
Wed, 1 Feb 2023 20:41:31 +0000 (20:41 +0000)
committerPádraig Brady <P@draigBrady.com>
Mon, 6 Feb 2023 16:28:53 +0000 (16:28 +0000)
* 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.

NEWS
THANKS.in
src/tail.c

diff --git a/NEWS b/NEWS
index eb8380e117666ad08048133a24622db893a22fd5..04088af70972f0422fe9d1901182545d7844e72c 100644 (file)
--- 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]
 
index a3d179a5572afe4c9b654e64eb753cc972f816de..8d903268e0a7b31c66b541e4adf3883649ea3b18 100644 (file)
--- 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
index 03061e8bf7a3bc597826959e942d9bf12bcc8ece..e2e7f46909c72d14a93eeb108a643db9af85ce60 100644 (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;
         }