Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 09 Oct 2015 18:35:33 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 203662] tail -F <file> misbehaves with stdin closed
Message-ID:  <bug-203662-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203662

            Bug ID: 203662
           Summary: tail -F <file> misbehaves with stdin closed
           Product: Base System
           Version: 10.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: fstd.lkml@gmail.com

Created attachment 161859
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=161859&action=edit
tail: Don't assume fd 0 is standard input, because it might not be. Use the
`stdin`FILE pointer instead.

I have fixed a bug in NetBSD's tail(1), it turns out FreeBSD also has it.
Below is the original Problem Report incl. steps to reproduce; attached is a
patch adapted to FreeBSD's tail.


[Quoting from http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50322]

>Description:
The point of tail -F /some/file is to follow the contents in /some/file, even
if /some/file is occasionally replaced with a different file, e.g. due to
newsyslog(8) running.  In this mode of operation, standard input is ignored, as
it should be.

Now, if standard input happens to be closed, for example by running
tail -F /some/file <&-
or by it being used inside a script that has its standard input closed
(possibly as a result of daemonizing the script), tail's attempt to fopen(3)
/some/file will open the file at fd 0 - the typical fd for stdin.

However, later on, tail effectively uses fd == 0 to determine whether it is
reading from stdin or not.  If /some/file was opened at fd 0, tail will hence
consider itself to be reading from stdin and omit adding the vnode filters to
kqueue/kevent.

The result is that it will not follow the file after newsyslog(8) rotated the
file away; it will instead forever be stuck in kevent(2).

I've been hit by this for a long time, only yesterday managed to finally find
this (Heisen)bug.

The root cause of the problem is that tail assumes fd 0 is standard input.  It
does this in two places by comparing `fileno(fp)` to `STDIN_FILENO`.  (`fp`
being a FILE * as returned by fopen(3) or freopen(3)).
It should instead compare `fp` to `stdin`.

>How-To-Repeat:
Terminal 1:
$ touch /tmp/foo
$ tail -F /tmp/foo <&-

Terminal 2:
$ echo foo >>/tmp/foo  # Outputs 'foo' on Terminal 1
$ rm /tmp/foo
$ echo bar >>/tmp/foo  # SHOULD output 'bar' on Terminal 1, but does not.


Cheers,
Timo Buhrmester

-- 
You are receiving this mail because:
You are the assignee for the bug.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-203662-8>