1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker
27*6236dae4SAndroid Build Coastguard Worker #if !defined(HAVE_SELECT) && !defined(HAVE_POLL)
28*6236dae4SAndroid Build Coastguard Worker #error "We cannot compile without select() or poll() support."
29*6236dae4SAndroid Build Coastguard Worker #endif
30*6236dae4SAndroid Build Coastguard Worker
31*6236dae4SAndroid Build Coastguard Worker #include <limits.h>
32*6236dae4SAndroid Build Coastguard Worker
33*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SYS_SELECT_H
34*6236dae4SAndroid Build Coastguard Worker #include <sys/select.h>
35*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_UNISTD_H)
36*6236dae4SAndroid Build Coastguard Worker #include <unistd.h>
37*6236dae4SAndroid Build Coastguard Worker #endif
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker #ifdef MSDOS
40*6236dae4SAndroid Build Coastguard Worker #include <dos.h> /* delay() */
41*6236dae4SAndroid Build Coastguard Worker #endif
42*6236dae4SAndroid Build Coastguard Worker
43*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
44*6236dae4SAndroid Build Coastguard Worker
45*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
46*6236dae4SAndroid Build Coastguard Worker #include "connect.h"
47*6236dae4SAndroid Build Coastguard Worker #include "select.h"
48*6236dae4SAndroid Build Coastguard Worker #include "timediff.h"
49*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
50*6236dae4SAndroid Build Coastguard Worker /* The last 3 #include files should be in this order */
51*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
52*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
53*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
54*6236dae4SAndroid Build Coastguard Worker
55*6236dae4SAndroid Build Coastguard Worker /*
56*6236dae4SAndroid Build Coastguard Worker * Internal function used for waiting a specific amount of ms in
57*6236dae4SAndroid Build Coastguard Worker * Curl_socket_check() and Curl_poll() when no file descriptor is provided to
58*6236dae4SAndroid Build Coastguard Worker * wait on, just being used to delay execution. Winsock select() and poll()
59*6236dae4SAndroid Build Coastguard Worker * timeout mechanisms need a valid socket descriptor in a not null file
60*6236dae4SAndroid Build Coastguard Worker * descriptor set to work. Waiting indefinitely with this function is not
61*6236dae4SAndroid Build Coastguard Worker * allowed, a zero or negative timeout value will return immediately. Timeout
62*6236dae4SAndroid Build Coastguard Worker * resolution, accuracy, as well as maximum supported value is system
63*6236dae4SAndroid Build Coastguard Worker * dependent, neither factor is a critical issue for the intended use of this
64*6236dae4SAndroid Build Coastguard Worker * function in the library.
65*6236dae4SAndroid Build Coastguard Worker *
66*6236dae4SAndroid Build Coastguard Worker * Return values:
67*6236dae4SAndroid Build Coastguard Worker * -1 = system call error, or invalid timeout value
68*6236dae4SAndroid Build Coastguard Worker * 0 = specified timeout has elapsed, or interrupted
69*6236dae4SAndroid Build Coastguard Worker */
Curl_wait_ms(timediff_t timeout_ms)70*6236dae4SAndroid Build Coastguard Worker int Curl_wait_ms(timediff_t timeout_ms)
71*6236dae4SAndroid Build Coastguard Worker {
72*6236dae4SAndroid Build Coastguard Worker int r = 0;
73*6236dae4SAndroid Build Coastguard Worker
74*6236dae4SAndroid Build Coastguard Worker if(!timeout_ms)
75*6236dae4SAndroid Build Coastguard Worker return 0;
76*6236dae4SAndroid Build Coastguard Worker if(timeout_ms < 0) {
77*6236dae4SAndroid Build Coastguard Worker SET_SOCKERRNO(EINVAL);
78*6236dae4SAndroid Build Coastguard Worker return -1;
79*6236dae4SAndroid Build Coastguard Worker }
80*6236dae4SAndroid Build Coastguard Worker #if defined(MSDOS)
81*6236dae4SAndroid Build Coastguard Worker delay(timeout_ms);
82*6236dae4SAndroid Build Coastguard Worker #elif defined(_WIN32)
83*6236dae4SAndroid Build Coastguard Worker /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
84*6236dae4SAndroid Build Coastguard Worker #if TIMEDIFF_T_MAX >= ULONG_MAX
85*6236dae4SAndroid Build Coastguard Worker if(timeout_ms >= ULONG_MAX)
86*6236dae4SAndroid Build Coastguard Worker timeout_ms = ULONG_MAX-1;
87*6236dae4SAndroid Build Coastguard Worker /* do not use ULONG_MAX, because that is equal to INFINITE */
88*6236dae4SAndroid Build Coastguard Worker #endif
89*6236dae4SAndroid Build Coastguard Worker Sleep((ULONG)timeout_ms);
90*6236dae4SAndroid Build Coastguard Worker #else
91*6236dae4SAndroid Build Coastguard Worker /* avoid using poll() for this since it behaves incorrectly with no sockets
92*6236dae4SAndroid Build Coastguard Worker on Apple operating systems */
93*6236dae4SAndroid Build Coastguard Worker {
94*6236dae4SAndroid Build Coastguard Worker struct timeval pending_tv;
95*6236dae4SAndroid Build Coastguard Worker r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms));
96*6236dae4SAndroid Build Coastguard Worker }
97*6236dae4SAndroid Build Coastguard Worker #endif /* _WIN32 */
98*6236dae4SAndroid Build Coastguard Worker if(r) {
99*6236dae4SAndroid Build Coastguard Worker if((r == -1) && (SOCKERRNO == EINTR))
100*6236dae4SAndroid Build Coastguard Worker /* make EINTR from select or poll not a "lethal" error */
101*6236dae4SAndroid Build Coastguard Worker r = 0;
102*6236dae4SAndroid Build Coastguard Worker else
103*6236dae4SAndroid Build Coastguard Worker r = -1;
104*6236dae4SAndroid Build Coastguard Worker }
105*6236dae4SAndroid Build Coastguard Worker return r;
106*6236dae4SAndroid Build Coastguard Worker }
107*6236dae4SAndroid Build Coastguard Worker
108*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_POLL
109*6236dae4SAndroid Build Coastguard Worker /*
110*6236dae4SAndroid Build Coastguard Worker * This is a wrapper around select() to aid in Windows compatibility. A
111*6236dae4SAndroid Build Coastguard Worker * negative timeout value makes this function wait indefinitely, unless no
112*6236dae4SAndroid Build Coastguard Worker * valid file descriptor is given, when this happens the negative timeout is
113*6236dae4SAndroid Build Coastguard Worker * ignored and the function times out immediately.
114*6236dae4SAndroid Build Coastguard Worker *
115*6236dae4SAndroid Build Coastguard Worker * Return values:
116*6236dae4SAndroid Build Coastguard Worker * -1 = system call error or fd >= FD_SETSIZE
117*6236dae4SAndroid Build Coastguard Worker * 0 = timeout
118*6236dae4SAndroid Build Coastguard Worker * N = number of signalled file descriptors
119*6236dae4SAndroid Build Coastguard Worker */
our_select(curl_socket_t maxfd,fd_set * fds_read,fd_set * fds_write,fd_set * fds_err,timediff_t timeout_ms)120*6236dae4SAndroid Build Coastguard Worker static int our_select(curl_socket_t maxfd, /* highest socket number */
121*6236dae4SAndroid Build Coastguard Worker fd_set *fds_read, /* sockets ready for reading */
122*6236dae4SAndroid Build Coastguard Worker fd_set *fds_write, /* sockets ready for writing */
123*6236dae4SAndroid Build Coastguard Worker fd_set *fds_err, /* sockets with errors */
124*6236dae4SAndroid Build Coastguard Worker timediff_t timeout_ms) /* milliseconds to wait */
125*6236dae4SAndroid Build Coastguard Worker {
126*6236dae4SAndroid Build Coastguard Worker struct timeval pending_tv;
127*6236dae4SAndroid Build Coastguard Worker struct timeval *ptimeout;
128*6236dae4SAndroid Build Coastguard Worker
129*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WINSOCK
130*6236dae4SAndroid Build Coastguard Worker /* Winsock select() cannot handle zero events. See the comment below. */
131*6236dae4SAndroid Build Coastguard Worker if((!fds_read || fds_read->fd_count == 0) &&
132*6236dae4SAndroid Build Coastguard Worker (!fds_write || fds_write->fd_count == 0) &&
133*6236dae4SAndroid Build Coastguard Worker (!fds_err || fds_err->fd_count == 0)) {
134*6236dae4SAndroid Build Coastguard Worker /* no sockets, just wait */
135*6236dae4SAndroid Build Coastguard Worker return Curl_wait_ms(timeout_ms);
136*6236dae4SAndroid Build Coastguard Worker }
137*6236dae4SAndroid Build Coastguard Worker #endif
138*6236dae4SAndroid Build Coastguard Worker
139*6236dae4SAndroid Build Coastguard Worker ptimeout = curlx_mstotv(&pending_tv, timeout_ms);
140*6236dae4SAndroid Build Coastguard Worker
141*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WINSOCK
142*6236dae4SAndroid Build Coastguard Worker /* Winsock select() must not be called with an fd_set that contains zero
143*6236dae4SAndroid Build Coastguard Worker fd flags, or it will return WSAEINVAL. But, it also cannot be called
144*6236dae4SAndroid Build Coastguard Worker with no fd_sets at all! From the documentation:
145*6236dae4SAndroid Build Coastguard Worker
146*6236dae4SAndroid Build Coastguard Worker Any two of the parameters, readfds, writefds, or exceptfds, can be
147*6236dae4SAndroid Build Coastguard Worker given as null. At least one must be non-null, and any non-null
148*6236dae4SAndroid Build Coastguard Worker descriptor set must contain at least one handle to a socket.
149*6236dae4SAndroid Build Coastguard Worker
150*6236dae4SAndroid Build Coastguard Worker It is unclear why Winsock does not just handle this for us instead of
151*6236dae4SAndroid Build Coastguard Worker calling this an error. Luckily, with Winsock, we can _also_ ask how
152*6236dae4SAndroid Build Coastguard Worker many bits are set on an fd_set. So, let's just check it beforehand.
153*6236dae4SAndroid Build Coastguard Worker */
154*6236dae4SAndroid Build Coastguard Worker return select((int)maxfd + 1,
155*6236dae4SAndroid Build Coastguard Worker fds_read && fds_read->fd_count ? fds_read : NULL,
156*6236dae4SAndroid Build Coastguard Worker fds_write && fds_write->fd_count ? fds_write : NULL,
157*6236dae4SAndroid Build Coastguard Worker fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
158*6236dae4SAndroid Build Coastguard Worker #else
159*6236dae4SAndroid Build Coastguard Worker return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
160*6236dae4SAndroid Build Coastguard Worker #endif
161*6236dae4SAndroid Build Coastguard Worker }
162*6236dae4SAndroid Build Coastguard Worker
163*6236dae4SAndroid Build Coastguard Worker #endif
164*6236dae4SAndroid Build Coastguard Worker
165*6236dae4SAndroid Build Coastguard Worker /*
166*6236dae4SAndroid Build Coastguard Worker * Wait for read or write events on a set of file descriptors. It uses poll()
167*6236dae4SAndroid Build Coastguard Worker * when poll() is available, in order to avoid limits with FD_SETSIZE,
168*6236dae4SAndroid Build Coastguard Worker * otherwise select() is used. An error is returned if select() is being used
169*6236dae4SAndroid Build Coastguard Worker * and a file descriptor is too large for FD_SETSIZE.
170*6236dae4SAndroid Build Coastguard Worker *
171*6236dae4SAndroid Build Coastguard Worker * A negative timeout value makes this function wait indefinitely, unless no
172*6236dae4SAndroid Build Coastguard Worker * valid file descriptor is given, when this happens the negative timeout is
173*6236dae4SAndroid Build Coastguard Worker * ignored and the function times out immediately.
174*6236dae4SAndroid Build Coastguard Worker *
175*6236dae4SAndroid Build Coastguard Worker * Return values:
176*6236dae4SAndroid Build Coastguard Worker * -1 = system call error or fd >= FD_SETSIZE
177*6236dae4SAndroid Build Coastguard Worker * 0 = timeout
178*6236dae4SAndroid Build Coastguard Worker * [bitmask] = action as described below
179*6236dae4SAndroid Build Coastguard Worker *
180*6236dae4SAndroid Build Coastguard Worker * CURL_CSELECT_IN - first socket is readable
181*6236dae4SAndroid Build Coastguard Worker * CURL_CSELECT_IN2 - second socket is readable
182*6236dae4SAndroid Build Coastguard Worker * CURL_CSELECT_OUT - write socket is writable
183*6236dae4SAndroid Build Coastguard Worker * CURL_CSELECT_ERR - an error condition occurred
184*6236dae4SAndroid Build Coastguard Worker */
Curl_socket_check(curl_socket_t readfd0,curl_socket_t readfd1,curl_socket_t writefd,timediff_t timeout_ms)185*6236dae4SAndroid Build Coastguard Worker int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
186*6236dae4SAndroid Build Coastguard Worker curl_socket_t readfd1,
187*6236dae4SAndroid Build Coastguard Worker curl_socket_t writefd, /* socket to write to */
188*6236dae4SAndroid Build Coastguard Worker timediff_t timeout_ms) /* milliseconds to wait */
189*6236dae4SAndroid Build Coastguard Worker {
190*6236dae4SAndroid Build Coastguard Worker struct pollfd pfd[3];
191*6236dae4SAndroid Build Coastguard Worker int num;
192*6236dae4SAndroid Build Coastguard Worker int r;
193*6236dae4SAndroid Build Coastguard Worker
194*6236dae4SAndroid Build Coastguard Worker if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
195*6236dae4SAndroid Build Coastguard Worker (writefd == CURL_SOCKET_BAD)) {
196*6236dae4SAndroid Build Coastguard Worker /* no sockets, just wait */
197*6236dae4SAndroid Build Coastguard Worker return Curl_wait_ms(timeout_ms);
198*6236dae4SAndroid Build Coastguard Worker }
199*6236dae4SAndroid Build Coastguard Worker
200*6236dae4SAndroid Build Coastguard Worker /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
201*6236dae4SAndroid Build Coastguard Worker time in this function does not need to be measured. This happens
202*6236dae4SAndroid Build Coastguard Worker when function is called with a zero timeout or a negative timeout
203*6236dae4SAndroid Build Coastguard Worker value indicating a blocking call should be performed. */
204*6236dae4SAndroid Build Coastguard Worker
205*6236dae4SAndroid Build Coastguard Worker num = 0;
206*6236dae4SAndroid Build Coastguard Worker if(readfd0 != CURL_SOCKET_BAD) {
207*6236dae4SAndroid Build Coastguard Worker pfd[num].fd = readfd0;
208*6236dae4SAndroid Build Coastguard Worker pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
209*6236dae4SAndroid Build Coastguard Worker pfd[num].revents = 0;
210*6236dae4SAndroid Build Coastguard Worker num++;
211*6236dae4SAndroid Build Coastguard Worker }
212*6236dae4SAndroid Build Coastguard Worker if(readfd1 != CURL_SOCKET_BAD) {
213*6236dae4SAndroid Build Coastguard Worker pfd[num].fd = readfd1;
214*6236dae4SAndroid Build Coastguard Worker pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
215*6236dae4SAndroid Build Coastguard Worker pfd[num].revents = 0;
216*6236dae4SAndroid Build Coastguard Worker num++;
217*6236dae4SAndroid Build Coastguard Worker }
218*6236dae4SAndroid Build Coastguard Worker if(writefd != CURL_SOCKET_BAD) {
219*6236dae4SAndroid Build Coastguard Worker pfd[num].fd = writefd;
220*6236dae4SAndroid Build Coastguard Worker pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI;
221*6236dae4SAndroid Build Coastguard Worker pfd[num].revents = 0;
222*6236dae4SAndroid Build Coastguard Worker num++;
223*6236dae4SAndroid Build Coastguard Worker }
224*6236dae4SAndroid Build Coastguard Worker
225*6236dae4SAndroid Build Coastguard Worker r = Curl_poll(pfd, (unsigned int)num, timeout_ms);
226*6236dae4SAndroid Build Coastguard Worker if(r <= 0)
227*6236dae4SAndroid Build Coastguard Worker return r;
228*6236dae4SAndroid Build Coastguard Worker
229*6236dae4SAndroid Build Coastguard Worker r = 0;
230*6236dae4SAndroid Build Coastguard Worker num = 0;
231*6236dae4SAndroid Build Coastguard Worker if(readfd0 != CURL_SOCKET_BAD) {
232*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
233*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_IN;
234*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLPRI|POLLNVAL))
235*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_ERR;
236*6236dae4SAndroid Build Coastguard Worker num++;
237*6236dae4SAndroid Build Coastguard Worker }
238*6236dae4SAndroid Build Coastguard Worker if(readfd1 != CURL_SOCKET_BAD) {
239*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
240*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_IN2;
241*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLPRI|POLLNVAL))
242*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_ERR;
243*6236dae4SAndroid Build Coastguard Worker num++;
244*6236dae4SAndroid Build Coastguard Worker }
245*6236dae4SAndroid Build Coastguard Worker if(writefd != CURL_SOCKET_BAD) {
246*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLWRNORM|POLLOUT))
247*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_OUT;
248*6236dae4SAndroid Build Coastguard Worker if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL))
249*6236dae4SAndroid Build Coastguard Worker r |= CURL_CSELECT_ERR;
250*6236dae4SAndroid Build Coastguard Worker }
251*6236dae4SAndroid Build Coastguard Worker
252*6236dae4SAndroid Build Coastguard Worker return r;
253*6236dae4SAndroid Build Coastguard Worker }
254*6236dae4SAndroid Build Coastguard Worker
255*6236dae4SAndroid Build Coastguard Worker /*
256*6236dae4SAndroid Build Coastguard Worker * This is a wrapper around poll(). If poll() does not exist, then
257*6236dae4SAndroid Build Coastguard Worker * select() is used instead. An error is returned if select() is
258*6236dae4SAndroid Build Coastguard Worker * being used and a file descriptor is too large for FD_SETSIZE.
259*6236dae4SAndroid Build Coastguard Worker * A negative timeout value makes this function wait indefinitely,
260*6236dae4SAndroid Build Coastguard Worker * unless no valid file descriptor is given, when this happens the
261*6236dae4SAndroid Build Coastguard Worker * negative timeout is ignored and the function times out immediately.
262*6236dae4SAndroid Build Coastguard Worker *
263*6236dae4SAndroid Build Coastguard Worker * Return values:
264*6236dae4SAndroid Build Coastguard Worker * -1 = system call error or fd >= FD_SETSIZE
265*6236dae4SAndroid Build Coastguard Worker * 0 = timeout
266*6236dae4SAndroid Build Coastguard Worker * N = number of structures with non zero revent fields
267*6236dae4SAndroid Build Coastguard Worker */
Curl_poll(struct pollfd ufds[],unsigned int nfds,timediff_t timeout_ms)268*6236dae4SAndroid Build Coastguard Worker int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
269*6236dae4SAndroid Build Coastguard Worker {
270*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_POLL
271*6236dae4SAndroid Build Coastguard Worker int pending_ms;
272*6236dae4SAndroid Build Coastguard Worker #else
273*6236dae4SAndroid Build Coastguard Worker fd_set fds_read;
274*6236dae4SAndroid Build Coastguard Worker fd_set fds_write;
275*6236dae4SAndroid Build Coastguard Worker fd_set fds_err;
276*6236dae4SAndroid Build Coastguard Worker curl_socket_t maxfd;
277*6236dae4SAndroid Build Coastguard Worker #endif
278*6236dae4SAndroid Build Coastguard Worker bool fds_none = TRUE;
279*6236dae4SAndroid Build Coastguard Worker unsigned int i;
280*6236dae4SAndroid Build Coastguard Worker int r;
281*6236dae4SAndroid Build Coastguard Worker
282*6236dae4SAndroid Build Coastguard Worker if(ufds) {
283*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < nfds; i++) {
284*6236dae4SAndroid Build Coastguard Worker if(ufds[i].fd != CURL_SOCKET_BAD) {
285*6236dae4SAndroid Build Coastguard Worker fds_none = FALSE;
286*6236dae4SAndroid Build Coastguard Worker break;
287*6236dae4SAndroid Build Coastguard Worker }
288*6236dae4SAndroid Build Coastguard Worker }
289*6236dae4SAndroid Build Coastguard Worker }
290*6236dae4SAndroid Build Coastguard Worker if(fds_none) {
291*6236dae4SAndroid Build Coastguard Worker /* no sockets, just wait */
292*6236dae4SAndroid Build Coastguard Worker return Curl_wait_ms(timeout_ms);
293*6236dae4SAndroid Build Coastguard Worker }
294*6236dae4SAndroid Build Coastguard Worker
295*6236dae4SAndroid Build Coastguard Worker /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
296*6236dae4SAndroid Build Coastguard Worker time in this function does not need to be measured. This happens
297*6236dae4SAndroid Build Coastguard Worker when function is called with a zero timeout or a negative timeout
298*6236dae4SAndroid Build Coastguard Worker value indicating a blocking call should be performed. */
299*6236dae4SAndroid Build Coastguard Worker
300*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_POLL
301*6236dae4SAndroid Build Coastguard Worker
302*6236dae4SAndroid Build Coastguard Worker /* prevent overflow, timeout_ms is typecast to int. */
303*6236dae4SAndroid Build Coastguard Worker #if TIMEDIFF_T_MAX > INT_MAX
304*6236dae4SAndroid Build Coastguard Worker if(timeout_ms > INT_MAX)
305*6236dae4SAndroid Build Coastguard Worker timeout_ms = INT_MAX;
306*6236dae4SAndroid Build Coastguard Worker #endif
307*6236dae4SAndroid Build Coastguard Worker if(timeout_ms > 0)
308*6236dae4SAndroid Build Coastguard Worker pending_ms = (int)timeout_ms;
309*6236dae4SAndroid Build Coastguard Worker else if(timeout_ms < 0)
310*6236dae4SAndroid Build Coastguard Worker pending_ms = -1;
311*6236dae4SAndroid Build Coastguard Worker else
312*6236dae4SAndroid Build Coastguard Worker pending_ms = 0;
313*6236dae4SAndroid Build Coastguard Worker r = poll(ufds, nfds, pending_ms);
314*6236dae4SAndroid Build Coastguard Worker if(r <= 0) {
315*6236dae4SAndroid Build Coastguard Worker if((r == -1) && (SOCKERRNO == EINTR))
316*6236dae4SAndroid Build Coastguard Worker /* make EINTR from select or poll not a "lethal" error */
317*6236dae4SAndroid Build Coastguard Worker r = 0;
318*6236dae4SAndroid Build Coastguard Worker return r;
319*6236dae4SAndroid Build Coastguard Worker }
320*6236dae4SAndroid Build Coastguard Worker
321*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < nfds; i++) {
322*6236dae4SAndroid Build Coastguard Worker if(ufds[i].fd == CURL_SOCKET_BAD)
323*6236dae4SAndroid Build Coastguard Worker continue;
324*6236dae4SAndroid Build Coastguard Worker if(ufds[i].revents & POLLHUP)
325*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLIN;
326*6236dae4SAndroid Build Coastguard Worker if(ufds[i].revents & POLLERR)
327*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLIN|POLLOUT;
328*6236dae4SAndroid Build Coastguard Worker }
329*6236dae4SAndroid Build Coastguard Worker
330*6236dae4SAndroid Build Coastguard Worker #else /* HAVE_POLL */
331*6236dae4SAndroid Build Coastguard Worker
332*6236dae4SAndroid Build Coastguard Worker FD_ZERO(&fds_read);
333*6236dae4SAndroid Build Coastguard Worker FD_ZERO(&fds_write);
334*6236dae4SAndroid Build Coastguard Worker FD_ZERO(&fds_err);
335*6236dae4SAndroid Build Coastguard Worker maxfd = (curl_socket_t)-1;
336*6236dae4SAndroid Build Coastguard Worker
337*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < nfds; i++) {
338*6236dae4SAndroid Build Coastguard Worker ufds[i].revents = 0;
339*6236dae4SAndroid Build Coastguard Worker if(ufds[i].fd == CURL_SOCKET_BAD)
340*6236dae4SAndroid Build Coastguard Worker continue;
341*6236dae4SAndroid Build Coastguard Worker VERIFY_SOCK(ufds[i].fd);
342*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
343*6236dae4SAndroid Build Coastguard Worker POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
344*6236dae4SAndroid Build Coastguard Worker if(ufds[i].fd > maxfd)
345*6236dae4SAndroid Build Coastguard Worker maxfd = ufds[i].fd;
346*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & (POLLRDNORM|POLLIN))
347*6236dae4SAndroid Build Coastguard Worker FD_SET(ufds[i].fd, &fds_read);
348*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & (POLLWRNORM|POLLOUT))
349*6236dae4SAndroid Build Coastguard Worker FD_SET(ufds[i].fd, &fds_write);
350*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & (POLLRDBAND|POLLPRI))
351*6236dae4SAndroid Build Coastguard Worker FD_SET(ufds[i].fd, &fds_err);
352*6236dae4SAndroid Build Coastguard Worker }
353*6236dae4SAndroid Build Coastguard Worker }
354*6236dae4SAndroid Build Coastguard Worker
355*6236dae4SAndroid Build Coastguard Worker /*
356*6236dae4SAndroid Build Coastguard Worker Note also that Winsock ignores the first argument, so we do not worry
357*6236dae4SAndroid Build Coastguard Worker about the fact that maxfd is computed incorrectly with Winsock (since
358*6236dae4SAndroid Build Coastguard Worker curl_socket_t is unsigned in such cases and thus -1 is the largest
359*6236dae4SAndroid Build Coastguard Worker value).
360*6236dae4SAndroid Build Coastguard Worker */
361*6236dae4SAndroid Build Coastguard Worker r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
362*6236dae4SAndroid Build Coastguard Worker if(r <= 0) {
363*6236dae4SAndroid Build Coastguard Worker if((r == -1) && (SOCKERRNO == EINTR))
364*6236dae4SAndroid Build Coastguard Worker /* make EINTR from select or poll not a "lethal" error */
365*6236dae4SAndroid Build Coastguard Worker r = 0;
366*6236dae4SAndroid Build Coastguard Worker return r;
367*6236dae4SAndroid Build Coastguard Worker }
368*6236dae4SAndroid Build Coastguard Worker
369*6236dae4SAndroid Build Coastguard Worker r = 0;
370*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < nfds; i++) {
371*6236dae4SAndroid Build Coastguard Worker ufds[i].revents = 0;
372*6236dae4SAndroid Build Coastguard Worker if(ufds[i].fd == CURL_SOCKET_BAD)
373*6236dae4SAndroid Build Coastguard Worker continue;
374*6236dae4SAndroid Build Coastguard Worker if(FD_ISSET(ufds[i].fd, &fds_read)) {
375*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLRDNORM)
376*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLRDNORM;
377*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLIN)
378*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLIN;
379*6236dae4SAndroid Build Coastguard Worker }
380*6236dae4SAndroid Build Coastguard Worker if(FD_ISSET(ufds[i].fd, &fds_write)) {
381*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLWRNORM)
382*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLWRNORM;
383*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLOUT)
384*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLOUT;
385*6236dae4SAndroid Build Coastguard Worker }
386*6236dae4SAndroid Build Coastguard Worker if(FD_ISSET(ufds[i].fd, &fds_err)) {
387*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLRDBAND)
388*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLRDBAND;
389*6236dae4SAndroid Build Coastguard Worker if(ufds[i].events & POLLPRI)
390*6236dae4SAndroid Build Coastguard Worker ufds[i].revents |= POLLPRI;
391*6236dae4SAndroid Build Coastguard Worker }
392*6236dae4SAndroid Build Coastguard Worker if(ufds[i].revents)
393*6236dae4SAndroid Build Coastguard Worker r++;
394*6236dae4SAndroid Build Coastguard Worker }
395*6236dae4SAndroid Build Coastguard Worker
396*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_POLL */
397*6236dae4SAndroid Build Coastguard Worker
398*6236dae4SAndroid Build Coastguard Worker return r;
399*6236dae4SAndroid Build Coastguard Worker }
400*6236dae4SAndroid Build Coastguard Worker
Curl_pollfds_init(struct curl_pollfds * cpfds,struct pollfd * static_pfds,unsigned int static_count)401*6236dae4SAndroid Build Coastguard Worker void Curl_pollfds_init(struct curl_pollfds *cpfds,
402*6236dae4SAndroid Build Coastguard Worker struct pollfd *static_pfds,
403*6236dae4SAndroid Build Coastguard Worker unsigned int static_count)
404*6236dae4SAndroid Build Coastguard Worker {
405*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cpfds);
406*6236dae4SAndroid Build Coastguard Worker memset(cpfds, 0, sizeof(*cpfds));
407*6236dae4SAndroid Build Coastguard Worker if(static_pfds && static_count) {
408*6236dae4SAndroid Build Coastguard Worker cpfds->pfds = static_pfds;
409*6236dae4SAndroid Build Coastguard Worker cpfds->count = static_count;
410*6236dae4SAndroid Build Coastguard Worker }
411*6236dae4SAndroid Build Coastguard Worker }
412*6236dae4SAndroid Build Coastguard Worker
Curl_pollfds_cleanup(struct curl_pollfds * cpfds)413*6236dae4SAndroid Build Coastguard Worker void Curl_pollfds_cleanup(struct curl_pollfds *cpfds)
414*6236dae4SAndroid Build Coastguard Worker {
415*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cpfds);
416*6236dae4SAndroid Build Coastguard Worker if(cpfds->allocated_pfds) {
417*6236dae4SAndroid Build Coastguard Worker free(cpfds->pfds);
418*6236dae4SAndroid Build Coastguard Worker }
419*6236dae4SAndroid Build Coastguard Worker memset(cpfds, 0, sizeof(*cpfds));
420*6236dae4SAndroid Build Coastguard Worker }
421*6236dae4SAndroid Build Coastguard Worker
cpfds_increase(struct curl_pollfds * cpfds,unsigned int inc)422*6236dae4SAndroid Build Coastguard Worker static CURLcode cpfds_increase(struct curl_pollfds *cpfds, unsigned int inc)
423*6236dae4SAndroid Build Coastguard Worker {
424*6236dae4SAndroid Build Coastguard Worker struct pollfd *new_fds;
425*6236dae4SAndroid Build Coastguard Worker unsigned int new_count = cpfds->count + inc;
426*6236dae4SAndroid Build Coastguard Worker
427*6236dae4SAndroid Build Coastguard Worker new_fds = calloc(new_count, sizeof(struct pollfd));
428*6236dae4SAndroid Build Coastguard Worker if(!new_fds)
429*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
430*6236dae4SAndroid Build Coastguard Worker
431*6236dae4SAndroid Build Coastguard Worker memcpy(new_fds, cpfds->pfds, cpfds->count * sizeof(struct pollfd));
432*6236dae4SAndroid Build Coastguard Worker if(cpfds->allocated_pfds)
433*6236dae4SAndroid Build Coastguard Worker free(cpfds->pfds);
434*6236dae4SAndroid Build Coastguard Worker cpfds->pfds = new_fds;
435*6236dae4SAndroid Build Coastguard Worker cpfds->count = new_count;
436*6236dae4SAndroid Build Coastguard Worker cpfds->allocated_pfds = TRUE;
437*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
438*6236dae4SAndroid Build Coastguard Worker }
439*6236dae4SAndroid Build Coastguard Worker
cpfds_add_sock(struct curl_pollfds * cpfds,curl_socket_t sock,short events,bool fold)440*6236dae4SAndroid Build Coastguard Worker static CURLcode cpfds_add_sock(struct curl_pollfds *cpfds,
441*6236dae4SAndroid Build Coastguard Worker curl_socket_t sock, short events, bool fold)
442*6236dae4SAndroid Build Coastguard Worker {
443*6236dae4SAndroid Build Coastguard Worker int i;
444*6236dae4SAndroid Build Coastguard Worker
445*6236dae4SAndroid Build Coastguard Worker if(fold && cpfds->n <= INT_MAX) {
446*6236dae4SAndroid Build Coastguard Worker for(i = (int)cpfds->n - 1; i >= 0; --i) {
447*6236dae4SAndroid Build Coastguard Worker if(sock == cpfds->pfds[i].fd) {
448*6236dae4SAndroid Build Coastguard Worker cpfds->pfds[i].events |= events;
449*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
450*6236dae4SAndroid Build Coastguard Worker }
451*6236dae4SAndroid Build Coastguard Worker }
452*6236dae4SAndroid Build Coastguard Worker }
453*6236dae4SAndroid Build Coastguard Worker /* not folded, add new entry */
454*6236dae4SAndroid Build Coastguard Worker if(cpfds->n >= cpfds->count) {
455*6236dae4SAndroid Build Coastguard Worker if(cpfds_increase(cpfds, 100))
456*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
457*6236dae4SAndroid Build Coastguard Worker }
458*6236dae4SAndroid Build Coastguard Worker cpfds->pfds[cpfds->n].fd = sock;
459*6236dae4SAndroid Build Coastguard Worker cpfds->pfds[cpfds->n].events = events;
460*6236dae4SAndroid Build Coastguard Worker ++cpfds->n;
461*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
462*6236dae4SAndroid Build Coastguard Worker }
463*6236dae4SAndroid Build Coastguard Worker
Curl_pollfds_add_sock(struct curl_pollfds * cpfds,curl_socket_t sock,short events)464*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_pollfds_add_sock(struct curl_pollfds *cpfds,
465*6236dae4SAndroid Build Coastguard Worker curl_socket_t sock, short events)
466*6236dae4SAndroid Build Coastguard Worker {
467*6236dae4SAndroid Build Coastguard Worker return cpfds_add_sock(cpfds, sock, events, FALSE);
468*6236dae4SAndroid Build Coastguard Worker }
469*6236dae4SAndroid Build Coastguard Worker
Curl_pollfds_add_ps(struct curl_pollfds * cpfds,struct easy_pollset * ps)470*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds,
471*6236dae4SAndroid Build Coastguard Worker struct easy_pollset *ps)
472*6236dae4SAndroid Build Coastguard Worker {
473*6236dae4SAndroid Build Coastguard Worker size_t i;
474*6236dae4SAndroid Build Coastguard Worker
475*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cpfds);
476*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(ps);
477*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < ps->num; i++) {
478*6236dae4SAndroid Build Coastguard Worker short events = 0;
479*6236dae4SAndroid Build Coastguard Worker if(ps->actions[i] & CURL_POLL_IN)
480*6236dae4SAndroid Build Coastguard Worker events |= POLLIN;
481*6236dae4SAndroid Build Coastguard Worker if(ps->actions[i] & CURL_POLL_OUT)
482*6236dae4SAndroid Build Coastguard Worker events |= POLLOUT;
483*6236dae4SAndroid Build Coastguard Worker if(events) {
484*6236dae4SAndroid Build Coastguard Worker if(cpfds_add_sock(cpfds, ps->sockets[i], events, TRUE))
485*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
486*6236dae4SAndroid Build Coastguard Worker }
487*6236dae4SAndroid Build Coastguard Worker }
488*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
489*6236dae4SAndroid Build Coastguard Worker }
490*6236dae4SAndroid Build Coastguard Worker
Curl_waitfds_init(struct curl_waitfds * cwfds,struct curl_waitfd * static_wfds,unsigned int static_count)491*6236dae4SAndroid Build Coastguard Worker void Curl_waitfds_init(struct curl_waitfds *cwfds,
492*6236dae4SAndroid Build Coastguard Worker struct curl_waitfd *static_wfds,
493*6236dae4SAndroid Build Coastguard Worker unsigned int static_count)
494*6236dae4SAndroid Build Coastguard Worker {
495*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cwfds);
496*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(static_wfds);
497*6236dae4SAndroid Build Coastguard Worker memset(cwfds, 0, sizeof(*cwfds));
498*6236dae4SAndroid Build Coastguard Worker cwfds->wfds = static_wfds;
499*6236dae4SAndroid Build Coastguard Worker cwfds->count = static_count;
500*6236dae4SAndroid Build Coastguard Worker }
501*6236dae4SAndroid Build Coastguard Worker
cwfds_add_sock(struct curl_waitfds * cwfds,curl_socket_t sock,short events)502*6236dae4SAndroid Build Coastguard Worker static CURLcode cwfds_add_sock(struct curl_waitfds *cwfds,
503*6236dae4SAndroid Build Coastguard Worker curl_socket_t sock, short events)
504*6236dae4SAndroid Build Coastguard Worker {
505*6236dae4SAndroid Build Coastguard Worker int i;
506*6236dae4SAndroid Build Coastguard Worker
507*6236dae4SAndroid Build Coastguard Worker if(cwfds->n <= INT_MAX) {
508*6236dae4SAndroid Build Coastguard Worker for(i = (int)cwfds->n - 1; i >= 0; --i) {
509*6236dae4SAndroid Build Coastguard Worker if(sock == cwfds->wfds[i].fd) {
510*6236dae4SAndroid Build Coastguard Worker cwfds->wfds[i].events |= events;
511*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
512*6236dae4SAndroid Build Coastguard Worker }
513*6236dae4SAndroid Build Coastguard Worker }
514*6236dae4SAndroid Build Coastguard Worker }
515*6236dae4SAndroid Build Coastguard Worker /* not folded, add new entry */
516*6236dae4SAndroid Build Coastguard Worker if(cwfds->n >= cwfds->count)
517*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
518*6236dae4SAndroid Build Coastguard Worker cwfds->wfds[cwfds->n].fd = sock;
519*6236dae4SAndroid Build Coastguard Worker cwfds->wfds[cwfds->n].events = events;
520*6236dae4SAndroid Build Coastguard Worker ++cwfds->n;
521*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
522*6236dae4SAndroid Build Coastguard Worker }
523*6236dae4SAndroid Build Coastguard Worker
Curl_waitfds_add_ps(struct curl_waitfds * cwfds,struct easy_pollset * ps)524*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
525*6236dae4SAndroid Build Coastguard Worker struct easy_pollset *ps)
526*6236dae4SAndroid Build Coastguard Worker {
527*6236dae4SAndroid Build Coastguard Worker size_t i;
528*6236dae4SAndroid Build Coastguard Worker
529*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cwfds);
530*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(ps);
531*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < ps->num; i++) {
532*6236dae4SAndroid Build Coastguard Worker short events = 0;
533*6236dae4SAndroid Build Coastguard Worker if(ps->actions[i] & CURL_POLL_IN)
534*6236dae4SAndroid Build Coastguard Worker events |= CURL_WAIT_POLLIN;
535*6236dae4SAndroid Build Coastguard Worker if(ps->actions[i] & CURL_POLL_OUT)
536*6236dae4SAndroid Build Coastguard Worker events |= CURL_WAIT_POLLOUT;
537*6236dae4SAndroid Build Coastguard Worker if(events) {
538*6236dae4SAndroid Build Coastguard Worker if(cwfds_add_sock(cwfds, ps->sockets[i], events))
539*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
540*6236dae4SAndroid Build Coastguard Worker }
541*6236dae4SAndroid Build Coastguard Worker }
542*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
543*6236dae4SAndroid Build Coastguard Worker }
544