[Libguestfs] [PATCH nbdkit 7/9] server: Add hand-written replacement for poll for Windows.

Richard W.M. Jones
2020-08-18T10:50:11Z

---
 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      | 106 ++++++++++++++++++++++++++++++++
 6 files changed, 171 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8c0398fe..bd9bd65f 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 5d73ac35..5abb6c2b 100644
--- a/common/replacements/Makefile.am
+++ b/common/replacements/Makefile.am
@@ -46,6 +46,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..c6da5f2a
--- /dev/null
+++ b/common/replacements/poll.c
@@ -0,0 +1,106 @@
+/* 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>
+
+/* Windows doesn't have poll.  It has something called WSAPoll in
+ * Winsock, but even MSFT admit it is broken.  Gnulib contains an
+ * elaborate emulation of poll written by Paolo, 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, nfds = 0, r;
+  fd_set readfds, writefds;
+  struct timeval tv, *tvp;
+
+  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);
+    if (fds[i].fd > nfds)
+      nfds = fds[i].fd;
+    fds[i].revents = 0;
+  }
+  nfds++;
+
+  if (timeout >= 0) {
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = timeout % 1000;
+    tvp = &tv;
+  }
+  else
+    tvp = NULL;
+
+  r = select (nfds, &readfds, &writefds, NULL, tvp);
+  if (r == -1)
+    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