]> sigrok.org Git - libsigrok.git/commitdiff
tcp: check for poll(2) and select(2), workaround for shutdown(2) API
authorGerhard Sittig <redacted>
Wed, 27 Sep 2023 15:15:02 +0000 (17:15 +0200)
committerGerhard Sittig <redacted>
Wed, 27 Sep 2023 16:36:23 +0000 (18:36 +0200)
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.

configure.ac
src/tcp.c

index 8b051b8866b8ebd518566620ec3e88637476cf99..85f4b2b49976b0329fe4b9b3ce4a6a8f66f20851 100644 (file)
@@ -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 <poll.h>]],
+                       [[(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 <sys/select.h>]],
+                       [[(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  ##
index aa6669d9f48cd780aa77be1ea996af89b361eba1..0870420ced51f540d3bb672d6620ce62f65883fe 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -17,7 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <config.h>
+#include "config.h"
 
 /* TODO
  * Can we sort these include directives? Or do the platform specific
@@ -33,7 +33,6 @@
 
 #include <errno.h>
 #include <glib.h>
-#include <poll.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <sys/types.h>
 #endif
 
+#if HAVE_POLL
+#include <poll.h>
+#elif HAVE_SELECT
+#include <sys/select.h>
+#endif
+
 #include <libsigrok/libsigrok.h>
 #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
 }
 
 /**