#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
#include "tool_cfgable.h"
#include "tool_cb_rea.h"
#include "memdebug.h" /* keep this as LAST include */
+#ifndef _WIN32
+/* Wait up to a number of milliseconds for socket activity. This function
+ waits on read activity on a file descriptor that is not a socket which
+ makes it not work with select() or poll() on Windows. */
+static bool waitfd(int waitms, int fd)
+{
+#ifdef HAVE_POLL
+ struct pollfd set;
+
+ set.fd = fd;
+ set.events = POLLIN;
+ set.revents = 0;
+ if(poll(&set, 1, (int)waitms))
+ return TRUE; /* timeout */
+ return FALSE;
+#else
+ fd_set bits;
+ struct timeval timeout;
+
+ if(fd >= FD_SETSIZE)
+ /* can't wait! */
+ return FALSE;
+
+ /* wait this long at the most */
+ timeout.tv_sec = waitms / 1000;
+ timeout.tv_usec = (int)((waitms % 1000) * 1000);
+
+ FD_ZERO(&bits);
+#ifdef __DJGPP__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warith-conversion"
+#endif
+ FD_SET(fd, &bits);
+#ifdef __DJGPP__
+#pragma GCC diagnostic pop
+#endif
+ if(!select(fd + 1, &bits, NULL, NULL, &timeout))
+ return TRUE; /* timeout */
+ return FALSE;
+#endif
+}
+#endif
+
/*
** callback for CURLOPT_READFUNCTION
*/
/* timeout */
return 0;
#ifndef _WIN32
- /* this logic waits on read activity on a file descriptor that is not a
- socket which makes it not work with select() on Windows */
else {
- fd_set bits;
- struct timeval timeout;
- long wait = config->timeout_ms - msdelta;
-
- /* wait this long at the most */
- timeout.tv_sec = wait/1000;
- timeout.tv_usec = (int)((wait%1000)*1000);
-
- FD_ZERO(&bits);
-#ifdef __DJGPP__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warith-conversion"
-#endif
- FD_SET(per->infd, &bits);
-#ifdef __DJGPP__
-#pragma GCC diagnostic pop
-#endif
- if(!select(per->infd + 1, &bits, NULL, NULL, &timeout))
- return 0; /* timeout */
+ long w = config->timeout_ms - msdelta;
+ if(w > INT_MAX)
+ w = INT_MAX;
+ waitfd((int)w, per->infd);
}
#endif
}
if(config->readbusy) {
if(ulprev == ulnow) {
#ifndef _WIN32
- fd_set bits;
- struct timeval timeout;
- /* wait this long at the most */
- timeout.tv_sec = 0;
- timeout.tv_usec = 1000;
-
- FD_ZERO(&bits);
-#ifdef __DJGPP__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warith-conversion"
-#endif
- FD_SET(per->infd, &bits);
-#ifdef __DJGPP__
-#pragma GCC diagnostic pop
-#endif
- select(per->infd + 1, &bits, NULL, NULL, &timeout);
+ waitfd(1, per->infd);
#else
/* sleep */
curlx_wait_ms(1);