blob: 52dca5a2c0b0efe20c1936c69e20da445c8317cb [file] [log] [blame]
Kristian Monsen5ab50182010-05-14 18:53:44 +01001/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
Elliott Hughes34dd5f42021-08-10 13:01:18 -07008 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
Kristian Monsen5ab50182010-05-14 18:53:44 +01009 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
Elliott Hughes34dd5f42021-08-10 13:01:18 -070012 * are also available at https://curl.se/docs/copyright.html.
Kristian Monsen5ab50182010-05-14 18:53:44 +010013 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070023#include "curl_setup.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010024
Haibo Huangca2a8022020-07-10 20:17:42 -070025#include <limits.h>
26
Kristian Monsen5ab50182010-05-14 18:53:44 +010027#ifdef HAVE_SYS_SELECT_H
28#include <sys/select.h>
Haibo Huang24c77a12020-04-29 13:49:57 -070029#elif defined(HAVE_UNISTD_H)
30#include <unistd.h>
Kristian Monsen5ab50182010-05-14 18:53:44 +010031#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +010032
33#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
34#error "We can't compile without select() or poll() support."
35#endif
36
37#if defined(__BEOS__) && !defined(__HAIKU__)
38/* BeOS has FD_SET defined in socket.h */
39#include <socket.h>
40#endif
41
42#ifdef MSDOS
43#include <dos.h> /* delay() */
44#endif
45
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070046#ifdef __VXWORKS__
47#include <strings.h> /* bzero() in FD_SET */
48#endif
49
Kristian Monsen5ab50182010-05-14 18:53:44 +010050#include <curl/curl.h>
51
52#include "urldata.h"
53#include "connect.h"
54#include "select.h"
Haibo Huangca2a8022020-07-10 20:17:42 -070055#include "timeval.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070056#include "warnless.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010057
Kristian Monsen5ab50182010-05-14 18:53:44 +010058/*
59 * Internal function used for waiting a specific amount of ms
Elliott Hughescee03382017-06-23 12:17:18 -070060 * in Curl_socket_check() and Curl_poll() when no file descriptor
Kristian Monsen5ab50182010-05-14 18:53:44 +010061 * is provided to wait on, just being used to delay execution.
62 * WinSock select() and poll() timeout mechanisms need a valid
63 * socket descriptor in a not null file descriptor set to work.
64 * Waiting indefinitely with this function is not allowed, a
65 * zero or negative timeout value will return immediately.
66 * Timeout resolution, accuracy, as well as maximum supported
67 * value is system dependent, neither factor is a citical issue
68 * for the intended use of this function in the library.
Kristian Monsen5ab50182010-05-14 18:53:44 +010069 *
70 * Return values:
71 * -1 = system call error, invalid timeout value, or interrupted
72 * 0 = specified timeout has elapsed
73 */
Haibo Huangca2a8022020-07-10 20:17:42 -070074int Curl_wait_ms(timediff_t timeout_ms)
Kristian Monsen5ab50182010-05-14 18:53:44 +010075{
Kristian Monsen5ab50182010-05-14 18:53:44 +010076 int r = 0;
77
78 if(!timeout_ms)
79 return 0;
80 if(timeout_ms < 0) {
81 SET_SOCKERRNO(EINVAL);
82 return -1;
83 }
84#if defined(MSDOS)
85 delay(timeout_ms);
Haibo Huangca2a8022020-07-10 20:17:42 -070086#elif defined(WIN32)
87 /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
88#if TIMEDIFF_T_MAX >= ULONG_MAX
89 if(timeout_ms >= ULONG_MAX)
90 timeout_ms = ULONG_MAX-1;
91 /* don't use ULONG_MAX, because that is equal to INFINITE */
92#endif
93 Sleep((ULONG)timeout_ms);
Kristian Monsen5ab50182010-05-14 18:53:44 +010094#else
Kristian Monsen5ab50182010-05-14 18:53:44 +010095#if defined(HAVE_POLL_FINE)
Haibo Huangca2a8022020-07-10 20:17:42 -070096 /* prevent overflow, timeout_ms is typecast to int. */
97#if TIMEDIFF_T_MAX > INT_MAX
98 if(timeout_ms > INT_MAX)
99 timeout_ms = INT_MAX;
100#endif
101 r = poll(NULL, 0, (int)timeout_ms);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100102#else
Haibo Huangb51266f2020-03-04 02:22:48 -0800103 {
104 struct timeval pending_tv;
Haibo Huangca2a8022020-07-10 20:17:42 -0700105 timediff_t tv_sec = timeout_ms / 1000;
106 timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
107#ifdef HAVE_SUSECONDS_T
108#if TIMEDIFF_T_MAX > TIME_T_MAX
109 /* tv_sec overflow check in case time_t is signed */
110 if(tv_sec > TIME_T_MAX)
111 tv_sec = TIME_T_MAX;
112#endif
113 pending_tv.tv_sec = (time_t)tv_sec;
114 pending_tv.tv_usec = (suseconds_t)tv_usec;
115#else
116#if TIMEDIFF_T_MAX > INT_MAX
117 /* tv_sec overflow check in case time_t is signed */
118 if(tv_sec > INT_MAX)
119 tv_sec = INT_MAX;
120#endif
121 pending_tv.tv_sec = (int)tv_sec;
122 pending_tv.tv_usec = (int)tv_usec;
123#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +0100124 r = select(0, NULL, NULL, NULL, &pending_tv);
Haibo Huangb51266f2020-03-04 02:22:48 -0800125 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100126#endif /* HAVE_POLL_FINE */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100127#endif /* USE_WINSOCK */
128 if(r)
129 r = -1;
130 return r;
131}
132
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700133#ifndef HAVE_POLL_FINE
Kristian Monsen5ab50182010-05-14 18:53:44 +0100134/*
Haibo Huang24c77a12020-04-29 13:49:57 -0700135 * This is a wrapper around select() to aid in Windows compatibility.
136 * A negative timeout value makes this function wait indefinitely,
137 * unless no valid file descriptor is given, when this happens the
138 * negative timeout is ignored and the function times out immediately.
139 *
140 * Return values:
141 * -1 = system call error or fd >= FD_SETSIZE
142 * 0 = timeout
143 * N = number of signalled file descriptors
144 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700145static int our_select(curl_socket_t maxfd, /* highest socket number */
146 fd_set *fds_read, /* sockets ready for reading */
147 fd_set *fds_write, /* sockets ready for writing */
148 fd_set *fds_err, /* sockets with errors */
149 timediff_t timeout_ms) /* milliseconds to wait */
Haibo Huang24c77a12020-04-29 13:49:57 -0700150{
151 struct timeval pending_tv;
152 struct timeval *ptimeout;
Haibo Huang24c77a12020-04-29 13:49:57 -0700153
Haibo Huang24c77a12020-04-29 13:49:57 -0700154#ifdef USE_WINSOCK
155 /* WinSock select() can't handle zero events. See the comment below. */
156 if((!fds_read || fds_read->fd_count == 0) &&
157 (!fds_write || fds_write->fd_count == 0) &&
158 (!fds_err || fds_err->fd_count == 0)) {
Haibo Huangb5a52b92020-10-28 22:18:23 -0700159 /* no sockets, just wait */
160 return Curl_wait_ms(timeout_ms);
Haibo Huang24c77a12020-04-29 13:49:57 -0700161 }
162#endif
163
164 ptimeout = &pending_tv;
Haibo Huang24c77a12020-04-29 13:49:57 -0700165 if(timeout_ms < 0) {
166 ptimeout = NULL;
167 }
168 else if(timeout_ms > 0) {
Haibo Huangca2a8022020-07-10 20:17:42 -0700169 timediff_t tv_sec = timeout_ms / 1000;
170 timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
171#ifdef HAVE_SUSECONDS_T
172#if TIMEDIFF_T_MAX > TIME_T_MAX
173 /* tv_sec overflow check in case time_t is signed */
174 if(tv_sec > TIME_T_MAX)
175 tv_sec = TIME_T_MAX;
176#endif
177 pending_tv.tv_sec = (time_t)tv_sec;
178 pending_tv.tv_usec = (suseconds_t)tv_usec;
179#elif defined(WIN32) /* maybe also others in the future */
180#if TIMEDIFF_T_MAX > LONG_MAX
181 /* tv_sec overflow check on Windows there we know it is long */
182 if(tv_sec > LONG_MAX)
183 tv_sec = LONG_MAX;
184#endif
185 pending_tv.tv_sec = (long)tv_sec;
186 pending_tv.tv_usec = (long)tv_usec;
187#else
188#if TIMEDIFF_T_MAX > INT_MAX
189 /* tv_sec overflow check in case time_t is signed */
190 if(tv_sec > INT_MAX)
191 tv_sec = INT_MAX;
192#endif
193 pending_tv.tv_sec = (int)tv_sec;
194 pending_tv.tv_usec = (int)tv_usec;
195#endif
Haibo Huang24c77a12020-04-29 13:49:57 -0700196 }
Haibo Huangca2a8022020-07-10 20:17:42 -0700197 else {
Haibo Huang24c77a12020-04-29 13:49:57 -0700198 pending_tv.tv_sec = 0;
199 pending_tv.tv_usec = 0;
200 }
201
202#ifdef USE_WINSOCK
203 /* WinSock select() must not be called with an fd_set that contains zero
204 fd flags, or it will return WSAEINVAL. But, it also can't be called
205 with no fd_sets at all! From the documentation:
206
207 Any two of the parameters, readfds, writefds, or exceptfds, can be
208 given as null. At least one must be non-null, and any non-null
209 descriptor set must contain at least one handle to a socket.
210
211 It is unclear why WinSock doesn't just handle this for us instead of
Haibo Huangb5a52b92020-10-28 22:18:23 -0700212 calling this an error. Luckily, with WinSock, we can _also_ ask how
213 many bits are set on an fd_set. So, let's just check it beforehand.
Haibo Huang24c77a12020-04-29 13:49:57 -0700214 */
Haibo Huangb5a52b92020-10-28 22:18:23 -0700215 return select((int)maxfd + 1,
216 fds_read && fds_read->fd_count ? fds_read : NULL,
217 fds_write && fds_write->fd_count ? fds_write : NULL,
218 fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
Haibo Huang24c77a12020-04-29 13:49:57 -0700219#else
Haibo Huangb5a52b92020-10-28 22:18:23 -0700220 return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
Haibo Huang24c77a12020-04-29 13:49:57 -0700221#endif
Haibo Huang24c77a12020-04-29 13:49:57 -0700222}
223
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700224#endif
225
Haibo Huang24c77a12020-04-29 13:49:57 -0700226/*
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700227 * Wait for read or write events on a set of file descriptors. It uses poll()
228 * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
229 * otherwise select() is used. An error is returned if select() is being used
230 * and a file descriptor is too large for FD_SETSIZE.
231 *
Kristian Monsen5ab50182010-05-14 18:53:44 +0100232 * A negative timeout value makes this function wait indefinitely,
Elliott Hughes82be86d2017-09-20 17:00:17 -0700233 * unless no valid file descriptor is given, when this happens the
Kristian Monsen5ab50182010-05-14 18:53:44 +0100234 * negative timeout is ignored and the function times out immediately.
Kristian Monsen5ab50182010-05-14 18:53:44 +0100235 *
236 * Return values:
237 * -1 = system call error or fd >= FD_SETSIZE
238 * 0 = timeout
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700239 * [bitmask] = action as described below
240 *
241 * CURL_CSELECT_IN - first socket is readable
242 * CURL_CSELECT_IN2 - second socket is readable
243 * CURL_CSELECT_OUT - write socket is writable
244 * CURL_CSELECT_ERR - an error condition occurred
Kristian Monsen5ab50182010-05-14 18:53:44 +0100245 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700246int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
247 curl_socket_t readfd1,
248 curl_socket_t writefd, /* socket to write to */
Haibo Huangca2a8022020-07-10 20:17:42 -0700249 timediff_t timeout_ms) /* milliseconds to wait */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100250{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700251 struct pollfd pfd[3];
Kristian Monsen5ab50182010-05-14 18:53:44 +0100252 int num;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100253 int r;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100254
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700255 if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
256 (writefd == CURL_SOCKET_BAD)) {
257 /* no sockets, just wait */
Haibo Huangb5a52b92020-10-28 22:18:23 -0700258 return Curl_wait_ms(timeout_ms);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100259 }
260
Alex Deymo486467e2017-12-19 19:04:07 +0100261 /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
Kristian Monsen5ab50182010-05-14 18:53:44 +0100262 time in this function does not need to be measured. This happens
263 when function is called with a zero timeout or a negative timeout
264 value indicating a blocking call should be performed. */
265
Kristian Monsen5ab50182010-05-14 18:53:44 +0100266 num = 0;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700267 if(readfd0 != CURL_SOCKET_BAD) {
268 pfd[num].fd = readfd0;
269 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
270 pfd[num].revents = 0;
271 num++;
272 }
273 if(readfd1 != CURL_SOCKET_BAD) {
274 pfd[num].fd = readfd1;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100275 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
276 pfd[num].revents = 0;
277 num++;
278 }
279 if(writefd != CURL_SOCKET_BAD) {
280 pfd[num].fd = writefd;
Haibo Huangb5a52b92020-10-28 22:18:23 -0700281 pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100282 pfd[num].revents = 0;
283 num++;
284 }
285
Haibo Huangca2a8022020-07-10 20:17:42 -0700286 r = Curl_poll(pfd, num, timeout_ms);
287 if(r <= 0)
288 return r;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100289
Haibo Huangb5a52b92020-10-28 22:18:23 -0700290 r = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100291 num = 0;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700292 if(readfd0 != CURL_SOCKET_BAD) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100293 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
Haibo Huangb5a52b92020-10-28 22:18:23 -0700294 r |= CURL_CSELECT_IN;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100295 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
Haibo Huangb5a52b92020-10-28 22:18:23 -0700296 r |= CURL_CSELECT_ERR;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100297 num++;
298 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700299 if(readfd1 != CURL_SOCKET_BAD) {
300 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
Haibo Huangb5a52b92020-10-28 22:18:23 -0700301 r |= CURL_CSELECT_IN2;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700302 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
Haibo Huangb5a52b92020-10-28 22:18:23 -0700303 r |= CURL_CSELECT_ERR;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700304 num++;
305 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100306 if(writefd != CURL_SOCKET_BAD) {
307 if(pfd[num].revents & (POLLWRNORM|POLLOUT))
Haibo Huangb5a52b92020-10-28 22:18:23 -0700308 r |= CURL_CSELECT_OUT;
309 if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL))
310 r |= CURL_CSELECT_ERR;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100311 }
312
Haibo Huangb5a52b92020-10-28 22:18:23 -0700313 return r;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100314}
315
316/*
317 * This is a wrapper around poll(). If poll() does not exist, then
318 * select() is used instead. An error is returned if select() is
319 * being used and a file descriptor is too large for FD_SETSIZE.
320 * A negative timeout value makes this function wait indefinitely,
Elliott Hughes82be86d2017-09-20 17:00:17 -0700321 * unless no valid file descriptor is given, when this happens the
Kristian Monsen5ab50182010-05-14 18:53:44 +0100322 * negative timeout is ignored and the function times out immediately.
Kristian Monsen5ab50182010-05-14 18:53:44 +0100323 *
324 * Return values:
325 * -1 = system call error or fd >= FD_SETSIZE
326 * 0 = timeout
327 * N = number of structures with non zero revent fields
328 */
Haibo Huangca2a8022020-07-10 20:17:42 -0700329int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100330{
Haibo Huang24c77a12020-04-29 13:49:57 -0700331#ifdef HAVE_POLL_FINE
332 int pending_ms;
333#else
Kristian Monsen5ab50182010-05-14 18:53:44 +0100334 fd_set fds_read;
335 fd_set fds_write;
336 fd_set fds_err;
337 curl_socket_t maxfd;
338#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +0100339 bool fds_none = TRUE;
340 unsigned int i;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100341 int r;
342
343 if(ufds) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700344 for(i = 0; i < nfds; i++) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100345 if(ufds[i].fd != CURL_SOCKET_BAD) {
346 fds_none = FALSE;
347 break;
348 }
349 }
350 }
351 if(fds_none) {
Haibo Huangca2a8022020-07-10 20:17:42 -0700352 /* no sockets, just wait */
Haibo Huangb5a52b92020-10-28 22:18:23 -0700353 return Curl_wait_ms(timeout_ms);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100354 }
355
Alex Deymo486467e2017-12-19 19:04:07 +0100356 /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
Kristian Monsen5ab50182010-05-14 18:53:44 +0100357 time in this function does not need to be measured. This happens
358 when function is called with a zero timeout or a negative timeout
359 value indicating a blocking call should be performed. */
360
Kristian Monsen5ab50182010-05-14 18:53:44 +0100361#ifdef HAVE_POLL_FINE
362
Haibo Huangca2a8022020-07-10 20:17:42 -0700363 /* prevent overflow, timeout_ms is typecast to int. */
364#if TIMEDIFF_T_MAX > INT_MAX
365 if(timeout_ms > INT_MAX)
366 timeout_ms = INT_MAX;
367#endif
Haibo Huang24c77a12020-04-29 13:49:57 -0700368 if(timeout_ms > 0)
Haibo Huangca2a8022020-07-10 20:17:42 -0700369 pending_ms = (int)timeout_ms;
Haibo Huang24c77a12020-04-29 13:49:57 -0700370 else if(timeout_ms < 0)
Haibo Huangb51266f2020-03-04 02:22:48 -0800371 pending_ms = -1;
Haibo Huang24c77a12020-04-29 13:49:57 -0700372 else
Haibo Huangb51266f2020-03-04 02:22:48 -0800373 pending_ms = 0;
374 r = poll(ufds, nfds, pending_ms);
Haibo Huangb5a52b92020-10-28 22:18:23 -0700375 if(r <= 0)
376 return r;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100377
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700378 for(i = 0; i < nfds; i++) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100379 if(ufds[i].fd == CURL_SOCKET_BAD)
380 continue;
381 if(ufds[i].revents & POLLHUP)
382 ufds[i].revents |= POLLIN;
383 if(ufds[i].revents & POLLERR)
Haibo Huangb5a52b92020-10-28 22:18:23 -0700384 ufds[i].revents |= POLLIN|POLLOUT;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100385 }
386
387#else /* HAVE_POLL_FINE */
388
389 FD_ZERO(&fds_read);
390 FD_ZERO(&fds_write);
391 FD_ZERO(&fds_err);
392 maxfd = (curl_socket_t)-1;
393
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700394 for(i = 0; i < nfds; i++) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100395 ufds[i].revents = 0;
396 if(ufds[i].fd == CURL_SOCKET_BAD)
397 continue;
398 VERIFY_SOCK(ufds[i].fd);
399 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
Haibo Huangb5a52b92020-10-28 22:18:23 -0700400 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100401 if(ufds[i].fd > maxfd)
402 maxfd = ufds[i].fd;
403 if(ufds[i].events & (POLLRDNORM|POLLIN))
404 FD_SET(ufds[i].fd, &fds_read);
405 if(ufds[i].events & (POLLWRNORM|POLLOUT))
406 FD_SET(ufds[i].fd, &fds_write);
407 if(ufds[i].events & (POLLRDBAND|POLLPRI))
408 FD_SET(ufds[i].fd, &fds_err);
409 }
410 }
411
Haibo Huangb5a52b92020-10-28 22:18:23 -0700412 /*
413 Note also that WinSock ignores the first argument, so we don't worry
414 about the fact that maxfd is computed incorrectly with WinSock (since
415 curl_socket_t is unsigned in such cases and thus -1 is the largest
416 value).
417 */
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700418 r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
Haibo Huangb5a52b92020-10-28 22:18:23 -0700419 if(r <= 0)
420 return r;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100421
422 r = 0;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700423 for(i = 0; i < nfds; i++) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100424 ufds[i].revents = 0;
425 if(ufds[i].fd == CURL_SOCKET_BAD)
426 continue;
Haibo Huangb5a52b92020-10-28 22:18:23 -0700427 if(FD_ISSET(ufds[i].fd, &fds_read)) {
428 if(ufds[i].events & POLLRDNORM)
429 ufds[i].revents |= POLLRDNORM;
430 if(ufds[i].events & POLLIN)
431 ufds[i].revents |= POLLIN;
432 }
433 if(FD_ISSET(ufds[i].fd, &fds_write)) {
434 if(ufds[i].events & POLLWRNORM)
435 ufds[i].revents |= POLLWRNORM;
436 if(ufds[i].events & POLLOUT)
437 ufds[i].revents |= POLLOUT;
438 }
439 if(FD_ISSET(ufds[i].fd, &fds_err)) {
440 if(ufds[i].events & POLLRDBAND)
441 ufds[i].revents |= POLLRDBAND;
442 if(ufds[i].events & POLLPRI)
443 ufds[i].revents |= POLLPRI;
444 }
Elliott Hughes34dd5f42021-08-10 13:01:18 -0700445 if(ufds[i].revents)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100446 r++;
447 }
448
449#endif /* HAVE_POLL_FINE */
450
451 return r;
452}
453
454#ifdef TPF
455/*
456 * This is a replacement for select() on the TPF platform.
457 * It is used whenever libcurl calls select().
458 * The call below to tpf_process_signals() is required because
459 * TPF's select calls are not signal interruptible.
460 *
461 * Return values are the same as select's.
462 */
Elliott Hughes82be86d2017-09-20 17:00:17 -0700463int tpf_select_libcurl(int maxfds, fd_set *reads, fd_set *writes,
464 fd_set *excepts, struct timeval *tv)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100465{
466 int rc;
467
468 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
469 tpf_process_signals();
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700470 return rc;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100471}
472#endif /* TPF */