[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