summaryrefslogtreecommitdiff
path: root/lib/select.c
diff options
context:
space:
mode:
authornikita <nikita@NetBSD.org>2021-01-13 00:53:52 +0100
committernikita <nikita@NetBSD.org>2021-01-13 00:53:52 +0100
commit5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb (patch)
treed69e840805484efba1885154b855bf93409248cb /lib/select.c
parent7bd28f37397837d72302550e43d95060413e9eb8 (diff)
parente052859759b34d0e05ce0f17244873e5cd7b457b (diff)
downloadgnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.tar.gz
gnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.tar.bz2
gnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.zip
Merge tag 'curl-7_74_0'
7.74.0
Diffstat (limited to 'lib/select.c')
-rw-r--r--lib/select.c177
1 files changed, 52 insertions, 125 deletions
diff --git a/lib/select.c b/lib/select.c
index e2c97efe6..f38f3179a 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -149,15 +149,14 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */
{
struct timeval pending_tv;
struct timeval *ptimeout;
- int r;
#ifdef USE_WINSOCK
/* WinSock select() can't handle zero events. See the comment below. */
if((!fds_read || fds_read->fd_count == 0) &&
(!fds_write || fds_write->fd_count == 0) &&
(!fds_err || fds_err->fd_count == 0)) {
- r = Curl_wait_ms(timeout_ms);
- return r;
+ /* no sockets, just wait */
+ return Curl_wait_ms(timeout_ms);
}
#endif
@@ -209,17 +208,16 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */
descriptor set must contain at least one handle to a socket.
It is unclear why WinSock doesn't just handle this for us instead of
- calling this an error.
+ calling this an error. Luckily, with WinSock, we can _also_ ask how
+ many bits are set on an fd_set. So, let's just check it beforehand.
*/
- r = select((int)maxfd + 1,
- fds_read && fds_read->fd_count ? fds_read : NULL,
- fds_write && fds_write->fd_count ? fds_write : NULL,
- fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+ return select((int)maxfd + 1,
+ fds_read && fds_read->fd_count ? fds_read : NULL,
+ fds_write && fds_write->fd_count ? fds_write : NULL,
+ fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
#else
- r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+ return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
#endif
-
- return r;
}
/*
@@ -247,23 +245,14 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
curl_socket_t writefd, /* socket to write to */
timediff_t timeout_ms) /* milliseconds to wait */
{
-#ifdef HAVE_POLL_FINE
struct pollfd pfd[3];
int num;
-#else
- fd_set fds_read;
- fd_set fds_write;
- fd_set fds_err;
- curl_socket_t maxfd;
-#endif
int r;
- int ret;
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
(writefd == CURL_SOCKET_BAD)) {
/* no sockets, just wait */
- r = Curl_wait_ms(timeout_ms);
- return r;
+ return Curl_wait_ms(timeout_ms);
}
/* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -271,8 +260,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
-#ifdef HAVE_POLL_FINE
-
num = 0;
if(readfd0 != CURL_SOCKET_BAD) {
pfd[num].fd = readfd0;
@@ -288,7 +275,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
}
if(writefd != CURL_SOCKET_BAD) {
pfd[num].fd = writefd;
- pfd[num].events = POLLWRNORM|POLLOUT;
+ pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI;
pfd[num].revents = 0;
num++;
}
@@ -297,101 +284,30 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
if(r <= 0)
return r;
- ret = 0;
+ r = 0;
num = 0;
if(readfd0 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
- ret |= CURL_CSELECT_IN;
+ r |= CURL_CSELECT_IN;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_ERR;
num++;
}
if(readfd1 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
- ret |= CURL_CSELECT_IN2;
+ r |= CURL_CSELECT_IN2;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_ERR;
num++;
}
if(writefd != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLWRNORM|POLLOUT))
- ret |= CURL_CSELECT_OUT;
- if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
- }
-
- return ret;
-
-#else /* HAVE_POLL_FINE */
-
- FD_ZERO(&fds_err);
- maxfd = (curl_socket_t)-1;
-
- FD_ZERO(&fds_read);
- if(readfd0 != CURL_SOCKET_BAD) {
- VERIFY_SOCK(readfd0);
- FD_SET(readfd0, &fds_read);
- FD_SET(readfd0, &fds_err);
- maxfd = readfd0;
- }
- if(readfd1 != CURL_SOCKET_BAD) {
- VERIFY_SOCK(readfd1);
- FD_SET(readfd1, &fds_read);
- FD_SET(readfd1, &fds_err);
- if(readfd1 > maxfd)
- maxfd = readfd1;
- }
-
- FD_ZERO(&fds_write);
- if(writefd != CURL_SOCKET_BAD) {
- VERIFY_SOCK(writefd);
- FD_SET(writefd, &fds_write);
- FD_SET(writefd, &fds_err);
- if(writefd > maxfd)
- maxfd = writefd;
- }
-
- /* We know that we have at least one bit set in at least two fd_sets in
- this case, but we may have no bits set in either fds_read or fd_write,
- so check for that and handle it. Luckily, with WinSock, we can _also_
- ask how many bits are set on an fd_set.
-
- Note also that WinSock ignores the first argument, so we don't worry
- about the fact that maxfd is computed incorrectly with WinSock (since
- curl_socket_t is unsigned in such cases and thus -1 is the largest
- value).
- */
- r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
-
- ret = 0;
- if(readfd0 != CURL_SOCKET_BAD) {
- if(FD_ISSET(readfd0, &fds_read))
- ret |= CURL_CSELECT_IN;
- if(FD_ISSET(readfd0, &fds_err))
- ret |= CURL_CSELECT_ERR;
- }
- if(readfd1 != CURL_SOCKET_BAD) {
- if(FD_ISSET(readfd1, &fds_read))
- ret |= CURL_CSELECT_IN2;
- if(FD_ISSET(readfd1, &fds_err))
- ret |= CURL_CSELECT_ERR;
- }
- if(writefd != CURL_SOCKET_BAD) {
- if(FD_ISSET(writefd, &fds_write))
- ret |= CURL_CSELECT_OUT;
- if(FD_ISSET(writefd, &fds_err))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_OUT;
+ if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL))
+ r |= CURL_CSELECT_ERR;
}
- return ret;
-
-#endif /* HAVE_POLL_FINE */
-
+ return r;
}
/*
@@ -431,8 +347,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
}
if(fds_none) {
/* no sockets, just wait */
- r = Curl_wait_ms(timeout_ms);
- return r;
+ return Curl_wait_ms(timeout_ms);
}
/* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -454,11 +369,8 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
else
pending_ms = 0;
r = poll(ufds, nfds, pending_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
+ if(r <= 0)
+ return r;
for(i = 0; i < nfds; i++) {
if(ufds[i].fd == CURL_SOCKET_BAD)
@@ -466,7 +378,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
if(ufds[i].revents & POLLHUP)
ufds[i].revents |= POLLIN;
if(ufds[i].revents & POLLERR)
- ufds[i].revents |= (POLLIN|POLLOUT);
+ ufds[i].revents |= POLLIN|POLLOUT;
}
#else /* HAVE_POLL_FINE */
@@ -482,7 +394,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
continue;
VERIFY_SOCK(ufds[i].fd);
if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
- POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+ POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
if(ufds[i].fd > maxfd)
maxfd = ufds[i].fd;
if(ufds[i].events & (POLLRDNORM|POLLIN))
@@ -494,24 +406,39 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
}
}
+ /*
+ Note also that WinSock ignores the first argument, so we don't worry
+ about the fact that maxfd is computed incorrectly with WinSock (since
+ curl_socket_t is unsigned in such cases and thus -1 is the largest
+ value).
+ */
r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
+ if(r <= 0)
+ return r;
r = 0;
for(i = 0; i < nfds; i++) {
ufds[i].revents = 0;
if(ufds[i].fd == CURL_SOCKET_BAD)
continue;
- if(FD_ISSET(ufds[i].fd, &fds_read))
- ufds[i].revents |= POLLIN;
- if(FD_ISSET(ufds[i].fd, &fds_write))
- ufds[i].revents |= POLLOUT;
- if(FD_ISSET(ufds[i].fd, &fds_err))
- ufds[i].revents |= POLLPRI;
+ if(FD_ISSET(ufds[i].fd, &fds_read)) {
+ if(ufds[i].events & POLLRDNORM)
+ ufds[i].revents |= POLLRDNORM;
+ if(ufds[i].events & POLLIN)
+ ufds[i].revents |= POLLIN;
+ }
+ if(FD_ISSET(ufds[i].fd, &fds_write)) {
+ if(ufds[i].events & POLLWRNORM)
+ ufds[i].revents |= POLLWRNORM;
+ if(ufds[i].events & POLLOUT)
+ ufds[i].revents |= POLLOUT;
+ }
+ if(FD_ISSET(ufds[i].fd, &fds_err)) {
+ if(ufds[i].events & POLLRDBAND)
+ ufds[i].revents |= POLLRDBAND;
+ if(ufds[i].events & POLLPRI)
+ ufds[i].revents |= POLLPRI;
+ }
if(ufds[i].revents != 0)
r++;
}