---
configure.ac | 1 +
common/replacements/Makefile.am | 2 +
common/replacements/poll.h | 60 ++++++++++++++++
server/public.c | 2 +-
server/sockets.c | 2 +-
common/replacements/poll.c | 120 ++++++++++++++++++++++++++++++++
6 files changed, 185 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0066fc45..190d35d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -343,6 +343,7 @@ AC_REPLACE_FUNCS([\
getdelim \
getline \
openlog \
+ poll \
realpath \
strndup \
syslog \
diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am
index 9494189b..9d1d34fa 100644
--- a/common/replacements/Makefile.am
+++ b/common/replacements/Makefile.am
@@ -45,6 +45,8 @@ EXTRA_DIST = \
getline.c \
getline.h \
openlog.c \
+ poll.c \
+ poll.h \
realpath.c \
realpath.h \
strndup.c \
diff --git a/common/replacements/poll.h b/common/replacements/poll.h
new file mode 100644
index 00000000..63f20861
--- /dev/null
+++ b/common/replacements/poll.h
@@ -0,0 +1,60 @@
+/* nbdkit
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NBDKIT_POLL_H
+#define NBDKIT_POLL_H
+
+#include <config.h>
+
+#ifdef HAVE_POLL
+
+#include_next <poll.h>
+
+#else
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#define POLLIN 0x0001
+#define POLLOUT 0x0002
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLRDHUP 0x2000
+
+extern int poll (struct pollfd *fds, int n, int timeout);
+
+#endif
+
+#endif /* NBDKIT_POLL_H */
diff --git a/server/public.c b/server/public.c
index fce16989..b25842f9 100644
--- a/server/public.c
+++ b/server/public.c
@@ -47,7 +47,6 @@
#include <limits.h>
#include <termios.h>
#include <errno.h>
-#include <poll.h>
#include <signal.h>
#include <sys/socket.h>
@@ -55,6 +54,7 @@
#include "ascii-string.h"
#include "get_current_dir_name.h"
#include "getline.h"
+#include "poll.h"
#include "realpath.h"
#include "internal.h"
diff --git a/server/sockets.c b/server/sockets.c
index f6c9643a..8da331da 100644
--- a/server/sockets.c
+++ b/server/sockets.c
@@ -38,7 +38,6 @@
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
-#include <poll.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
@@ -59,6 +58,7 @@
#include <pthread.h>
#include "internal.h"
+#include "poll.h"
#include "utils.h"
#include "vector.h"
diff --git a/common/replacements/poll.c b/common/replacements/poll.c
new file mode 100644
index 00000000..51531880
--- /dev/null
+++ b/common/replacements/poll.c
@@ -0,0 +1,120 @@
+/* nbdkit
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Replacement for poll for platforms which lack this function. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HAVE_POLL
+
+#include "poll.h"
+
+#ifdef WIN32
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <errno.h>
+
+/* This is provided by common/utils which hasn't been compiled yet.
+ * Programs using the poll replacement will need to link to
+ * libutils.la. XXX
+ */
+extern int translate_winsock_error (const char *fn, int err);
+
+/* Windows doesn't have poll. It has something called WSAPoll in
+ * Winsock, but even Microsoft admit it is broken. Gnulib contains an
+ * elaborate emulation of poll written by Paolo Bonzini, but it's
+ * distributed under an incompatible license. However Winsock has
+ * select so we can write a simple (but slow) emulation of poll using
+ * select.
+ */
+int
+poll (struct pollfd *fds, int n, int timeout)
+{
+ int i, r;
+ fd_set readfds, writefds;
+ struct timeval tv, *tvp;
+
+ /*
https://docs.microsoft.com/en-us/windows/win32/winsock/maximum-number-of-...
*/
+ if (n >= 64) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ FD_ZERO (&readfds);
+ FD_ZERO (&writefds);
+
+ for (i = 0; i < n; ++i) {
+ if (fds[i].events & POLLIN)
+ FD_SET (fds[i].fd, &readfds);
+ if (fds[i].events & POLLOUT)
+ FD_SET (fds[i].fd, &writefds);
+ fds[i].revents = 0;
+ }
+
+ if (timeout >= 0) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = timeout % 1000;
+ tvp = &tv;
+ }
+ else
+ tvp = NULL;
+
+ /* Windows ignores the nfds parameter of select. */
+ r = select (0, &readfds, &writefds, NULL, tvp);
+ if (r == -1) {
+ errno = translate_winsock_error ("select", WSAGetLastError ());
+ return -1;
+ }
+
+ r = 0;
+ for (i = 0; i < n; ++i) {
+ if (FD_ISSET (fds[i].fd, &readfds))
+ fds[i].revents |= POLLIN;
+ if (FD_ISSET (fds[i].fd, &writefds))
+ fds[i].revents |= POLLOUT;
+ if (fds[i].revents != 0)
+ r++;
+ }
+
+ return r;
+}
+
+#else /* !WIN32 */
+#error "no replacement poll is available on this platform"
+#endif
+
+#endif /* !HAVE_POLL */
--
2.27.0