1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2014, 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 http://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 */
55 #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
57 int Curl_ack_eintr = 0;
58 #define error_not_EINTR (Curl_ack_eintr || error != EINTR)
61 * Internal function used for waiting a specific amount of ms
62 * in Curl_socket_ready() and Curl_poll() when no file descriptor
63 * is provided to wait on, just being used to delay execution.
64 * WinSock select() and poll() timeout mechanisms need a valid
65 * socket descriptor in a not null file descriptor set to work.
66 * Waiting indefinitely with this function is not allowed, a
67 * zero or negative timeout value will return immediately.
68 * Timeout resolution, accuracy, as well as maximum supported
69 * value is system dependent, neither factor is a citical issue
70 * for the intended use of this function in the library.
73 * -1 = system call error, invalid timeout value, or interrupted
74 * 0 = specified timeout has elapsed
76 int Curl_wait_ms(int timeout_ms)
78 #if !defined(MSDOS) && !defined(USE_WINSOCK)
79 #ifndef HAVE_POLL_FINE
80 struct timeval pending_tv;
82 struct timeval initial_tv;
91 SET_SOCKERRNO(EINVAL);
96 #elif defined(USE_WINSOCK)
99 pending_ms = timeout_ms;
100 initial_tv = curlx_tvnow();
102 #if defined(HAVE_POLL_FINE)
103 r = poll(NULL, 0, pending_ms);
105 pending_tv.tv_sec = pending_ms / 1000;
106 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
107 r = select(0, NULL, NULL, NULL, &pending_tv);
108 #endif /* HAVE_POLL_FINE */
112 if(error && error_not_EINTR)
114 pending_ms = timeout_ms - elapsed_ms;
115 if(pending_ms <= 0) {
116 r = 0; /* Simulate a "call timed out" case */
120 #endif /* USE_WINSOCK */
127 * Wait for read or write events on a set of file descriptors. It uses poll()
128 * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
129 * otherwise select() is used. An error is returned if select() is being used
130 * and a file descriptor is too large for FD_SETSIZE.
132 * A negative timeout value makes this function wait indefinitely,
133 * unles no valid file descriptor is given, when this happens the
134 * negative timeout is ignored and the function times out immediately.
137 * -1 = system call error or fd >= FD_SETSIZE
139 * [bitmask] = action as described below
141 * CURL_CSELECT_IN - first socket is readable
142 * CURL_CSELECT_IN2 - second socket is readable
143 * CURL_CSELECT_OUT - write socket is writable
144 * CURL_CSELECT_ERR - an error condition occurred
146 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
147 curl_socket_t readfd1,
148 curl_socket_t writefd, /* socket to write to */
149 long timeout_ms) /* milliseconds to wait */
151 #ifdef HAVE_POLL_FINE
152 struct pollfd pfd[3];
155 struct timeval pending_tv;
156 struct timeval *ptimeout;
162 struct timeval initial_tv = {0,0};
168 if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
169 (writefd == CURL_SOCKET_BAD)) {
170 /* no sockets, just wait */
171 r = Curl_wait_ms((int)timeout_ms);
175 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
176 time in this function does not need to be measured. This happens
177 when function is called with a zero timeout or a negative timeout
178 value indicating a blocking call should be performed. */
181 pending_ms = (int)timeout_ms;
182 initial_tv = curlx_tvnow();
185 #ifdef HAVE_POLL_FINE
188 if(readfd0 != CURL_SOCKET_BAD) {
189 pfd[num].fd = readfd0;
190 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
191 pfd[num].revents = 0;
194 if(readfd1 != CURL_SOCKET_BAD) {
195 pfd[num].fd = readfd1;
196 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
197 pfd[num].revents = 0;
200 if(writefd != CURL_SOCKET_BAD) {
201 pfd[num].fd = writefd;
202 pfd[num].events = POLLWRNORM|POLLOUT;
203 pfd[num].revents = 0;
212 r = poll(pfd, num, pending_ms);
216 if(error && error_not_EINTR)
219 pending_ms = (int)(timeout_ms - elapsed_ms);
220 if(pending_ms <= 0) {
221 r = 0; /* Simulate a "call timed out" case */
234 if(readfd0 != CURL_SOCKET_BAD) {
235 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
236 ret |= CURL_CSELECT_IN;
237 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
238 ret |= CURL_CSELECT_ERR;
241 if(readfd1 != CURL_SOCKET_BAD) {
242 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
243 ret |= CURL_CSELECT_IN2;
244 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
245 ret |= CURL_CSELECT_ERR;
248 if(writefd != CURL_SOCKET_BAD) {
249 if(pfd[num].revents & (POLLWRNORM|POLLOUT))
250 ret |= CURL_CSELECT_OUT;
251 if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
252 ret |= CURL_CSELECT_ERR;
257 #else /* HAVE_POLL_FINE */
260 maxfd = (curl_socket_t)-1;
263 if(readfd0 != CURL_SOCKET_BAD) {
264 VERIFY_SOCK(readfd0);
265 FD_SET(readfd0, &fds_read);
266 FD_SET(readfd0, &fds_err);
269 if(readfd1 != CURL_SOCKET_BAD) {
270 VERIFY_SOCK(readfd1);
271 FD_SET(readfd1, &fds_read);
272 FD_SET(readfd1, &fds_err);
278 if(writefd != CURL_SOCKET_BAD) {
279 VERIFY_SOCK(writefd);
280 FD_SET(writefd, &fds_write);
281 FD_SET(writefd, &fds_err);
286 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
290 pending_tv.tv_sec = pending_ms / 1000;
291 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
293 else if(!timeout_ms) {
294 pending_tv.tv_sec = 0;
295 pending_tv.tv_usec = 0;
298 /* WinSock select() must not be called with an fd_set that contains zero
299 fd flags, or it will return WSAEINVAL. But, it also can't be called
300 with no fd_sets at all! From the documentation:
302 Any two of the parameters, readfds, writefds, or exceptfds, can be
303 given as null. At least one must be non-null, and any non-null
304 descriptor set must contain at least one handle to a socket.
306 We know that we have at least one bit set in at least two fd_sets in
307 this case, but we may have no bits set in either fds_read or fd_write,
308 so check for that and handle it. Luckily, with WinSock, we can _also_
309 ask how many bits are set on an fd_set.
311 It is unclear why WinSock doesn't just handle this for us instead of
312 calling this an error.
314 Note also that WinSock ignores the first argument, so we don't worry
315 about the fact that maxfd is computed incorrectly with WinSock (since
316 curl_socket_t is unsigned in such cases and thus -1 is the largest
319 r = select((int)maxfd + 1,
324 fds_read.fd_count ? &fds_read : NULL,
325 fds_write.fd_count ? &fds_write : NULL,
331 if(error && error_not_EINTR)
334 pending_ms = timeout_ms - elapsed_ms;
335 if(pending_ms <= 0) {
336 r = 0; /* Simulate a "call timed out" case */
348 if(readfd0 != CURL_SOCKET_BAD) {
349 if(FD_ISSET(readfd0, &fds_read))
350 ret |= CURL_CSELECT_IN;
351 if(FD_ISSET(readfd0, &fds_err))
352 ret |= CURL_CSELECT_ERR;
354 if(readfd1 != CURL_SOCKET_BAD) {
355 if(FD_ISSET(readfd1, &fds_read))
356 ret |= CURL_CSELECT_IN2;
357 if(FD_ISSET(readfd1, &fds_err))
358 ret |= CURL_CSELECT_ERR;
360 if(writefd != CURL_SOCKET_BAD) {
361 if(FD_ISSET(writefd, &fds_write))
362 ret |= CURL_CSELECT_OUT;
363 if(FD_ISSET(writefd, &fds_err))
364 ret |= CURL_CSELECT_ERR;
369 #endif /* HAVE_POLL_FINE */
374 * This is a wrapper around poll(). If poll() does not exist, then
375 * select() is used instead. An error is returned if select() is
376 * being used and a file descriptor is too large for FD_SETSIZE.
377 * A negative timeout value makes this function wait indefinitely,
378 * unles no valid file descriptor is given, when this happens the
379 * negative timeout is ignored and the function times out immediately.
382 * -1 = system call error or fd >= FD_SETSIZE
384 * N = number of structures with non zero revent fields
386 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
388 #ifndef HAVE_POLL_FINE
389 struct timeval pending_tv;
390 struct timeval *ptimeout;
396 struct timeval initial_tv = {0,0};
397 bool fds_none = TRUE;
404 for(i = 0; i < nfds; i++) {
405 if(ufds[i].fd != CURL_SOCKET_BAD) {
412 r = Curl_wait_ms(timeout_ms);
416 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
417 time in this function does not need to be measured. This happens
418 when function is called with a zero timeout or a negative timeout
419 value indicating a blocking call should be performed. */
422 pending_ms = timeout_ms;
423 initial_tv = curlx_tvnow();
426 #ifdef HAVE_POLL_FINE
433 r = poll(ufds, nfds, pending_ms);
437 if(error && error_not_EINTR)
440 pending_ms = timeout_ms - elapsed_ms;
441 if(pending_ms <= 0) {
442 r = 0; /* Simulate a "call timed out" case */
453 for(i = 0; i < nfds; i++) {
454 if(ufds[i].fd == CURL_SOCKET_BAD)
456 if(ufds[i].revents & POLLHUP)
457 ufds[i].revents |= POLLIN;
458 if(ufds[i].revents & POLLERR)
459 ufds[i].revents |= (POLLIN|POLLOUT);
462 #else /* HAVE_POLL_FINE */
467 maxfd = (curl_socket_t)-1;
469 for(i = 0; i < nfds; i++) {
471 if(ufds[i].fd == CURL_SOCKET_BAD)
473 VERIFY_SOCK(ufds[i].fd);
474 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
475 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
476 if(ufds[i].fd > maxfd)
478 if(ufds[i].events & (POLLRDNORM|POLLIN))
479 FD_SET(ufds[i].fd, &fds_read);
480 if(ufds[i].events & (POLLWRNORM|POLLOUT))
481 FD_SET(ufds[i].fd, &fds_write);
482 if(ufds[i].events & (POLLRDBAND|POLLPRI))
483 FD_SET(ufds[i].fd, &fds_err);
488 /* WinSock select() can't handle zero events. See the comment about this in
489 Curl_check_socket(). */
490 if(fds_read.fd_count == 0 && fds_write.fd_count == 0
491 && fds_err.fd_count == 0) {
492 r = Curl_wait_ms(timeout_ms);
497 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
501 pending_tv.tv_sec = pending_ms / 1000;
502 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
504 else if(!timeout_ms) {
505 pending_tv.tv_sec = 0;
506 pending_tv.tv_usec = 0;
508 r = select((int)maxfd + 1,
510 &fds_read, &fds_write, &fds_err,
512 /* WinSock select() can't handle fd_sets with zero bits set, so
513 don't give it such arguments. See the comment about this in
516 fds_read.fd_count ? &fds_read : NULL,
517 fds_write.fd_count ? &fds_write : NULL,
518 fds_err.fd_count ? &fds_err : NULL,
524 if(error && error_not_EINTR)
527 pending_ms = timeout_ms - elapsed_ms;
528 if(pending_ms <= 0) {
529 r = 0; /* Simulate a "call timed out" case */
541 for(i = 0; i < nfds; i++) {
543 if(ufds[i].fd == CURL_SOCKET_BAD)
545 if(FD_ISSET(ufds[i].fd, &fds_read))
546 ufds[i].revents |= POLLIN;
547 if(FD_ISSET(ufds[i].fd, &fds_write))
548 ufds[i].revents |= POLLOUT;
549 if(FD_ISSET(ufds[i].fd, &fds_err))
550 ufds[i].revents |= POLLPRI;
551 if(ufds[i].revents != 0)
555 #endif /* HAVE_POLL_FINE */
562 * This is a replacement for select() on the TPF platform.
563 * It is used whenever libcurl calls select().
564 * The call below to tpf_process_signals() is required because
565 * TPF's select calls are not signal interruptible.
567 * Return values are the same as select's.
569 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
570 fd_set* excepts, struct timeval* tv)
574 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
575 tpf_process_signals();