]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: fix detection of closed stdout on macOS
authorPádraig Brady <P@draigBrady.com>
Tue, 21 Sep 2021 13:01:34 +0000 (14:01 +0100)
committerPádraig Brady <P@draigBrady.com>
Tue, 21 Sep 2021 16:50:54 +0000 (17:50 +0100)
* 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

bootstrap.conf
src/tail.c

index bcfc6f0a0c998cc2471db24651d49ae2f2f912c7..aef9ec7ded827be818e13a897590f1539728ea94 100644 (file)
@@ -194,7 +194,6 @@ gnulib_modules="
   physmem
   pipe-posix
   pipe2
-  poll
   posix-shell
   posixtm
   posixver
@@ -230,6 +229,7 @@ gnulib_modules="
   save-cwd
   savedir
   savewd
+  select
   selinux-at
   setenv
   settime
index d2c898adf7ecba5b5e75574cd03da5aab6a0a5f9..df1b28f07a27e1bedf360d11e836e2ed46858bb6 100644 (file)
@@ -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>
 
 # 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"
@@ -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