--- 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