Commit 0414ea65 authored by Simon McVittie's avatar Simon McVittie

build: Never use poll() on Darwin family (macOS, etc.) or Interix

Doing a runtime check in (AC_RUN_IFELSE) has several

* It doesn't work when cross-compiling. For example, if we build macOS
  binaries on a Linux system, we'd assume that poll() works, but in
  fact it won't.

* It checks the build system capabilities, but that is not necessarily
  appropriate if (for example) a macOS 10.10 user builds binaries that
  could be used by macOS 10.12 or macOS 10.9 users.

* It checks for one specific failure mode, but macOS seems to have a
  history of various implementation issues in poll().

* If we want it to work in CMake, we have to duplicate it in the CMake
  build system.

None of these is a showstopper on its own, but the combination of all
of them makes the current approach to avoiding the broken poll() on
macOS look unreliable. libcurl, a widely-portable library making
extensive use of sockets, specifically doesn't use poll() on Darwin
(macOS, iOS, etc.) or on Interix; let's follow their example here.

See also and
for some relevant history.
Signed-off-by: Simon McVittie's avatarSimon McVittie <>
Resolves: #232
parent 86ae83d4
......@@ -633,34 +633,6 @@ fi
AC_CHECK_FUNCS_ONCE([prctl raise])
#### Check for broken poll; taken from Glib's configure
AC_MSG_CHECKING([for broken poll])
#include <stdlib.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/poll.h>
int main(void) {
struct pollfd fds[1];
int fd;
fd = open("/dev/null", 1);
fds[0].fd = fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
if (poll(fds, 1, 0) < 0 || (fds[0].revents & POLLNVAL) != 0) {
exit(1); /* Does not work for devices -- fail */
AC_DEFINE(BROKEN_POLL,1,[poll doesn't work on devices])],
[broken_poll="no (cross compiling)"])
AC_MSG_CHECKING(for dirfd)
#include <sys/types.h>
......@@ -48,6 +48,32 @@
#include <string.h>
#include <stdarg.h>
#if !defined(BROKEN_POLL) && (defined(__APPLE__) || defined(__INTERIX))
/* Following libcurl's example, we blacklist poll() on Darwin
* (macOS, iOS, etc.) and Interix due to a history of implementation
* issues.
* On unspecified older macOS versions, poll() failed if given a
* device node to poll.
* On macOS < 10.9, poll() with nfds=0 failed instead of waiting for
* the timeout and then succeeding.
* On macOS >= 10.12, poll() with nfds=0 succeeded immediately
* instead of waiting for the timeout, resulting in busy-looping.
* On Interix, poll() apparently only works for files in /proc.
* The "legacy" build flavour in our CI machinery defines BROKEN_POLL
* on whatever platform is in use (normally Linux) to force use of the
* same select()-based poll() emulation that we use for macOS, Interix,
* and any platform that lacks a real poll(), so that we can test it
* more regularly.
# define BROKEN_POLL
/* AIX sys/poll.h does #define events reqevents, and other
* wonderousness, so must include sys/poll before declaring
* DBusPollFD
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment