diff options
author | Jim Meyering <jim@meyering.net> | 2006-01-24 10:32:32 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-01-24 10:32:32 +0000 |
commit | 0cc660d1fee40a665fec5979a3ece3766629b2e1 (patch) | |
tree | 7311c2380b5766b05d0ff6668bae6318c1090eec | |
parent | a30a9a3ec41f93213f6813a50f664fcf79a14452 (diff) | |
download | coreutils-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.
-rw-r--r-- | src/tail.c | 23 |
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; } |