bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug #15473] tail -f fails on append-only files


From: Jim Meyering
Subject: Re: [bug #15473] tail -f fails on append-only files
Date: Tue, 24 Jan 2006 11:33:44 +0100

dean gaudet <address@hidden> wrote:
> URL: <http://savannah.gnu.org/bugs/?func=detailitem&item_id=15473>
> Details:
>
> tail -f tries to set O_NONBLOCK on all regular files... which doesn't really
> accomplish anything except it results in an EPERM on linux when the file is
> marked append-only... and unfortunately append-only is a really useful
> attribute for a log file (especially a non-root log file since append-only
> can only be changed by root).
>
> this is a regression since 5.2.1...
>
> the patch below ignores EPERM errors for O_NONBLOCK on regular files.

Thanks for tracking it down to the combination of
O_NONBLOCK and the append-only attribute.

I've fixed it a little differently, to ensure that
when there's a blocking-mode mismatch, the code uses
the file's actual mode (not the target mode).

2006-01-23  Jim Meyering  <address@hidden>

        * Version 6.0-cvs.

        * src/tail.c (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.

        FIXME: add a root-only test requiring ext[23] or xfs, and chattr.

Index: src/tail.c
===================================================================
RCS file: /fetish/cu/src/tail.c,v
retrieving revision 1.247
diff -u -p -r1.247 tail.c
--- src/tail.c  5 Jan 2006 10:27:03 -0000       1.247
+++ src/tail.c  23 Jan 2006 20:34:10 -0000
@@ -1015,12 +1015,22 @@ tail_forever (struct File_spec *f, int n
              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 n
                       <= 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 n
            }
 
          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;
        }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]