1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, 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 ***************************************************************************/
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 /* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1] */
51 #if defined(USE_WINSOCK) || defined(TPF)
52 #define VERIFY_SOCK(x) do { } while(0)
54 #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
55 #define VERIFY_SOCK(x) do { \
56 if(!VALID_SOCK(x)) { \
57 SET_SOCKERRNO(EINVAL); \
63 /* Convenience local macros */
65 #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
67 #ifdef CURL_ACKNOWLEDGE_EINTR
68 #define error_not_EINTR (1)
70 #define error_not_EINTR (error != EINTR)
74 * Internal function used for waiting a specific amount of ms
75 * in Curl_socket_ready() and Curl_poll() when no file descriptor
76 * is provided to wait on, just being used to delay execution.
77 * WinSock select() and poll() timeout mechanisms need a valid
78 * socket descriptor in a not null file descriptor set to work.
79 * Waiting indefinitely with this function is not allowed, a
80 * zero or negative timeout value will return immediately.
81 * Timeout resolution, accuracy, as well as maximum supported
82 * value is system dependent, neither factor is a citical issue
83 * for the intended use of this function in the library.
84 * On non-DOS and non-Winsock platforms, when compiled with
85 * CURL_ACKNOWLEDGE_EINTR defined, EINTR condition is honored
86 * and function might exit early without awaiting full timeout,
87 * otherwise EINTR will be ignored and full timeout will elapse.
90 * -1 = system call error, invalid timeout value, or interrupted
91 * 0 = specified timeout has elapsed
93 static int wait_ms(int timeout_ms)
95 #if !defined(MSDOS) && !defined(USE_WINSOCK)
96 #ifndef HAVE_POLL_FINE
97 struct timeval pending_tv;
99 struct timeval initial_tv;
108 SET_SOCKERRNO(EINVAL);
113 #elif defined(USE_WINSOCK)
116 pending_ms = timeout_ms;
117 initial_tv = curlx_tvnow();
119 #if defined(HAVE_POLL_FINE)
120 r = poll(NULL, 0, pending_ms);
122 pending_tv.tv_sec = pending_ms / 1000;
123 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
124 r = select(0, NULL, NULL, NULL, &pending_tv);
125 #endif /* HAVE_POLL_FINE */
129 if(error && error_not_EINTR)
131 pending_ms = timeout_ms - elapsed_ms;
135 #endif /* USE_WINSOCK */
142 * This is an internal function used for waiting for read or write
143 * events on a pair of file descriptors. It uses poll() when a fine
144 * poll() is available, in order to avoid limits with FD_SETSIZE,
145 * otherwise select() is used. An error is returned if select() is
146 * being used and a file descriptor is too large for FD_SETSIZE.
147 * A negative timeout value makes this function wait indefinitely,
148 * unles no valid file descriptor is given, when this happens the
149 * negative timeout is ignored and the function times out immediately.
150 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
151 * is honored and function might exit early without awaiting timeout,
152 * otherwise EINTR will be ignored.
155 * -1 = system call error or fd >= FD_SETSIZE
157 * CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
159 int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
162 #ifdef HAVE_POLL_FINE
163 struct pollfd pfd[2];
166 struct timeval pending_tv;
167 struct timeval *ptimeout;
173 struct timeval initial_tv = {0,0};
179 if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
180 r = wait_ms((int)timeout_ms);
184 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
185 time in this function does not need to be measured. This happens
186 when function is called with a zero timeout or a negative timeout
187 value indicating a blocking call should be performed. */
190 pending_ms = (int)timeout_ms;
191 initial_tv = curlx_tvnow();
194 #ifdef HAVE_POLL_FINE
197 if(readfd != CURL_SOCKET_BAD) {
198 pfd[num].fd = readfd;
199 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
200 pfd[num].revents = 0;
203 if(writefd != CURL_SOCKET_BAD) {
204 pfd[num].fd = writefd;
205 pfd[num].events = POLLWRNORM|POLLOUT;
206 pfd[num].revents = 0;
215 r = poll(pfd, num, pending_ms);
219 if(error && error_not_EINTR)
222 pending_ms = (int)(timeout_ms - elapsed_ms);
235 if(readfd != CURL_SOCKET_BAD) {
236 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
237 ret |= CURL_CSELECT_IN;
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(readfd != CURL_SOCKET_BAD) {
259 FD_SET(readfd, &fds_read);
260 FD_SET(readfd, &fds_err);
265 if(writefd != CURL_SOCKET_BAD) {
266 VERIFY_SOCK(writefd);
267 FD_SET(writefd, &fds_write);
268 FD_SET(writefd, &fds_err);
273 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
277 pending_tv.tv_sec = pending_ms / 1000;
278 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
280 else if(!timeout_ms) {
281 pending_tv.tv_sec = 0;
282 pending_tv.tv_usec = 0;
284 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
288 if(error && error_not_EINTR)
291 pending_ms = timeout_ms - elapsed_ms;
303 if(readfd != CURL_SOCKET_BAD) {
304 if(FD_ISSET(readfd, &fds_read))
305 ret |= CURL_CSELECT_IN;
306 if(FD_ISSET(readfd, &fds_err))
307 ret |= CURL_CSELECT_ERR;
309 if(writefd != CURL_SOCKET_BAD) {
310 if(FD_ISSET(writefd, &fds_write))
311 ret |= CURL_CSELECT_OUT;
312 if(FD_ISSET(writefd, &fds_err))
313 ret |= CURL_CSELECT_ERR;
318 #endif /* HAVE_POLL_FINE */
323 * This is a wrapper around poll(). If poll() does not exist, then
324 * select() is used instead. An error is returned if select() is
325 * being used and a file descriptor is too large for FD_SETSIZE.
326 * A negative timeout value makes this function wait indefinitely,
327 * unles no valid file descriptor is given, when this happens the
328 * negative timeout is ignored and the function times out immediately.
329 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
330 * is honored and function might exit early without awaiting timeout,
331 * otherwise EINTR will be ignored.
334 * -1 = system call error or fd >= FD_SETSIZE
336 * N = number of structures with non zero revent fields
338 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
340 #ifndef HAVE_POLL_FINE
341 struct timeval pending_tv;
342 struct timeval *ptimeout;
348 struct timeval initial_tv = {0,0};
349 bool fds_none = TRUE;
356 for(i = 0; i < nfds; i++) {
357 if(ufds[i].fd != CURL_SOCKET_BAD) {
364 r = wait_ms((int)timeout_ms);
368 /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
369 time in this function does not need to be measured. This happens
370 when function is called with a zero timeout or a negative timeout
371 value indicating a blocking call should be performed. */
374 pending_ms = timeout_ms;
375 initial_tv = curlx_tvnow();
378 #ifdef HAVE_POLL_FINE
385 r = poll(ufds, nfds, pending_ms);
389 if(error && error_not_EINTR)
392 pending_ms = timeout_ms - elapsed_ms;
403 for(i = 0; i < nfds; i++) {
404 if(ufds[i].fd == CURL_SOCKET_BAD)
406 if(ufds[i].revents & POLLHUP)
407 ufds[i].revents |= POLLIN;
408 if(ufds[i].revents & POLLERR)
409 ufds[i].revents |= (POLLIN|POLLOUT);
412 #else /* HAVE_POLL_FINE */
417 maxfd = (curl_socket_t)-1;
419 for(i = 0; i < nfds; i++) {
421 if(ufds[i].fd == CURL_SOCKET_BAD)
423 VERIFY_SOCK(ufds[i].fd);
424 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
425 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
426 if(ufds[i].fd > maxfd)
428 if(ufds[i].events & (POLLRDNORM|POLLIN))
429 FD_SET(ufds[i].fd, &fds_read);
430 if(ufds[i].events & (POLLWRNORM|POLLOUT))
431 FD_SET(ufds[i].fd, &fds_write);
432 if(ufds[i].events & (POLLRDBAND|POLLPRI))
433 FD_SET(ufds[i].fd, &fds_err);
437 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
441 pending_tv.tv_sec = pending_ms / 1000;
442 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
444 else if(!timeout_ms) {
445 pending_tv.tv_sec = 0;
446 pending_tv.tv_usec = 0;
448 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
452 if(error && error_not_EINTR)
455 pending_ms = timeout_ms - elapsed_ms;
467 for(i = 0; i < nfds; i++) {
469 if(ufds[i].fd == CURL_SOCKET_BAD)
471 if(FD_ISSET(ufds[i].fd, &fds_read))
472 ufds[i].revents |= POLLIN;
473 if(FD_ISSET(ufds[i].fd, &fds_write))
474 ufds[i].revents |= POLLOUT;
475 if(FD_ISSET(ufds[i].fd, &fds_err))
476 ufds[i].revents |= POLLPRI;
477 if(ufds[i].revents != 0)
481 #endif /* HAVE_POLL_FINE */
488 * This is a replacement for select() on the TPF platform.
489 * It is used whenever libcurl calls select().
490 * The call below to tpf_process_signals() is required because
491 * TPF's select calls are not signal interruptible.
493 * Return values are the same as select's.
495 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
496 fd_set* excepts, struct timeval* tv)
500 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
501 tpf_process_signals();