From 61a1a6af22e17fc94999a5d1294f27346e6c4668 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 12 Jan 2022 08:57:49 +1100 Subject: [PATCH] OS X poll(2) is broken; use compat replacement Darwin's poll(2) implementation is broken. For character-special devices like /dev/null, it returns POLLNVAL when polled with POLLIN. Apparently this is Apple bug 3710161, which is AFAIK not public, but a websearch will find other OSS projects rediscovering it periodically since it was first identified in 2005 (!!) --- configure.ac | 4 ++++ openbsd-compat/bsd-poll.c | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 1feb73ef9..eb265143b 100644 --- a/configure.ac +++ b/configure.ac @@ -731,6 +731,10 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) # proc_pidinfo()-based closefrom() replacement. AC_CHECK_HEADERS([libproc.h]) AC_CHECK_FUNCS([proc_pidinfo]) + # poll(2) is broken for character-special devices (at least). + # cf. Apple bug 3710161 (not public, but searchable) + AC_DEFINE([BROKEN_POLL], [1], + [System poll(2) implementation is broken]) ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index 2d28eed5b..8084776ce 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c @@ -15,7 +15,7 @@ */ #include "includes.h" -#if !defined(HAVE_PPOLL) || !defined(HAVE_POLL) +#if !defined(HAVE_PPOLL) || !defined(HAVE_POLL) || defined(BROKEN_POLL) #include #include @@ -29,7 +29,7 @@ #include #include "bsd-poll.h" -#ifndef HAVE_PPOLL +#if !defined(HAVE_PPOLL) || defined(BROKEN_POLL) /* * A minimal implementation of ppoll(2), built on top of pselect(2). * @@ -109,9 +109,9 @@ out: errno = saved_errno; return ret; } -#endif /* HAVE_PPOLL */ +#endif /* !HAVE_PPOLL || BROKEN_POLL */ -#ifndef HAVE_POLL +#if !defined(HAVE_POLL) || defined(BROKEN_POLL) int poll(struct pollfd *fds, nfds_t nfds, int timeout) { @@ -126,6 +126,6 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout) return ppoll(fds, nfds, tsp, NULL); } -#endif /* HAVE_POLL */ +#endif /* !HAVE_POLL || BROKEN_POLL */ -#endif /* HAVE_PPOLL || HAVE_POLL */ +#endif /* !HAVE_PPOLL || !HAVE_POLL || BROKEN_POLL */