[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] have tail always detect broken pipes
From: |
Pádraig Brady |
Subject: |
Re: [RFC] have tail always detect broken pipes |
Date: |
Thu, 8 Jun 2017 22:46:41 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 |
On 07/06/17 01:00, Pádraig Brady wrote:
> The following will hang indefinitely, due to no further data
> being written through the pipe, and thus no SIGPIPE generated:
>
> $ tail -f /etc/hosts | sleep 1
>
> A more practical use case might be:
>
> tail -f file.log | grep -q trigger &&
> process_immediately
>
> Another case where one might notice this is that sometimes
> (depending on how slow the reader is) the following will hang,
> and you may not notice the issue until data arrives
>
> tail -f file.log | grep_typo filter
>
> Below is a quick hack to support this,
> and tail now terminates promptly for the above cases.
>
> The implementation is a proof on concept done in a few minutes
> (and may change from poll() to select() if possible).
> A disadvantage is the extra syscalls to do the polling.
> Actually I may be able to combine the existing select()
> with this new poll(), and thus wait for changes in the
> output as well as the inotify descriptor.
>
> cheers,
> Pádraig.
>
>
> diff --git a/src/tail.c b/src/tail.c
> +/* If the output has gone away, then terminate
> + as we would if we had written to this output. */
> +static void
> +check_output (void)
> +{
> + struct pollfd pfd = {.fd = STDOUT_FILENO, .events = POLLERR};
> + if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
> + raise (SIGPIPE);
> +}
> +
The attached changes from using poll() to using select(),
which was already used in tail(1), and avoids the repeated
poll() calls in the normal case.
cheers,
Pádraig
tail-pipe.diff
Description: Text Data