bug-coreutils
[Top][All Lists]
Advanced

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

bug#24903: "tail -f - foo" does not terminate when stdin is closed and f


From: Julian Büning
Subject: bug#24903: "tail -f - foo" does not terminate when stdin is closed and foo is ignored
Date: Tue, 8 Nov 2016 17:39:18 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.0

We observed another behavior possibly related to bug #24495:

$ mkdir foo
$ echo "bar" | tail -f - foo &
[1] 16386
==> standard input <==
bar

==> foo <==
tail: error reading 'foo': Is a directory
tail: foo: cannot follow end of this type of file; giving up on this name
$ jobs
[1]+  Running                 echo "bar" | tail -f - foo &
$ readlink /proc/16386/fd/0
pipe:[162156]
$ lsof | grep 162156
tail      16386          user    0r     FIFO       0,10       0t0
162156 pipe

Only the reading end of the pipe is still open, thus tail should not be
able to read any more bytes from it.


expected behavior:

$ mkdir foo
$ echo "bar" | tail -f - foo &
[1] 16386
==> standard input <==
bar

==> foo <==
tail: error reading 'foo': Is a directory
tail: foo: cannot follow end of this type of file; giving up on this name
tail: no files remaining
[1]+  Done                    echo "bar" | tail -f - foo &

This would match the behavior of tail when called without a directory as
parameter:

$ echo "bar" | tail -f - &
[1] 8411
bar
[1]+  Done                    echo "bar" | tail -f -


We could reproduce this behavior with version 8.25 (package) and
8.25.91-23066 (compiled from source) on Fedora.

We need the directory (or some other untailable file) as second argument to reproduce this behavior as the -f option is ignored for any FIFO or pipe using ignore_fifo_and_pipe(), which prevents tail_forever() from being called in case only FIFOs or pipes are available. The aforementioned function sets .ignore to true for any FIFO or pipe.

In our test case, tail_forever() skips both the directory and stdin as
their .ignore entries are set to true. Before sleeping and starting the
next iteration of the loop (without making any attempt to read from
stdin), any_live_files() is called, which returns true for stdin:
 > if (0 <= f[i].fd)
 >    return true;


This behavior was found using Symbolic Execution techniques developed in
the course of the SYMBIOSYS research project at COMSYS, RWTH Aachen
University.

Regards,
Julian Büning





reply via email to

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