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_not_EINTR (error != EINTR)
81 #define error_not_EINTR (1)
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 */
139 } while ((r == -1) && (error = SOCKERRNO) &&
140 (error != EINVAL) && error_not_EINTR &&
141 ((pending_ms = timeout_ms - elapsed_ms) > 0));
142 #endif /* USE_WINSOCK */
149 * This is an internal function used for waiting for read or write
150 * events on a pair of file descriptors. It uses poll() when a fine
151 * poll() is available, in order to avoid limits with FD_SETSIZE,
152 * otherwise select() is used. An error is returned if select() is
153 * being used and a file descriptor is too large for FD_SETSIZE.
154 * A negative timeout value makes this function wait indefinitely,
155 * unles no valid file descriptor is given, when this happens the
156 * negative timeout is ignored and the function times out immediately.
157 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
158 * is honored and function might exit early without awaiting timeout,
159 * otherwise EINTR will be ignored.
162 * -1 = system call error or fd >= FD_SETSIZE
164 * CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
166 int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
169 #ifdef HAVE_POLL_FINE
170 struct pollfd pfd[2];
173 struct timeval pending_tv;
174 struct timeval *ptimeout;
180 struct timeval initial_tv;
186 if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
187 r = wait_ms(timeout_ms);
191 pending_ms = timeout_ms;
192 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;
213 r = poll(pfd, num, pending_ms);
214 } while ((r == -1) && (error = SOCKERRNO) &&
215 (error != EINVAL) && error_not_EINTR &&
216 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
225 if (readfd != CURL_SOCKET_BAD) {
226 if (pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
227 ret |= CURL_CSELECT_IN;
228 if (pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
229 ret |= CURL_CSELECT_ERR;
232 if (writefd != CURL_SOCKET_BAD) {
233 if (pfd[num].revents & (POLLWRNORM|POLLOUT))
234 ret |= CURL_CSELECT_OUT;
235 if (pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
236 ret |= CURL_CSELECT_ERR;
241 #else /* HAVE_POLL_FINE */
244 maxfd = (curl_socket_t)-1;
247 if (readfd != CURL_SOCKET_BAD) {
249 FD_SET(readfd, &fds_read);
250 FD_SET(readfd, &fds_err);
255 if (writefd != CURL_SOCKET_BAD) {
256 VERIFY_SOCK(writefd);
257 FD_SET(writefd, &fds_write);
258 FD_SET(writefd, &fds_err);
263 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
267 pending_tv.tv_sec = pending_ms / 1000;
268 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
270 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
271 } while ((r == -1) && (error = SOCKERRNO) &&
272 (error != EINVAL) && (error != EBADF) && error_not_EINTR &&
273 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
281 if (readfd != CURL_SOCKET_BAD) {
282 if (FD_ISSET(readfd, &fds_read))
283 ret |= CURL_CSELECT_IN;
284 if (FD_ISSET(readfd, &fds_err))
285 ret |= CURL_CSELECT_ERR;
287 if (writefd != CURL_SOCKET_BAD) {
288 if (FD_ISSET(writefd, &fds_write))
289 ret |= CURL_CSELECT_OUT;
290 if (FD_ISSET(writefd, &fds_err))
291 ret |= CURL_CSELECT_ERR;
296 #endif /* HAVE_POLL_FINE */
301 * This is a wrapper around poll(). If poll() does not exist, then
302 * select() is used instead. An error is returned if select() is
303 * being used and a file descriptor is too large for FD_SETSIZE.
304 * A negative timeout value makes this function wait indefinitely,
305 * unles no valid file descriptor is given, when this happens the
306 * negative timeout is ignored and the function times out immediately.
307 * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
308 * is honored and function might exit early without awaiting timeout,
309 * otherwise EINTR will be ignored.
312 * -1 = system call error or fd >= FD_SETSIZE
314 * N = number of structures with non zero revent fields
316 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
318 #ifndef HAVE_POLL_FINE
319 struct timeval pending_tv;
320 struct timeval *ptimeout;
326 struct timeval initial_tv;
327 bool fds_none = TRUE;
334 for (i = 0; i < nfds; i++) {
335 if (ufds[i].fd != CURL_SOCKET_BAD) {
342 r = wait_ms(timeout_ms);
346 pending_ms = timeout_ms;
347 initial_tv = curlx_tvnow();
349 #ifdef HAVE_POLL_FINE
354 r = poll(ufds, nfds, pending_ms);
355 } while ((r == -1) && (error = SOCKERRNO) &&
356 (error != EINVAL) && error_not_EINTR &&
357 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
359 #else /* HAVE_POLL_FINE */
364 maxfd = (curl_socket_t)-1;
366 for (i = 0; i < nfds; i++) {
368 if (ufds[i].fd == CURL_SOCKET_BAD)
370 VERIFY_SOCK(ufds[i].fd);
371 if (ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
372 POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
373 if (ufds[i].fd > maxfd)
375 if (ufds[i].events & (POLLRDNORM|POLLIN))
376 FD_SET(ufds[i].fd, &fds_read);
377 if (ufds[i].events & (POLLWRNORM|POLLOUT))
378 FD_SET(ufds[i].fd, &fds_write);
379 if (ufds[i].events & (POLLRDBAND|POLLPRI))
380 FD_SET(ufds[i].fd, &fds_err);
384 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
388 pending_tv.tv_sec = pending_ms / 1000;
389 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
391 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
392 } while ((r == -1) && (error = SOCKERRNO) &&
393 (error != EINVAL) && (error != EBADF) && error_not_EINTR &&
394 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
402 for (i = 0; i < nfds; i++) {
404 if (ufds[i].fd == CURL_SOCKET_BAD)
406 if (FD_ISSET(ufds[i].fd, &fds_read))
407 ufds[i].revents |= POLLIN;
408 if (FD_ISSET(ufds[i].fd, &fds_write))
409 ufds[i].revents |= POLLOUT;
410 if (FD_ISSET(ufds[i].fd, &fds_err))
411 ufds[i].revents |= POLLPRI;
412 if (ufds[i].revents != 0)
416 #endif /* HAVE_POLL_FINE */
422 * This is a wrapper around select(). It uses poll() when a fine
423 * poll() is available, in order to avoid limits with FD_SETSIZE,
424 * otherwise select() is used. An error is returned if select() is
425 * being used and a the number of file descriptors is larger than
426 * FD_SETSIZE. A NULL timeout pointer makes this function wait
427 * indefinitely, unles no valid file descriptor is given, when this
428 * happens the NULL timeout is ignored and the function times out
429 * immediately. When compiled with CURL_ACKNOWLEDGE_EINTR defined,
430 * EINTR condition is honored and function might exit early without
431 * awaiting timeout, otherwise EINTR will be ignored.
434 * -1 = system call error or nfds > FD_SETSIZE
436 * N = number of file descriptors kept in file descriptor sets.
438 int Curl_select(int nfds,
439 fd_set *fds_read, fd_set *fds_write, fd_set *fds_excep,
440 struct timeval *timeout)
442 struct timeval initial_tv;
447 #ifdef HAVE_POLL_FINE
448 struct pollfd small_fds[SMALL_POLLNFDS];
449 struct pollfd *poll_fds;
454 struct timeval pending_tv;
455 struct timeval *ptimeout;
460 ((nfds > 0) && (!fds_read && !fds_write && !fds_excep))) {
461 SET_SOCKERRNO(EINVAL);
466 if ((timeout->tv_sec < 0) ||
467 (timeout->tv_usec < 0) ||
468 (timeout->tv_usec >= 1000000)) {
469 SET_SOCKERRNO(EINVAL);
472 timeout_ms = (int)(timeout->tv_sec * 1000) +
473 (int)(timeout->tv_usec / 1000);
479 if ((!nfds) || (!fds_read && !fds_write && !fds_excep)) {
480 r = wait_ms(timeout_ms);
484 pending_ms = timeout_ms;
485 initial_tv = curlx_tvnow();
487 #ifdef HAVE_POLL_FINE
489 if (fds_read || fds_write || fds_excep) {
492 if ((fds_read && (0 != FD_ISSET(fd, fds_read))) ||
493 (fds_write && (0 != FD_ISSET(fd, fds_write))) ||
494 (fds_excep && (0 != FD_ISSET(fd, fds_excep))))
501 else if (poll_nfds <= SMALL_POLLNFDS)
502 poll_fds = small_fds;
504 poll_fds = calloc((size_t)poll_nfds, sizeof(struct pollfd));
506 SET_SOCKERRNO(ENOBUFS);
515 poll_fds[ix].events = 0;
516 if (fds_read && (0 != FD_ISSET(fd, fds_read)))
517 poll_fds[ix].events |= (POLLRDNORM|POLLIN);
518 if (fds_write && (0 != FD_ISSET(fd, fds_write)))
519 poll_fds[ix].events |= (POLLWRNORM|POLLOUT);
520 if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
521 poll_fds[ix].events |= (POLLRDBAND|POLLPRI);
522 if (poll_fds[ix].events) {
523 poll_fds[ix].fd = fd;
524 poll_fds[ix].revents = 0;
533 r = poll(poll_fds, poll_nfds, pending_ms);
534 } while ((r == -1) && (error = SOCKERRNO) &&
535 (error != EINVAL) && error_not_EINTR &&
536 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
544 if (poll_fds[ix].revents & POLLNVAL) {
545 SET_SOCKERRNO(EBADF);
555 if (fds_read && (0 != FD_ISSET(poll_fds[ix].fd, fds_read))) {
556 if (0 == (poll_fds[ix].revents & (POLLRDNORM|POLLERR|POLLHUP|POLLIN)))
557 FD_CLR(poll_fds[ix].fd, fds_read);
561 if (fds_write && (0 != FD_ISSET(poll_fds[ix].fd, fds_write))) {
562 if (0 == (poll_fds[ix].revents & (POLLWRNORM|POLLERR|POLLHUP|POLLOUT)))
563 FD_CLR(poll_fds[ix].fd, fds_write);
567 if (fds_excep && (0 != FD_ISSET(poll_fds[ix].fd, fds_excep))) {
568 if (0 == (poll_fds[ix].revents & (POLLRDBAND|POLLERR|POLLHUP|POLLPRI)))
569 FD_CLR(poll_fds[ix].fd, fds_excep);
576 if (poll_fds && (poll_nfds > SMALL_POLLNFDS))
579 #else /* HAVE_POLL_FINE */
583 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
587 pending_tv.tv_sec = pending_ms / 1000;
588 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
590 r = select(nfds, fds_read, fds_write, fds_excep, ptimeout);
591 } while ((r == -1) && (error = SOCKERRNO) &&
592 (error != EINVAL) && (error != EBADF) && error_not_EINTR &&
593 ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0)));
600 #endif /* HAVE_POLL_FINE */
607 * This is a replacement for select() on the TPF platform.
608 * It is used whenever libcurl calls select().
609 * The call below to tpf_process_signals() is required because
610 * TPF's select calls are not signal interruptible.
612 * Return values are the same as select's.
614 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
615 fd_set* excepts, struct timeval* tv)
619 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
620 tpf_process_signals();