From 01e4d2983a0e6a7848caae6a3a86b3a751538d1e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 3 Aug 2025 08:29:52 -0700 Subject: [PATCH] =?utf8?q?tail:=20refactor=20=E2=80=98failable=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/tail.c (recheck, tail_file): Do not mark a file as tailable merely because --retry is not in effect. Simplify internal logic. This should not change behavior; it’s just for clarity and to make the code match the comments better. --- src/tail.c | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/tail.c b/src/tail.c index 6a769181a9..5579b2b711 100644 --- a/src/tail.c +++ b/src/tail.c @@ -966,9 +966,8 @@ static void recheck (struct File_spec *f, bool blocking) { struct stat new_stats; - bool ok = true; + bool ok = false; bool is_stdin = (STREQ (f->name, "-")); - bool was_tailable = f->tailable; int prev_errnum = f->errnum; bool new_file; int fd = (is_stdin @@ -978,17 +977,12 @@ recheck (struct File_spec *f, bool blocking) affirm (valid_file_spec (f)); - /* If the open fails because the file doesn't exist, - then mark the file as not tailable. */ - f->tailable = !(reopen_inaccessible_files && fd < 0); - char linkbuf[1]; if (! disable_inotify && 0 <= readlink (f->name, linkbuf, 1)) { /* Diagnose the edge case where a regular file is changed to a symlink. We avoid inotify with symlinks since it's awkward to match between symlink name and target. */ - ok = false; f->errnum = -1; f->ignore = true; @@ -997,11 +991,10 @@ recheck (struct File_spec *f, bool blocking) } else if (fd < 0 || fstat (fd, &new_stats) < 0) { - ok = false; f->errnum = fd < 0 ? open_errno : errno; - if (!f->tailable) + if (fd < 0) { - if (was_tailable) + if (f->tailable) { /* FIXME-maybe: detect the case in which the file first becomes unreadable (perms), and later becomes readable again and can @@ -1020,18 +1013,15 @@ recheck (struct File_spec *f, bool blocking) } else if (!IS_TAILABLE_FILE_TYPE (new_stats.st_mode)) { - ok = false; f->errnum = -1; - f->tailable = false; f->ignore = ! (reopen_inaccessible_files && follow_mode == Follow_name); - if (was_tailable || prev_errnum != f->errnum) + if (f->tailable || ! (prev_errnum < 0 || prev_errnum == EISDIR)) error (0, 0, _("%s has been replaced with an untailable file%s"), quoteaf (f->prettyname), f->ignore ? _("; giving up on this name") : ""); } else if ((f->remote = fremote (fd, f)) && ! disable_inotify) { - ok = false; f->errnum = -1; error (0, 0, _("%s has been replaced with an untailable remote file"), quoteaf (f->prettyname)); @@ -1039,9 +1029,12 @@ recheck (struct File_spec *f, bool blocking) } else { + ok = true; f->errnum = 0; } + f->tailable = ok; + new_file = false; if (!ok) { @@ -1380,7 +1373,7 @@ any_non_regular_fifo (const struct File_spec *f, int n_files) } /* Return true if any of the N_FILES files in F represents - stdin and is tailable. */ + stdin and is not ignored. */ static bool tailable_stdin (const struct File_spec *f, int n_files) @@ -1986,7 +1979,7 @@ tail_file (struct File_spec *f, count_t n_files, count_t n_units) else fd = open (f->name, O_RDONLY | O_BINARY | (nonblocking ? O_NONBLOCK : 0)); - f->tailable = !(reopen_inaccessible_files && fd < 0); + f->tailable = false; if (fd < 0) { @@ -2009,33 +2002,33 @@ tail_file (struct File_spec *f, count_t n_files, count_t n_units) off_t read_pos; struct stat stats; - bool stat_ok = 0 <= fstat (fd, &stats); - if (!stat_ok) + ok = 0 <= fstat (fd, &stats); + if (!ok) { f->errnum = errno; error (0, f->errnum, _("cannot fstat %s"), quoteaf (f->prettyname)); - ok = false; } else { read_pos = tail (f->prettyname, fd, &stats, n_units); ok = -1 <= read_pos; f->errnum = ok ? 0 : -1 - read_pos; - } - if (forever) - { - if (stat_ok && !IS_TAILABLE_FILE_TYPE (stats.st_mode)) + if (IS_TAILABLE_FILE_TYPE (stats.st_mode)) + f->tailable = true; + else if (forever) { ok = false; f->errnum = -1; - f->tailable = false; - f->ignore = ! reopen_inaccessible_files; error (0, 0, _("%s: cannot follow end of this type of file%s"), quotef (f->prettyname), - f->ignore ? _("; giving up on this name") : ""); + (reopen_inaccessible_files ? "" + : _("; giving up on this name"))); } + } + if (forever) + { if (!ok) { f->ignore = ! reopen_inaccessible_files; -- 2.47.2