Skip to content

Commit

Permalink
tail: fix detection of closed stdout on macOS
Browse files Browse the repository at this point in the history
* bootstrap.conf: We only need poll on Linux and AIX
where poll is not replaced.  Also resinstate dependence
on select so we can use it unconditionally.
* src/tail.c (check_output_alive): Reinstate use of select()
by default as poll was seen to be ineffective for this
application on macOS.
Fixes https://bugs.gnu.org/50714
  • Loading branch information
pixelb committed Sep 21, 2021
1 parent f8819b6 commit a656db6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bootstrap.conf
Expand Up @@ -194,7 +194,6 @@ gnulib_modules="
physmem
pipe-posix
pipe2
poll
posix-shell
posixtm
posixver
Expand Down Expand Up @@ -230,6 +229,7 @@ gnulib_modules="
save-cwd
savedir
savewd
select
selinux-at
setenv
settime
Expand Down
25 changes: 24 additions & 1 deletion src/tail.c
Expand Up @@ -28,7 +28,7 @@
#include <stdio.h>
#include <assert.h>
#include <getopt.h>
#include <poll.h>
#include <sys/select.h>
#include <sys/types.h>
#include <signal.h>

Expand All @@ -55,6 +55,10 @@
# include <sys/inotify.h>
#endif

#if defined _AIX || HAVE_INOTIFY
# include <poll.h>
#endif

/* Linux can optimize the handling of local files. */
#if defined __linux__ || defined __ANDROID__
# include "fs.h"
Expand Down Expand Up @@ -348,12 +352,31 @@ check_output_alive (void)
if (! monitor_output)
return;

/* Use 'poll' on AIX (where 'select' was seen to give a readable
event immediately) or if using inotify (which relies on 'poll'
anyway). Otherwise, use 'select' as it's more portable;
'poll' doesn't work for this application on macOS. */
#if defined _AIX || HAVE_INOTIFY
struct pollfd pfd;
pfd.fd = STDOUT_FILENO;
pfd.events = POLLERR;

if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
die_pipe ();
#else
struct timeval delay;
delay.tv_sec = delay.tv_usec = 0;

fd_set rfd;
FD_ZERO (&rfd);
FD_SET (STDOUT_FILENO, &rfd);

/* readable event on STDOUT is equivalent to POLLERR,
and implies an error condition on output like broken pipe. */
if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
die_pipe ();
#endif

}

static bool
Expand Down

0 comments on commit a656db6

Please sign in to comment.