summaryrefslogtreecommitdiff
path: root/src/tail.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-01-24 10:32:32 +0000
committerJim Meyering <jim@meyering.net>2006-01-24 10:32:32 +0000
commit0cc660d1fee40a665fec5979a3ece3766629b2e1 (patch)
tree7311c2380b5766b05d0ff6668bae6318c1090eec /src/tail.c
parenta30a9a3ec41f93213f6813a50f664fcf79a14452 (diff)
downloadcoreutils-0cc660d1fee40a665fec5979a3ece3766629b2e1.tar.xz
(tail_forever): Don't exit-nonzero when an attempt
to put a regular file in O_NONBLOCK mode fails with EPERM. That happens on Linux when using tail -f on a file with the append-only attribute. Reported by Dean Gaudet. For details, see http://savannah.gnu.org/bugs/?func=detailitem&item_id=15473.
Diffstat (limited to 'src/tail.c')
-rw-r--r--src/tail.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/tail.c b/src/tail.c
index ee18f31de..1bfe4bb30 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -1015,12 +1015,22 @@ tail_forever (struct File_spec *f, int nfiles, double sleep_interval)
if (old_flags < 0
|| (new_flags != old_flags
&& fcntl (fd, F_SETFL, new_flags) == -1))
- error (EXIT_FAILURE, errno,
- _("%s: cannot change nonblocking mode"), name);
- f[i].blocking = blocking;
+ {
+ /* Don't update f[i].blocking if fcntl fails. */
+ if (S_ISREG (f[i].mode) && errno == EPERM)
+ {
+ /* This happens when using tail -f on a file with
+ the append-only attribute. */
+ }
+ else
+ error (EXIT_FAILURE, errno,
+ _("%s: cannot change nonblocking mode"), name);
+ }
+ else
+ f[i].blocking = blocking;
}
- if (!blocking)
+ if (!f[i].blocking)
{
if (fstat (fd, &stats) != 0)
{
@@ -1038,7 +1048,7 @@ tail_forever (struct File_spec *f, int nfiles, double sleep_interval)
<= f[i].n_unchanged_stats++)
&& follow_mode == Follow_name)
{
- recheck (&f[i], blocking);
+ recheck (&f[i], f[i].blocking);
f[i].n_unchanged_stats = 0;
}
continue;
@@ -1071,7 +1081,8 @@ tail_forever (struct File_spec *f, int nfiles, double sleep_interval)
}
bytes_read = dump_remainder (name, fd,
- blocking ? COPY_A_BUFFER : COPY_TO_EOF);
+ (f[i].blocking
+ ? COPY_A_BUFFER : COPY_TO_EOF));
any_input |= (bytes_read != 0);
f[i].size += bytes_read;
}