1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifdef HAVE_SYS_SELECT_H
26 #include <sys/select.h>
29 #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
30 #error "We can't compile without select() or poll() support."
33 #if defined(__BEOS__) && !defined(__HAIKU__)
34 /* BeOS has FD_SET defined in socket.h */
39 #include <dos.h> /* delay() */
43 #include <strings.h> /* bzero() in FD_SET */
46 #include <curl/curl.h>
53 /* Convenience local macros */
54 #define ELAPSED_MS() (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
56 int Curl_ack_eintr = 0;
57 #define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
60 * Internal function used for waiting a specific amount of ms
61 * in Curl_socket_check() and Curl_poll() when no file descriptor
62 * is provided to wait on, just being used to delay execution.
63 * WinSock select() and poll() timeout mechanisms need a valid
64 * socket descriptor in a not null file descriptor set to work.
65 * Waiting indefinitely with this function is not allowed, a
66 * zero or negative timeout value will return immediately.
67 * Timeout resolution, accuracy, as well as maximum supported
68 * value is system dependent, neither factor is a citical issue
69 * for the intended use of this function in the library.
72 * -1 = system call error, invalid timeout value, or interrupted
73 * 0 = specified timeout has elapsed
75 int Curl_wait_ms(int timeout_ms)
77 #if !defined(MSDOS) && !defined(USE_WINSOCK)
78 #ifndef HAVE_POLL_FINE
79 struct timeval pending_tv;
81 struct timeval initial_tv;
90 SET_SOCKERRNO(EINVAL);
95 #elif defined(USE_WINSOCK)
98 pending_ms = timeout_ms;
99 initial_tv = curlx_tvnow();
101 #if defined(HAVE_POLL_FINE)
102 r = poll(NULL, 0, pending_ms);
104 pending_tv.tv_sec = pending_ms / 1000;
105 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
106 r = select(0, NULL, NULL, NULL, &pending_tv);
107 #endif /* HAVE_POLL_FINE */
111 if(error && ERROR_NOT_EINTR(error))
113 pending_ms = timeout_ms - ELAPSED_MS();
114 if(pending_ms <= 0) {
115 r = 0; /* Simulate a "call timed out" case */
119 #endif /* USE_WINSOCK */
126 * Wait for read or write events on a set of file descriptors. It uses poll()
127 * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
128 * otherwise select() is used. An error is returned if select() is being used
129 * and a file descriptor is too large for FD_SETSIZE.
131 * A negative timeout value makes this function wait indefinitely,
132 * unles no valid file descriptor is given, when this happens the
133 * negative timeout is ignored and the function times out immediately.
136 * -1 = system call error or fd >= FD_SETSIZE
138 * [bitmask] = action as described below
140 * CURL_CSELECT_IN - first socket is readable
141 * CURL_CSELECT_IN2 - second socket is readable
142 * CURL_CSELECT_OUT - write socket is writable
143 * CURL_CSELECT_ERR - an error condition occurred
145 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
146 curl_socket_t readfd1,
147 curl_socket_t writefd, /* socket to write to */
148 time_t timeout_ms) /* milliseconds to wait */
150 #ifdef HAVE_POLL_FINE
151 struct pollfd pfd[3];
154 struct timeval pending_tv;
155 struct timeval *ptimeout;
161 struct timeval initial_tv = {0, 0};
167 #if SIZEOF_LONG != SIZEOF_INT
168 /* wrap-around precaution */
169 if(timeout_ms >= INT_MAX)
170 timeout_ms = INT_MAX;
173 if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
174 (writefd == CURL_SOCKET_BAD)) {
175 /* no sockets, just wait */
176 r = Curl_wait_ms((int)timeout_ms);
180 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
181 time in this function does not need to be measured. This happens
182 when function is called with a zero timeout or a negative timeout
183 value indicating a blocking call should be performed. */
186 pending_ms = (int)timeout_ms;
187 initial_tv = curlx_tvnow();
190 #ifdef HAVE_POLL_FINE
193 if(readfd0 != CURL_SOCKET_BAD) {
194 pfd[num].fd = readfd0;
195 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
196 pfd[num].revents = 0;
199 if(readfd1 != CURL_SOCKET_BAD) {
200 pfd[num].fd = readfd1;
201 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
202 pfd[num].revents = 0;
205 if(writefd != CURL_SOCKET_BAD) {
206 pfd[num].fd = writefd;
207 pfd[num].events = POLLWRNORM|POLLOUT;
208 pfd[num].revents = 0;
217 r = poll(pfd, num, pending_ms);
221 if(error && ERROR_NOT_EINTR(error))
224 pending_ms = (int)(timeout_ms - ELAPSED_MS());
225 if(pending_ms <= 0) {
226 r = 0; /* Simulate a "call timed out" case */
239 if(readfd0 != CURL_SOCKET_BAD) {
240 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
241 ret |= CURL_CSELECT_IN;
242 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
243 ret |= CURL_CSELECT_ERR;
246 if(readfd1 != CURL_SOCKET_BAD) {
247 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
248 ret |= CURL_CSELECT_IN2;
249 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
250 ret |= CURL_CSELECT_ERR;
253 if(writefd != CURL_SOCKET_BAD) {
254 if(pfd[num].revents & (POLLWRNORM|POLLOUT))
255 ret |= CURL_CSELECT_OUT;
256 if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
257 ret |= CURL_CSELECT_ERR;
262 #else /* HAVE_POLL_FINE */
265 maxfd = (curl_socket_t)-1;
268 if(readfd0 != CURL_SOCKET_BAD) {
269 VERIFY_SOCK(readfd0);
270 FD_SET(readfd0, &fds_read);
271 FD_SET(readfd0, &fds_err);
274 if(readfd1 != CURL_SOCKET_BAD) {
275 VERIFY_SOCK(readfd1);
276 FD_SET(readfd1, &fds_read);
277 FD_SET(readfd1, &fds_err);
283 if(writefd != CURL_SOCKET_BAD) {
284 VERIFY_SOCK(writefd);
285 FD_SET(writefd, &fds_write);
286 FD_SET(writefd, &fds_err);
291 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
295 pending_tv.tv_sec = pending_ms / 1000;
296 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
298 else if(!timeout_ms) {
299 pending_tv.tv_sec = 0;
300 pending_tv.tv_usec = 0;
303 /* WinSock select() must not be called with an fd_set that contains zero
304 fd flags, or it will return WSAEINVAL. But, it also can't be called
305 with no fd_sets at all! From the documentation:
307 Any two of the parameters, readfds, writefds, or exceptfds, can be
308 given as null. At least one must be non-null, and any non-null
309 descriptor set must contain at least one handle to a socket.
311 We know that we have at least one bit set in at least two fd_sets in
312 this case, but we may have no bits set in either fds_read or fd_write,
313 so check for that and handle it. Luckily, with WinSock, we can _also_
314 ask how many bits are set on an fd_set.
316 It is unclear why WinSock doesn't just handle this for us instead of
317 calling this an error.
319 Note also that WinSock ignores the first argument, so we don't worry
320 about the fact that maxfd is computed incorrectly with WinSock (since
321 curl_socket_t is unsigned in such cases and thus -1 is the largest
325 r = select((int)maxfd + 1,
326 fds_read.fd_count ? &fds_read : NULL,
327 fds_write.fd_count ? &fds_write : NULL,
330 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
336 if(error && ERROR_NOT_EINTR(error))
339 pending_ms = (int)(timeout_ms - ELAPSED_MS());
340 if(pending_ms <= 0) {
341 r = 0; /* Simulate a "call timed out" case */
353 if(readfd0 != CURL_SOCKET_BAD) {
354 if(FD_ISSET(readfd0, &fds_read))
355 ret |= CURL_CSELECT_IN;
356 if(FD_ISSET(readfd0, &fds_err))
357 ret |= CURL_CSELECT_ERR;
359 if(readfd1 != CURL_SOCKET_BAD) {
360 if(FD_ISSET(readfd1, &fds_read))
361 ret |= CURL_CSELECT_IN2;
362 if(FD_ISSET(readfd1, &fds_err))
363 ret |= CURL_CSELECT_ERR;
365 if(writefd != CURL_SOCKET_BAD) {
366 if(FD_ISSET(writefd, &fds_write))
367 ret |= CURL_CSELECT_OUT;
368 if(FD_ISSET(writefd, &fds_err))
369 ret |= CURL_CSELECT_ERR;
374 #endif /* HAVE_POLL_FINE */
379 * This is a wrapper around poll(). If poll() does not exist, then
380 * select() is used instead. An error is returned if select() is
381 * being used and a file descriptor is too large for FD_SETSIZE.
382 * A negative timeout value makes this function wait indefinitely,
383 * unles no valid file descriptor is given, when this happens the
384 * negative timeout is ignored and the function times out immediately.
387 * -1 = system call error or fd >= FD_SETSIZE
389 * N = number of structures with non zero revent fields
391 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
393 #ifndef HAVE_POLL_FINE
394 struct timeval pending_tv;
395 struct timeval *ptimeout;
401 struct timeval initial_tv = {0, 0};
402 bool fds_none = TRUE;
409 for(i = 0; i < nfds; i++) {
410 if(ufds[i].fd != CURL_SOCKET_BAD) {
417 r = Curl_wait_ms(timeout_ms);
421 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
422 time in this function does not need to be measured. This happens
423 when function is called with a zero timeout or a negative timeout
424 value indicating a blocking call should be performed. */
427 pending_ms = timeout_ms;
428 initial_tv = curlx_tvnow();
431 #ifdef HAVE_POLL_FINE
438 r = poll(ufds, nfds, pending_ms);
442 if(error && ERROR_NOT_EINTR(error))
445 pending_ms = (int)(timeout_ms - ELAPSED_MS());
446 if(pending_ms <= 0) {
447 r = 0; /* Simulate a "call timed out" case */
458 for(i = 0; i < nfds; i++) {
459 if(ufds[i].fd == CURL_SOCKET_BAD)
461 if(ufds[i].revents & POLLHUP)
462 ufds[i].revents |= POLLIN;
463 if(ufds[i].revents & POLLERR)
464 ufds[i].revents |= (POLLIN|POLLOUT);
467 #else /* HAVE_POLL_FINE */
472 maxfd = (curl_socket_t)-1;
474 for(i = 0; i < nfds; i++) {
476 if(ufds[i].fd == CURL_SOCKET_BAD)
478 VERIFY_SOCK(ufds[i].fd);
479 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
480 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
481 if(ufds[i].fd > maxfd)
483 if(ufds[i].events & (POLLRDNORM|POLLIN))
484 FD_SET(ufds[i].fd, &fds_read);
485 if(ufds[i].events & (POLLWRNORM|POLLOUT))
486 FD_SET(ufds[i].fd, &fds_write);
487 if(ufds[i].events & (POLLRDBAND|POLLPRI))
488 FD_SET(ufds[i].fd, &fds_err);
493 /* WinSock select() can't handle zero events. See the comment about this in
494 Curl_check_socket(). */
495 if(fds_read.fd_count == 0 && fds_write.fd_count == 0
496 && fds_err.fd_count == 0) {
497 r = Curl_wait_ms(timeout_ms);
502 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
506 pending_tv.tv_sec = pending_ms / 1000;
507 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
509 else if(!timeout_ms) {
510 pending_tv.tv_sec = 0;
511 pending_tv.tv_usec = 0;
515 r = select((int)maxfd + 1,
516 /* WinSock select() can't handle fd_sets with zero bits set, so
517 don't give it such arguments. See the comment about this in
520 fds_read.fd_count ? &fds_read : NULL,
521 fds_write.fd_count ? &fds_write : NULL,
522 fds_err.fd_count ? &fds_err : NULL, ptimeout);
524 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
529 if(error && ERROR_NOT_EINTR(error))
532 pending_ms = timeout_ms - ELAPSED_MS();
533 if(pending_ms <= 0) {
534 r = 0; /* Simulate a "call timed out" case */
546 for(i = 0; i < nfds; i++) {
548 if(ufds[i].fd == CURL_SOCKET_BAD)
550 if(FD_ISSET(ufds[i].fd, &fds_read))
551 ufds[i].revents |= POLLIN;
552 if(FD_ISSET(ufds[i].fd, &fds_write))
553 ufds[i].revents |= POLLOUT;
554 if(FD_ISSET(ufds[i].fd, &fds_err))
555 ufds[i].revents |= POLLPRI;
556 if(ufds[i].revents != 0)
560 #endif /* HAVE_POLL_FINE */
567 * This is a replacement for select() on the TPF platform.
568 * It is used whenever libcurl calls select().
569 * The call below to tpf_process_signals() is required because
570 * TPF's select calls are not signal interruptible.
572 * Return values are the same as select's.
574 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
575 fd_set* excepts, struct timeval* tv)
579 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
580 tpf_process_signals();