From: Gerhard Sittig Date: Wed, 27 Sep 2023 15:15:02 +0000 (+0200) Subject: tcp: check for poll(2) and select(2), workaround for shutdown(2) API X-Git-Url: http://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=8c542453218985efa9c2904fb1ed6c1ca9b56a6a tcp: check for poll(2) and select(2), workaround for shutdown(2) API The poll(2) API is not universally available. Check for its presence before referencing it. Fallback to select(2) in its absence. Check for the availability of select(2) as well. If neither is available, there is no (portable) way of checking a file descriptor's readability. The SHUT_RDWR identifier is not available in winsock. But a different symbol with identical meaning is available. Use it as a fallback. This amends commit fcab496c12b2 which introduced common TCP support. --- diff --git a/configure.ac b/configure.ac index 8b051b88..85f4b2b4 100644 --- a/configure.ac +++ b/configure.ac @@ -225,6 +225,20 @@ AM_CONDITIONAL([NEED_RPC], [test "x$sr_cv_have_rpc" = xyes]) # Check for compiler support of 128 bit integers AC_CHECK_TYPES([__int128_t, __uint128_t], [], [], []) +AC_CACHE_CHECK([for poll], [sr_cv_have_poll], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[(void) poll(0, 0, -1);]])], + [sr_cv_have_poll=yes], [sr_cv_have_poll=no])]) +AS_IF([test "x$sr_cv_have_poll" = xyes], + [AC_DEFINE([HAVE_POLL], [1], + [Specifies whether we have the poll(2) function.])]) +AC_CACHE_CHECK([for select], [sr_cv_have_select], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[(void) select(0, 0, 0, 0, 0);]])], + [sr_cv_have_select=yes], [sr_cv_have_select=no])]) +AS_IF([test "x$sr_cv_have_select" = xyes], + [AC_DEFINE([HAVE_SELECT], [1], + [Specifies whether we have the select(2) function.])]) ####################### ## miniLZO related ## diff --git a/src/tcp.c b/src/tcp.c index aa6669d9..0870420c 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -#include +#include "config.h" /* TODO * Can we sort these include directives? Or do the platform specific @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -45,9 +44,23 @@ #include #endif +#if HAVE_POLL +#include +#elif HAVE_SELECT +#include +#endif + #include #include "libsigrok-internal.h" +/* + * Workaround because Windows cannot simply use established identifiers. + * https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown + */ +#if !defined SHUT_RDWR && defined SD_BOTH +# define SHUT_RDWR SD_BOTH +#endif + #define LOG_PREFIX "tcp" /** @@ -64,6 +77,7 @@ */ SR_PRIV gboolean sr_fd_is_readable(int fd) { +#if HAVE_POLL struct pollfd fds[1]; int ret; @@ -79,6 +93,26 @@ SR_PRIV gboolean sr_fd_is_readable(int fd) return FALSE; return TRUE; +#elif HAVE_SELECT + fd_set rfds; + struct timeval tv; + int ret; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + memset(&tv, 0, sizeof(tv)); + ret = select(fd + 1, &rfds, NULL, NULL, &tv); + if (ret < 0) + return FALSE; + if (!ret) + return FALSE; + if (!FD_ISSET(fd, rfds)) + return FALSE; + return TRUE; +#else + (void)fd; + return FALSE; +#endif } /**