From 763b803a1c49290cffba8e0e97e0fb6e1ee14b0e Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Tue, 20 Apr 2021 13:41:44 +0100 Subject: [PATCH] network: Split FD select code to platform-specific C files Roll out two do_select() functions, one for Windows and one for UNIX, to make the code simpler. Signed-off-by: Paul Cercueil --- network-unix.c | 22 +++++++++++++++++++++ network-windows.c | 38 ++++++++++++++++++++++++++++++++++++ network.c | 49 ++--------------------------------------------- network.h | 1 + 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/network-unix.c b/network-unix.c index 594ffc877..6aa017b6e 100644 --- a/network-unix.c +++ b/network-unix.c @@ -201,3 +201,25 @@ int set_socket_timeout(int fd, unsigned int timeout) else return 0; } + +int do_select(int fd, unsigned int timeout) +{ + struct pollfd pfd; + int ret; + + pfd.fd = fd; + pfd.events = POLLOUT | POLLERR; + pfd.revents = 0; + + do { + ret = poll(&pfd, 1, timeout); + } while (ret == -1 && errno == EINTR); + + if (ret < 0) + return -errno; + + if (ret == 0) + return -ETIMEDOUT; + + return 0; +} diff --git a/network-windows.c b/network-windows.c index 24c61311b..a0a1a1afe 100644 --- a/network-windows.c +++ b/network-windows.c @@ -129,3 +129,41 @@ int set_socket_timeout(int fd, unsigned int timeout) else return 0; } + +int do_select(int fd, unsigned int timeout) +{ + struct timeval tv; + struct timeval *ptv; + fd_set set; + int ret; + +#ifdef _MSC_BUILD + /* + * This is so stupid, but studio emits a signed/unsigned mismatch + * on their own FD_ZERO macro, so turn the warning off/on + */ +#pragma warning(disable : 4389) +#endif + FD_ZERO(&set); + FD_SET(fd, &set); +#ifdef _MSC_BUILD +#pragma warning(default: 4389) +#endif + + if (timeout != 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + ptv = &tv; + } else { + ptv = NULL; + } + + ret = select(fd + 1, NULL, &set, &set, ptv); + if (ret < 0) + return -WSAGetLastError(); + + if (ret == 0) + return -WSAETIMEDOUT; + + return 0; +} diff --git a/network.c b/network.c index bc1fd2200..409a5a483 100644 --- a/network.c +++ b/network.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -48,9 +47,6 @@ #ifdef _WIN32 #define close(s) closesocket(s) -#define NETWORK_ERR_TIMEOUT WSAETIMEDOUT -#else -#define NETWORK_ERR_TIMEOUT ETIMEDOUT #endif #define DEFAULT_TIMEOUT_MS 5000 @@ -179,13 +175,6 @@ static int do_connect(int fd, const struct addrinfo *addrinfo, { int ret, error; socklen_t len; -#ifdef _WIN32 - struct timeval tv; - struct timeval *ptv; - fd_set set; -#else - struct pollfd pfd; -#endif ret = set_blocking_mode(fd, false); if (ret < 0) @@ -198,43 +187,9 @@ static int do_connect(int fd, const struct addrinfo *addrinfo, return ret; } -#ifdef _WIN32 -#ifdef _MSC_BUILD - /* This is so stupid, but studio emits a signed/unsigned mismatch - * on their own FD_ZERO macro, so turn the warning off/on - */ -#pragma warning(disable : 4389) -#endif - FD_ZERO(&set); - FD_SET(fd, &set); -#ifdef _MSC_BUILD -#pragma warning(default: 4389) -#endif - - if (timeout != 0) { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - ptv = &tv; - } else { - ptv = NULL; - } - - ret = select(fd + 1, NULL, &set, &set, ptv); -#else - pfd.fd = fd; - pfd.events = POLLOUT | POLLERR; - pfd.revents = 0; - - do { - ret = poll(&pfd, 1, timeout); - } while (ret == -1 && errno == EINTR); -#endif - + ret = do_select(fd, timeout); if (ret < 0) - return network_get_error(); - - if (ret == 0) - return -NETWORK_ERR_TIMEOUT; + return ret; /* Verify that we don't have an error */ len = sizeof(error); diff --git a/network.h b/network.h index 7670484ba..bc536d39f 100644 --- a/network.h +++ b/network.h @@ -31,6 +31,7 @@ void do_cancel(struct iiod_client_pdata *io_ctx); int wait_cancellable(struct iiod_client_pdata *io_ctx, bool read); int do_create_socket(const struct addrinfo *addrinfo); +int do_select(int fd, unsigned int timeout); int set_blocking_mode(int s, bool blocking); int set_socket_timeout(int fd, unsigned int timeout);