summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2016-09-21 18:42:40 +0100
committerPádraig Brady <P@draigBrady.com>2016-09-28 23:40:47 +0100
commitf04daf570b91286d47a80074cf4a6a63c4309dc0 (patch)
tree946f0975a979c05c523d5f21328116dee506162f /src
parenteb406b2caf4d6307d7f86f38da4d6029a6b83961 (diff)
downloadcoreutils-f04daf570b91286d47a80074cf4a6a63c4309dc0.tar.xz
tail: -F now always processes initially untailable files
which was not the case when inotify was not available. * src/tail.c (any_live_files): Simplify, since the IGNORE flag is now only set when a file should be ignored indefinitely. (recheck): Only output the "giving up on name" message when that's actually the case. Only set the IGNORE flag when ignoring a file indefinitely. (tail_file): Likewise. * tests/tail-2/retry.sh: Add a test case. Also run all existing test cases with and without inotify. NEWS: Mention the fix. THANKS.in: Add the reporter. Fixes http://bugs.gnu.org/24495 which was detected using Symbolic Execution techniques developed in the course of the SYMBIOSYS research project at COMSYS, RWTH Aachen University.
Diffstat (limited to 'src')
-rw-r--r--src/tail.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/tail.c b/src/tail.c
index caa54076a..545da033c 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -956,8 +956,8 @@ recheck (struct File_spec *f, bool blocking)
f->errnum = -1;
f->ignore = true;
- error (0, 0, _("%s has been replaced with a symbolic link. "
- "giving up on this name"), quoteaf (pretty_name (f)));
+ error (0, 0, _("%s has been replaced with an untailable symbolic link"),
+ quoteaf (pretty_name (f)));
}
else if (fd == -1 || fstat (fd, &new_stats) < 0)
{
@@ -986,17 +986,20 @@ recheck (struct File_spec *f, bool blocking)
{
ok = false;
f->errnum = -1;
- error (0, 0, _("%s has been replaced with an untailable file;\
- giving up on this name"),
- quoteaf (pretty_name (f)));
- f->ignore = true;
+ f->tailable = false;
+ if (! (reopen_inaccessible_files && follow_mode == Follow_name))
+ f->ignore = true;
+ if (was_tailable || prev_errnum != f->errnum)
+ error (0, 0, _("%s has been replaced with an untailable file%s"),
+ quoteaf (pretty_name (f)),
+ f->ignore ? _("; giving up on this name") : "");
}
else if (!disable_inotify && fremote (fd, pretty_name (f)))
{
ok = false;
f->errnum = -1;
- error (0, 0, _("%s has been replaced with a remote file. "
- "giving up on this name"), quoteaf (pretty_name (f)));
+ error (0, 0, _("%s has been replaced with an untailable remote file"),
+ quoteaf (pretty_name (f)));
f->ignore = true;
f->remote = true;
}
@@ -1075,20 +1078,20 @@ any_live_files (const struct File_spec *f, size_t n_files)
{
size_t i;
+ /* In inotify mode, ignore may be set for files
+ which may later be replaced with new files.
+ So always consider files live in -F mode. */
if (reopen_inaccessible_files && follow_mode == Follow_name)
- return true; /* continue following for -F option */
+ return true;
for (i = 0; i < n_files; i++)
{
if (0 <= f[i].fd)
- {
- return true;
- }
+ return true;
else
{
- if (reopen_inaccessible_files && follow_mode == Follow_descriptor)
- if (! f[i].ignore)
- return true;
+ if (! f[i].ignore && reopen_inaccessible_files)
+ return true;
}
}
@@ -1930,12 +1933,14 @@ tail_file (struct File_spec *f, uintmax_t n_units)
}
else if (!IS_TAILABLE_FILE_TYPE (stats.st_mode))
{
- error (0, 0, _("%s: cannot follow end of this type of file;\
- giving up on this name"),
- quotef (pretty_name (f)));
ok = false;
f->errnum = -1;
- f->ignore = true;
+ f->tailable = false;
+ f->ignore = ! (reopen_inaccessible_files
+ && follow_mode == Follow_name);
+ error (0, 0, _("%s: cannot follow end of this type of file%s"),
+ quotef (pretty_name (f)),
+ f->ignore ? _("; giving up on this name") : "");
}
if (!ok)