From: Pádraig Brady Date: Wed, 1 Feb 2023 20:41:31 +0000 (+0000) Subject: tail: improve --follow=name with single non regular files X-Git-Tag: v9.2~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d195e3863cdba55bd851dac44dbf4f0bcb89a4fe;p=thirdparty%2Fcoreutils.git 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. --- diff --git a/NEWS b/NEWS index eb8380e117..04088af709 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 a3d179a557..8d903268e0 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 03061e8bf7..e2e7f46909 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; }