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; }