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() */
42 #include <curl/curl.h>
49 /* Convenience local macros */
51 #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
53 int Curl_ack_eintr = 0;
54 #define error_not_EINTR (Curl_ack_eintr || error != EINTR)
57 * Internal function used for waiting a specific amount of ms
58 * in Curl_socket_ready() and Curl_poll() when no file descriptor
59 * is provided to wait on, just being used to delay execution.
60 * WinSock select() and poll() timeout mechanisms need a valid
61 * socket descriptor in a not null file descriptor set to work.
62 * Waiting indefinitely with this function is not allowed, a
63 * zero or negative timeout value will return immediately.
64 * Timeout resolution, accuracy, as well as maximum supported
65 * value is system dependent, neither factor is a citical issue
66 * for the intended use of this function in the library.
69 * -1 = system call error, invalid timeout value, or interrupted
70 * 0 = specified timeout has elapsed
72 int Curl_wait_ms(int timeout_ms)
74 #if !defined(MSDOS) && !defined(USE_WINSOCK)
75 #ifndef HAVE_POLL_FINE
76 struct timeval pending_tv;
78 struct timeval initial_tv;
87 SET_SOCKERRNO(EINVAL);
92 #elif defined(USE_WINSOCK)
95 pending_ms = timeout_ms;
96 initial_tv = curlx_tvnow();
98 #if defined(HAVE_POLL_FINE)
99 r = poll(NULL, 0, pending_ms);
101 pending_tv.tv_sec = pending_ms / 1000;
102 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
103 r = select(0, NULL, NULL, NULL, &pending_tv);
104 #endif /* HAVE_POLL_FINE */
108 if(error && error_not_EINTR)
110 pending_ms = timeout_ms - elapsed_ms;
114 #endif /* USE_WINSOCK */
121 * Wait for read or write events on a set of file descriptors. It uses poll()
122 * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
123 * otherwise select() is used. An error is returned if select() is being used
124 * and a file descriptor is too large for FD_SETSIZE.
126 * A negative timeout value makes this function wait indefinitely,
127 * unles no valid file descriptor is given, when this happens the
128 * negative timeout is ignored and the function times out immediately.
131 * -1 = system call error or fd >= FD_SETSIZE
133 * [bitmask] = action as described below
135 * CURL_CSELECT_IN - first socket is readable
136 * CURL_CSELECT_IN2 - second socket is readable
137 * CURL_CSELECT_OUT - write socket is writable
138 * CURL_CSELECT_ERR - an error condition occurred
140 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
141 curl_socket_t readfd1,
142 curl_socket_t writefd, /* socket to write to */
143 long timeout_ms) /* milliseconds to wait */
145 #ifdef HAVE_POLL_FINE
146 struct pollfd pfd[3];
149 struct timeval pending_tv;
150 struct timeval *ptimeout;
156 struct timeval initial_tv = {0,0};
162 if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
163 (writefd == CURL_SOCKET_BAD)) {
164 /* no sockets, just wait */
165 r = Curl_wait_ms((int)timeout_ms);
169 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
170 time in this function does not need to be measured. This happens
171 when function is called with a zero timeout or a negative timeout
172 value indicating a blocking call should be performed. */
175 pending_ms = (int)timeout_ms;
176 initial_tv = curlx_tvnow();
179 #ifdef HAVE_POLL_FINE
182 if(readfd0 != CURL_SOCKET_BAD) {
183 pfd[num].fd = readfd0;
184 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
185 pfd[num].revents = 0;
188 if(readfd1 != CURL_SOCKET_BAD) {
189 pfd[num].fd = readfd1;
190 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
191 pfd[num].revents = 0;
194 if(writefd != CURL_SOCKET_BAD) {
195 pfd[num].fd = writefd;
196 pfd[num].events = POLLWRNORM|POLLOUT;
197 pfd[num].revents = 0;
206 r = poll(pfd, num, pending_ms);
210 if(error && error_not_EINTR)
213 pending_ms = (int)(timeout_ms - elapsed_ms);
214 if(pending_ms <= 0) {
215 r = 0; /* Simulate a "call timed out" case */
228 if(readfd0 != CURL_SOCKET_BAD) {
229 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
230 ret |= CURL_CSELECT_IN;
231 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
232 ret |= CURL_CSELECT_ERR;
235 if(readfd1 != CURL_SOCKET_BAD) {
236 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
237 ret |= CURL_CSELECT_IN2;
238 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
239 ret |= CURL_CSELECT_ERR;
242 if(writefd != CURL_SOCKET_BAD) {
243 if(pfd[num].revents & (POLLWRNORM|POLLOUT))
244 ret |= CURL_CSELECT_OUT;
245 if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
246 ret |= CURL_CSELECT_ERR;
251 #else /* HAVE_POLL_FINE */
254 maxfd = (curl_socket_t)-1;
257 if(readfd0 != CURL_SOCKET_BAD) {
258 VERIFY_SOCK(readfd0);
259 FD_SET(readfd0, &fds_read);
260 FD_SET(readfd0, &fds_err);
263 if(readfd1 != CURL_SOCKET_BAD) {
264 VERIFY_SOCK(readfd1);
265 FD_SET(readfd1, &fds_read);
266 FD_SET(readfd1, &fds_err);
272 if(writefd != CURL_SOCKET_BAD) {
273 VERIFY_SOCK(writefd);
274 FD_SET(writefd, &fds_write);
275 FD_SET(writefd, &fds_err);
280 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
284 pending_tv.tv_sec = pending_ms / 1000;
285 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
287 else if(!timeout_ms) {
288 pending_tv.tv_sec = 0;
289 pending_tv.tv_usec = 0;
292 /* WinSock select() must not be called with an fd_set that contains zero
293 fd flags, or it will return WSAEINVAL. But, it also can't be called
294 with no fd_sets at all! From the documentation:
296 Any two of the parameters, readfds, writefds, or exceptfds, can be
297 given as null. At least one must be non-null, and any non-null
298 descriptor set must contain at least one handle to a socket.
300 We know that we have at least one bit set in at least two fd_sets in
301 this case, but we may have no bits set in either fds_read or fd_write,
302 so check for that and handle it. Luckily, with WinSock, we can _also_
303 ask how many bits are set on an fd_set.
305 It is unclear why WinSock doesn't just handle this for us instead of
306 calling this an error.
308 Note also that WinSock ignores the first argument, so we don't worry
309 about the fact that maxfd is computed incorrectly with WinSock (since
310 curl_socket_t is unsigned in such cases and thus -1 is the largest
313 r = select((int)maxfd + 1,
318 fds_read.fd_count ? &fds_read : NULL,
319 fds_write.fd_count ? &fds_write : NULL,
325 if(error && error_not_EINTR)
328 pending_ms = timeout_ms - elapsed_ms;
329 if(pending_ms <= 0) {
330 r = 0; /* Simulate a "call timed out" case */
342 if(readfd0 != CURL_SOCKET_BAD) {
343 if(FD_ISSET(readfd0, &fds_read))
344 ret |= CURL_CSELECT_IN;
345 if(FD_ISSET(readfd0, &fds_err))
346 ret |= CURL_CSELECT_ERR;
348 if(readfd1 != CURL_SOCKET_BAD) {
349 if(FD_ISSET(readfd1, &fds_read))
350 ret |= CURL_CSELECT_IN2;
351 if(FD_ISSET(readfd1, &fds_err))
352 ret |= CURL_CSELECT_ERR;
354 if(writefd != CURL_SOCKET_BAD) {
355 if(FD_ISSET(writefd, &fds_write))
356 ret |= CURL_CSELECT_OUT;
357 if(FD_ISSET(writefd, &fds_err))
358 ret |= CURL_CSELECT_ERR;
363 #endif /* HAVE_POLL_FINE */
368 * This is a wrapper around poll(). If poll() does not exist, then
369 * select() is used instead. An error is returned if select() is
370 * being used and a file descriptor is too large for FD_SETSIZE.
371 * A negative timeout value makes this function wait indefinitely,
372 * unles no valid file descriptor is given, when this happens the
373 * negative timeout is ignored and the function times out immediately.
376 * -1 = system call error or fd >= FD_SETSIZE
378 * N = number of structures with non zero revent fields
380 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
382 #ifndef HAVE_POLL_FINE
383 struct timeval pending_tv;
384 struct timeval *ptimeout;
390 struct timeval initial_tv = {0,0};
391 bool fds_none = TRUE;
398 for(i = 0; i < nfds; i++) {
399 if(ufds[i].fd != CURL_SOCKET_BAD) {
406 r = Curl_wait_ms(timeout_ms);
410 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
411 time in this function does not need to be measured. This happens
412 when function is called with a zero timeout or a negative timeout
413 value indicating a blocking call should be performed. */
416 pending_ms = timeout_ms;
417 initial_tv = curlx_tvnow();
420 #ifdef HAVE_POLL_FINE
427 r = poll(ufds, nfds, pending_ms);
431 if(error && error_not_EINTR)
434 pending_ms = timeout_ms - elapsed_ms;
445 for(i = 0; i < nfds; i++) {
446 if(ufds[i].fd == CURL_SOCKET_BAD)
448 if(ufds[i].revents & POLLHUP)
449 ufds[i].revents |= POLLIN;
450 if(ufds[i].revents & POLLERR)
451 ufds[i].revents |= (POLLIN|POLLOUT);
454 #else /* HAVE_POLL_FINE */
459 maxfd = (curl_socket_t)-1;
461 for(i = 0; i < nfds; i++) {
463 if(ufds[i].fd == CURL_SOCKET_BAD)
465 VERIFY_SOCK(ufds[i].fd);
466 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
467 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
468 if(ufds[i].fd > maxfd)
470 if(ufds[i].events & (POLLRDNORM|POLLIN))
471 FD_SET(ufds[i].fd, &fds_read);
472 if(ufds[i].events & (POLLWRNORM|POLLOUT))
473 FD_SET(ufds[i].fd, &fds_write);
474 if(ufds[i].events & (POLLRDBAND|POLLPRI))
475 FD_SET(ufds[i].fd, &fds_err);
480 /* WinSock select() can't handle zero events. See the comment about this in
481 Curl_check_socket(). */
482 if(fds_read.fd_count == 0 && fds_write.fd_count == 0
483 && fds_err.fd_count == 0) {
484 r = Curl_wait_ms(timeout_ms);
489 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
493 pending_tv.tv_sec = pending_ms / 1000;
494 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
496 else if(!timeout_ms) {
497 pending_tv.tv_sec = 0;
498 pending_tv.tv_usec = 0;
500 r = select((int)maxfd + 1,
502 &fds_read, &fds_write, &fds_err,
504 /* WinSock select() can't handle fd_sets with zero bits set, so
505 don't give it such arguments. See the comment about this in
508 fds_read.fd_count ? &fds_read : NULL,
509 fds_write.fd_count ? &fds_write : NULL,
510 fds_err.fd_count ? &fds_err : NULL,
516 if(error && error_not_EINTR)
519 pending_ms = timeout_ms - elapsed_ms;
531 for(i = 0; i < nfds; i++) {
533 if(ufds[i].fd == CURL_SOCKET_BAD)
535 if(FD_ISSET(ufds[i].fd, &fds_read))
536 ufds[i].revents |= POLLIN;
537 if(FD_ISSET(ufds[i].fd, &fds_write))
538 ufds[i].revents |= POLLOUT;
539 if(FD_ISSET(ufds[i].fd, &fds_err))
540 ufds[i].revents |= POLLPRI;
541 if(ufds[i].revents != 0)
545 #endif /* HAVE_POLL_FINE */
552 * This is a replacement for select() on the TPF platform.
553 * It is used whenever libcurl calls select().
554 * The call below to tpf_process_signals() is required because
555 * TPF's select calls are not signal interruptible.
557 * Return values are the same as select's.
559 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
560 fd_set* excepts, struct timeval* tv)
564 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
565 tpf_process_signals();