1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2007, 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.
22 ***************************************************************************/
26 #ifdef HAVE_SYS_SELECT_H
27 #include <sys/select.h>
29 #ifdef HAVE_SYS_TIME_H
33 #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
34 #error "We can't compile without select() or poll() support."
38 /* BeOS has FD_SET defined in socket.h */
43 #include <dos.h> /* delay() */
46 #include <curl/curl.h>
52 /* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1] */
54 #if defined(USE_WINSOCK) || defined(TPF)
55 #define VERIFY_SOCK(x) do { } while (0)
56 #define VERIFY_NFDS(x) do { } while (0)
58 #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
59 #define VERIFY_SOCK(x) do { \
60 if(!VALID_SOCK(x)) { \
61 SET_SOCKERRNO(EINVAL); \
65 #define VALID_NFDS(n) (((n) >= 0) && ((n) <= FD_SETSIZE))
66 #define VERIFY_NFDS(x) do { \
67 if(!VALID_NFDS(x)) { \
68 SET_SOCKERRNO(EINVAL); \
74 /* Convenience local macros */
76 #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
78 #ifdef CURL_ACKNOWLEDGE_EINTR
79 #define error_is_EINTR (error == EINTR)
81 #define error_is_EINTR (0)
84 #define SMALL_POLLNFDS 0x20
87 * Internal function used for waiting a specific amount of ms
88 * in Curl_socket_ready() and Curl_poll() when no file descriptor
89 * is provided to wait on, just being used to delay execution.
90 * WinSock select() and poll() timeout mechanisms need a valid
91 * socket descriptor in a not null file descriptor set to work.
92 * Waiting indefinitely with this function is not allowed, a
93 * zero or negative timeout value will return immediately.
94 * Timeout resolution, accuracy, as well as maximum supported
95 * value is system dependant, neither factor is a citical issue
96 * for the intended use of this function in the library.
97 * On non-DOS and non-Winsock platforms, when compiled with
98 * CURL_ACKNOWLEDGE_EINTR defined, EINTR condition is honored
99 * and function might exit early without awaiting full timeout,
100 * otherwise EINTR will be ignored and full timeout will elapse.
103 * -1 = system call error, invalid timeout value, or interrupted
104 * 0 = specified timeout has elapsed
106 static int wait_ms(int timeout_ms)
108 #if !defined(MSDOS) && !defined(USE_WINSOCK)
109 #ifndef HAVE_POLL_FINE
110 struct timeval pending_tv;
112 struct timeval initial_tv;
120 if (timeout_ms < 0) {
121 SET_SOCKERRNO(EINVAL);
126 #elif defined(USE_WINSOCK)
129 pending_ms = timeout_ms;
130 initial_tv = curlx_tvnow();
132 #if defined(HAVE_POLL_FINE)
133 r = poll(NULL, 0, pending_ms);
135 pending_tv.tv_sec = pending_ms / 1000;
136 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
137 r = select(0, NULL, NULL, NULL, &pending_tv);
138 #endif /* HAVE_POLL_FINE */
142 if ((error == EINVAL) || error_is_EINTR)
144 pending_ms = timeout_ms - elapsed_ms;
148 #endif /* USE_WINSOCK */
155 * This is an internal function used for waiting for read or write
156 * events on a pair of file descriptors. It uses poll() when a fine
157 * poll() is available, in order to avoid limits with FD_SETSIZE,
158 * otherwise select() is used. An error is returned if select() is
159 * being used and a file descriptor is too large for FD_SETSIZE.
160 * A negative timeout value makes this function wait indefinitely,
161 * unles no valid file descriptor is given, when this happens the
162 * negative timeout is ignored and the function times out immediately.
163 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
164 * is honored and function might exit early without awaiting timeout,
165 * otherwise EINTR will be ignored.
168 * -1 = system call error or fd >= FD_SETSIZE
170 * CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
172 int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
175 #ifdef HAVE_POLL_FINE
176 struct pollfd pfd[2];
179 struct timeval pending_tv;
180 struct timeval *ptimeout;
186 struct timeval initial_tv;
192 if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
193 r = wait_ms(timeout_ms);
197 /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
198 time in this function does not need to be measured. This happens
199 when function is called with a zero timeout or a negative timeout
200 value indicating a blocking call should be performed. */
202 if (timeout_ms > 0) {
203 pending_ms = timeout_ms;
204 initial_tv = curlx_tvnow();
207 #ifdef HAVE_POLL_FINE
210 if (readfd != CURL_SOCKET_BAD) {
211 pfd[num].fd = readfd;
212 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
213 pfd[num].revents = 0;
216 if (writefd != CURL_SOCKET_BAD) {
217 pfd[num].fd = writefd;
218 pfd[num].events = POLLWRNORM|POLLOUT;
219 pfd[num].revents = 0;
226 else if (!timeout_ms)
228 r = poll(pfd, num, pending_ms);
232 if ((error == EINVAL) || error_is_EINTR)
234 if (timeout_ms > 0) {
235 pending_ms = timeout_ms - elapsed_ms;
248 if (readfd != CURL_SOCKET_BAD) {
249 if (pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
250 ret |= CURL_CSELECT_IN;
251 if (pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
252 ret |= CURL_CSELECT_ERR;
255 if (writefd != CURL_SOCKET_BAD) {
256 if (pfd[num].revents & (POLLWRNORM|POLLOUT))
257 ret |= CURL_CSELECT_OUT;
258 if (pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
259 ret |= CURL_CSELECT_ERR;
264 #else /* HAVE_POLL_FINE */
267 maxfd = (curl_socket_t)-1;
270 if (readfd != CURL_SOCKET_BAD) {
272 FD_SET(readfd, &fds_read);
273 FD_SET(readfd, &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;
289 if (timeout_ms > 0) {
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;
297 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
301 if ((error == EINVAL) || (error == EBADF) || error_is_EINTR)
303 if (timeout_ms > 0) {
304 pending_ms = timeout_ms - elapsed_ms;
316 if (readfd != CURL_SOCKET_BAD) {
317 if (FD_ISSET(readfd, &fds_read))
318 ret |= CURL_CSELECT_IN;
319 if (FD_ISSET(readfd, &fds_err))
320 ret |= CURL_CSELECT_ERR;
322 if (writefd != CURL_SOCKET_BAD) {
323 if (FD_ISSET(writefd, &fds_write))
324 ret |= CURL_CSELECT_OUT;
325 if (FD_ISSET(writefd, &fds_err))
326 ret |= CURL_CSELECT_ERR;
331 #endif /* HAVE_POLL_FINE */
336 * This is a wrapper around poll(). If poll() does not exist, then
337 * select() is used instead. An error is returned if select() is
338 * being used and a file descriptor is too large for FD_SETSIZE.
339 * A negative timeout value makes this function wait indefinitely,
340 * unles no valid file descriptor is given, when this happens the
341 * negative timeout is ignored and the function times out immediately.
342 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
343 * is honored and function might exit early without awaiting timeout,
344 * otherwise EINTR will be ignored.
347 * -1 = system call error or fd >= FD_SETSIZE
349 * N = number of structures with non zero revent fields
351 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
353 #ifndef HAVE_POLL_FINE
354 struct timeval pending_tv;
355 struct timeval *ptimeout;
361 struct timeval initial_tv;
362 bool fds_none = TRUE;
369 for (i = 0; i < nfds; i++) {
370 if (ufds[i].fd != CURL_SOCKET_BAD) {
377 r = wait_ms(timeout_ms);
381 /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
382 time in this function does not need to be measured. This happens
383 when function is called with a zero timeout or a negative timeout
384 value indicating a blocking call should be performed. */
386 if (timeout_ms > 0) {
387 pending_ms = timeout_ms;
388 initial_tv = curlx_tvnow();
391 #ifdef HAVE_POLL_FINE
396 else if (!timeout_ms)
398 r = poll(ufds, nfds, pending_ms);
402 if ((error == EINVAL) || error_is_EINTR)
404 if (timeout_ms > 0) {
405 pending_ms = timeout_ms - elapsed_ms;
411 #else /* HAVE_POLL_FINE */
416 maxfd = (curl_socket_t)-1;
418 for (i = 0; i < nfds; i++) {
420 if (ufds[i].fd == CURL_SOCKET_BAD)
422 VERIFY_SOCK(ufds[i].fd);
423 if (ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
424 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
425 if (ufds[i].fd > maxfd)
427 if (ufds[i].events & (POLLRDNORM|POLLIN))
428 FD_SET(ufds[i].fd, &fds_read);
429 if (ufds[i].events & (POLLWRNORM|POLLOUT))
430 FD_SET(ufds[i].fd, &fds_write);
431 if (ufds[i].events & (POLLRDBAND|POLLPRI))
432 FD_SET(ufds[i].fd, &fds_err);
436 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
439 if (timeout_ms > 0) {
440 pending_tv.tv_sec = pending_ms / 1000;
441 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
443 else if (!timeout_ms) {
444 pending_tv.tv_sec = 0;
445 pending_tv.tv_usec = 0;
447 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
451 if ((error == EINVAL) || (error == EBADF) || error_is_EINTR)
453 if (timeout_ms > 0) {
454 pending_ms = timeout_ms - elapsed_ms;
466 for (i = 0; i < nfds; i++) {
468 if (ufds[i].fd == CURL_SOCKET_BAD)
470 if (FD_ISSET(ufds[i].fd, &fds_read))
471 ufds[i].revents |= POLLIN;
472 if (FD_ISSET(ufds[i].fd, &fds_write))
473 ufds[i].revents |= POLLOUT;
474 if (FD_ISSET(ufds[i].fd, &fds_err))
475 ufds[i].revents |= POLLPRI;
476 if (ufds[i].revents != 0)
480 #endif /* HAVE_POLL_FINE */
486 * This is a wrapper around select(). It uses poll() when a fine
487 * poll() is available, in order to avoid limits with FD_SETSIZE,
488 * otherwise select() is used. An error is returned if select() is
489 * being used and a the number of file descriptors is larger than
490 * FD_SETSIZE. A NULL timeout pointer makes this function wait
491 * indefinitely, unles no valid file descriptor is given, when this
492 * happens the NULL timeout is ignored and the function times out
493 * immediately. When compiled with CURL_ACKNOWLEDGE_EINTR defined,
494 * EINTR condition is honored and function might exit early without
495 * awaiting timeout, otherwise EINTR will be ignored.
498 * -1 = system call error or nfds > FD_SETSIZE
500 * N = number of file descriptors kept in file descriptor sets.
502 int Curl_select(int nfds,
503 fd_set *fds_read, fd_set *fds_write, fd_set *fds_excep,
504 struct timeval *timeout)
506 struct timeval initial_tv;
511 #ifdef HAVE_POLL_FINE
512 struct pollfd small_fds[SMALL_POLLNFDS];
513 struct pollfd *poll_fds;
518 struct timeval pending_tv;
519 struct timeval *ptimeout;
524 ((nfds > 0) && (!fds_read && !fds_write && !fds_excep))) {
525 SET_SOCKERRNO(EINVAL);
530 if ((timeout->tv_sec < 0) ||
531 (timeout->tv_usec < 0) ||
532 (timeout->tv_usec >= 1000000)) {
533 SET_SOCKERRNO(EINVAL);
536 timeout_ms = (int)(timeout->tv_sec * 1000) +
537 (int)(timeout->tv_usec / 1000);
543 if ((!nfds) || (!fds_read && !fds_write && !fds_excep)) {
544 r = wait_ms(timeout_ms);
548 /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
549 time in this function does not need to be measured. This happens
550 when function is called with a zero timeout in the timeval struct
551 referenced argument or when a NULL pointer is received as timeval
552 reference indicating a blocking call should be performed. */
554 if (timeout_ms > 0) {
555 pending_ms = timeout_ms;
556 initial_tv = curlx_tvnow();
559 #ifdef HAVE_POLL_FINE
561 if (fds_read || fds_write || fds_excep) {
564 if ((fds_read && (0 != FD_ISSET(fd, fds_read))) ||
565 (fds_write && (0 != FD_ISSET(fd, fds_write))) ||
566 (fds_excep && (0 != FD_ISSET(fd, fds_excep))))
573 else if (poll_nfds <= SMALL_POLLNFDS)
574 poll_fds = small_fds;
576 poll_fds = malloc(poll_nfds * sizeof(struct pollfd));
578 SET_SOCKERRNO(ENOBUFS);
589 if (fds_read && (0 != FD_ISSET(fd, fds_read)))
590 events |= (POLLRDNORM|POLLIN);
591 if (fds_write && (0 != FD_ISSET(fd, fds_write)))
592 events |= (POLLWRNORM|POLLOUT);
593 if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
594 events |= (POLLRDBAND|POLLPRI);
596 poll_fds[ix].events = events;
597 poll_fds[ix].fd = fd;
598 poll_fds[ix].revents = 0;
601 /* since we know this is the total amount of descriptors with
602 interesting actions, we can skip the rest of the loop at this
612 else if (!timeout_ms)
614 r = poll(poll_fds, poll_nfds, pending_ms);
618 if ((error == EINVAL) || error_is_EINTR)
620 if (timeout_ms > 0) {
621 pending_ms = timeout_ms - elapsed_ms;
633 if (poll_fds[ix].revents & POLLNVAL) {
634 SET_SOCKERRNO(EBADF);
644 if (fds_read && (0 != FD_ISSET(poll_fds[ix].fd, fds_read))) {
645 if (0 == (poll_fds[ix].revents & (POLLRDNORM|POLLERR|POLLHUP|POLLIN)))
646 FD_CLR(poll_fds[ix].fd, fds_read);
650 if (fds_write && (0 != FD_ISSET(poll_fds[ix].fd, fds_write))) {
651 if (0 == (poll_fds[ix].revents & (POLLWRNORM|POLLERR|POLLHUP|POLLOUT)))
652 FD_CLR(poll_fds[ix].fd, fds_write);
656 if (fds_excep && (0 != FD_ISSET(poll_fds[ix].fd, fds_excep))) {
657 if (0 == (poll_fds[ix].revents & (POLLRDBAND|POLLERR|POLLHUP|POLLPRI)))
658 FD_CLR(poll_fds[ix].fd, fds_excep);
665 if (poll_fds && (poll_nfds > SMALL_POLLNFDS))
668 #else /* HAVE_POLL_FINE */
672 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
675 if (timeout_ms > 0) {
676 pending_tv.tv_sec = pending_ms / 1000;
677 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
679 else if (!timeout_ms) {
680 pending_tv.tv_sec = 0;
681 pending_tv.tv_usec = 0;
683 r = select(nfds, fds_read, fds_write, fds_excep, ptimeout);
687 if ((error == EINVAL) || (error == EBADF) || error_is_EINTR)
689 if (timeout_ms > 0) {
690 pending_ms = timeout_ms - elapsed_ms;
701 #endif /* HAVE_POLL_FINE */
708 * This is a replacement for select() on the TPF platform.
709 * It is used whenever libcurl calls select().
710 * The call below to tpf_process_signals() is required because
711 * TPF's select calls are not signal interruptible.
713 * Return values are the same as select's.
715 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
716 fd_set* excepts, struct timeval* tv)
720 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
721 tpf_process_signals();