1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
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.
13 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#ifdef HAVE_SYS_SELECT_H
26#include <sys/select.h>
27#endif
28
29#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
30#error "We can't compile without select() or poll() support."
31#endif
32
33#if defined(__BEOS__) && !defined(__HAIKU__)
34/* BeOS has FD_SET defined in socket.h */
35#include <socket.h>
36#endif
37
38#ifdef MSDOS
39#include <dos.h>  /* delay() */
40#endif
41
42#include <curl/curl.h>
43
44#include "urldata.h"
45#include "connect.h"
46#include "select.h"
47#include "warnless.h"
48
49/* Convenience local macros */
50
51#define elapsed_ms  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
52
53int Curl_ack_eintr = 0;
54#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
55
56/*
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.
67 *
68 * Return values:
69 *   -1 = system call error, invalid timeout value, or interrupted
70 *    0 = specified timeout has elapsed
71 */
72int Curl_wait_ms(int timeout_ms)
73{
74#if !defined(MSDOS) && !defined(USE_WINSOCK)
75#ifndef HAVE_POLL_FINE
76  struct timeval pending_tv;
77#endif
78  struct timeval initial_tv;
79  int pending_ms;
80  int error;
81#endif
82  int r = 0;
83
84  if(!timeout_ms)
85    return 0;
86  if(timeout_ms < 0) {
87    SET_SOCKERRNO(EINVAL);
88    return -1;
89  }
90#if defined(MSDOS)
91  delay(timeout_ms);
92#elif defined(USE_WINSOCK)
93  Sleep(timeout_ms);
94#else
95  pending_ms = timeout_ms;
96  initial_tv = curlx_tvnow();
97  do {
98#if defined(HAVE_POLL_FINE)
99    r = poll(NULL, 0, pending_ms);
100#else
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 */
105    if(r != -1)
106      break;
107    error = SOCKERRNO;
108    if(error && error_not_EINTR)
109      break;
110    pending_ms = timeout_ms - elapsed_ms;
111    if(pending_ms <= 0)
112      break;
113  } while(r == -1);
114#endif /* USE_WINSOCK */
115  if(r)
116    r = -1;
117  return r;
118}
119
120/*
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.
125 *
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.
129 *
130 * Return values:
131 *   -1 = system call error or fd >= FD_SETSIZE
132 *    0 = timeout
133 *    [bitmask] = action as described below
134 *
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
139 */
140int 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 */
144{
145#ifdef HAVE_POLL_FINE
146  struct pollfd pfd[3];
147  int num;
148#else
149  struct timeval pending_tv;
150  struct timeval *ptimeout;
151  fd_set fds_read;
152  fd_set fds_write;
153  fd_set fds_err;
154  curl_socket_t maxfd;
155#endif
156  struct timeval initial_tv = {0,0};
157  int pending_ms = 0;
158  int error;
159  int r;
160  int ret;
161
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);
166    return r;
167  }
168
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. */
173
174  if(timeout_ms > 0) {
175    pending_ms = (int)timeout_ms;
176    initial_tv = curlx_tvnow();
177  }
178
179#ifdef HAVE_POLL_FINE
180
181  num = 0;
182  if(readfd0 != CURL_SOCKET_BAD) {
183    pfd[num].fd = readfd0;
184    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
185    pfd[num].revents = 0;
186    num++;
187  }
188  if(readfd1 != CURL_SOCKET_BAD) {
189    pfd[num].fd = readfd1;
190    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
191    pfd[num].revents = 0;
192    num++;
193  }
194  if(writefd != CURL_SOCKET_BAD) {
195    pfd[num].fd = writefd;
196    pfd[num].events = POLLWRNORM|POLLOUT;
197    pfd[num].revents = 0;
198    num++;
199  }
200
201  do {
202    if(timeout_ms < 0)
203      pending_ms = -1;
204    else if(!timeout_ms)
205      pending_ms = 0;
206    r = poll(pfd, num, pending_ms);
207    if(r != -1)
208      break;
209    error = SOCKERRNO;
210    if(error && error_not_EINTR)
211      break;
212    if(timeout_ms > 0) {
213      pending_ms = (int)(timeout_ms - elapsed_ms);
214      if(pending_ms <= 0) {
215        r = 0;  /* Simulate a "call timed out" case */
216        break;
217      }
218    }
219  } while(r == -1);
220
221  if(r < 0)
222    return -1;
223  if(r == 0)
224    return 0;
225
226  ret = 0;
227  num = 0;
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;
233    num++;
234  }
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;
240    num++;
241  }
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;
247  }
248
249  return ret;
250
251#else  /* HAVE_POLL_FINE */
252
253  FD_ZERO(&fds_err);
254  maxfd = (curl_socket_t)-1;
255
256  FD_ZERO(&fds_read);
257  if(readfd0 != CURL_SOCKET_BAD) {
258    VERIFY_SOCK(readfd0);
259    FD_SET(readfd0, &fds_read);
260    FD_SET(readfd0, &fds_err);
261    maxfd = readfd0;
262  }
263  if(readfd1 != CURL_SOCKET_BAD) {
264    VERIFY_SOCK(readfd1);
265    FD_SET(readfd1, &fds_read);
266    FD_SET(readfd1, &fds_err);
267    if(readfd1 > maxfd)
268      maxfd = readfd1;
269  }
270
271  FD_ZERO(&fds_write);
272  if(writefd != CURL_SOCKET_BAD) {
273    VERIFY_SOCK(writefd);
274    FD_SET(writefd, &fds_write);
275    FD_SET(writefd, &fds_err);
276    if(writefd > maxfd)
277      maxfd = writefd;
278  }
279
280  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
281
282  do {
283    if(timeout_ms > 0) {
284      pending_tv.tv_sec = pending_ms / 1000;
285      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
286    }
287    else if(!timeout_ms) {
288      pending_tv.tv_sec = 0;
289      pending_tv.tv_usec = 0;
290    }
291
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:
295
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.
299
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.
304
305       It is unclear why WinSock doesn't just handle this for us instead of
306       calling this an error.
307
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
311       value).
312    */
313    r = select((int)maxfd + 1,
314#ifndef USE_WINSOCK
315               &fds_read,
316               &fds_write,
317#else
318               fds_read.fd_count ? &fds_read : NULL,
319               fds_write.fd_count ? &fds_write : NULL,
320#endif
321               &fds_err, ptimeout);
322    if(r != -1)
323      break;
324    error = SOCKERRNO;
325    if(error && error_not_EINTR)
326      break;
327    if(timeout_ms > 0) {
328      pending_ms = timeout_ms - elapsed_ms;
329      if(pending_ms <= 0) {
330        r = 0;  /* Simulate a "call timed out" case */
331        break;
332      }
333    }
334  } while(r == -1);
335
336  if(r < 0)
337    return -1;
338  if(r == 0)
339    return 0;
340
341  ret = 0;
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;
347  }
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;
353  }
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;
359  }
360
361  return ret;
362
363#endif  /* HAVE_POLL_FINE */
364
365}
366
367/*
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.
374 *
375 * Return values:
376 *   -1 = system call error or fd >= FD_SETSIZE
377 *    0 = timeout
378 *    N = number of structures with non zero revent fields
379 */
380int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
381{
382#ifndef HAVE_POLL_FINE
383  struct timeval pending_tv;
384  struct timeval *ptimeout;
385  fd_set fds_read;
386  fd_set fds_write;
387  fd_set fds_err;
388  curl_socket_t maxfd;
389#endif
390  struct timeval initial_tv = {0,0};
391  bool fds_none = TRUE;
392  unsigned int i;
393  int pending_ms = 0;
394  int error;
395  int r;
396
397  if(ufds) {
398    for(i = 0; i < nfds; i++) {
399      if(ufds[i].fd != CURL_SOCKET_BAD) {
400        fds_none = FALSE;
401        break;
402      }
403    }
404  }
405  if(fds_none) {
406    r = Curl_wait_ms(timeout_ms);
407    return r;
408  }
409
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. */
414
415  if(timeout_ms > 0) {
416    pending_ms = timeout_ms;
417    initial_tv = curlx_tvnow();
418  }
419
420#ifdef HAVE_POLL_FINE
421
422  do {
423    if(timeout_ms < 0)
424      pending_ms = -1;
425    else if(!timeout_ms)
426      pending_ms = 0;
427    r = poll(ufds, nfds, pending_ms);
428    if(r != -1)
429      break;
430    error = SOCKERRNO;
431    if(error && error_not_EINTR)
432      break;
433    if(timeout_ms > 0) {
434      pending_ms = timeout_ms - elapsed_ms;
435      if(pending_ms <= 0)
436        break;
437    }
438  } while(r == -1);
439
440  if(r < 0)
441    return -1;
442  if(r == 0)
443    return 0;
444
445  for(i = 0; i < nfds; i++) {
446    if(ufds[i].fd == CURL_SOCKET_BAD)
447      continue;
448    if(ufds[i].revents & POLLHUP)
449      ufds[i].revents |= POLLIN;
450    if(ufds[i].revents & POLLERR)
451      ufds[i].revents |= (POLLIN|POLLOUT);
452  }
453
454#else  /* HAVE_POLL_FINE */
455
456  FD_ZERO(&fds_read);
457  FD_ZERO(&fds_write);
458  FD_ZERO(&fds_err);
459  maxfd = (curl_socket_t)-1;
460
461  for(i = 0; i < nfds; i++) {
462    ufds[i].revents = 0;
463    if(ufds[i].fd == CURL_SOCKET_BAD)
464      continue;
465    VERIFY_SOCK(ufds[i].fd);
466    if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
467                          POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
468      if(ufds[i].fd > maxfd)
469        maxfd = ufds[i].fd;
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);
476    }
477  }
478
479#ifdef USE_WINSOCK
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);
485    return r;
486  }
487#endif
488
489  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
490
491  do {
492    if(timeout_ms > 0) {
493      pending_tv.tv_sec = pending_ms / 1000;
494      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
495    }
496    else if(!timeout_ms) {
497      pending_tv.tv_sec = 0;
498      pending_tv.tv_usec = 0;
499    }
500    r = select((int)maxfd + 1,
501#ifndef USE_WINSOCK
502               &fds_read, &fds_write, &fds_err,
503#else
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
506                  Curl_check_socket().
507               */
508               fds_read.fd_count ? &fds_read : NULL,
509               fds_write.fd_count ? &fds_write : NULL,
510               fds_err.fd_count ? &fds_err : NULL,
511#endif
512               ptimeout);
513    if(r != -1)
514      break;
515    error = SOCKERRNO;
516    if(error && error_not_EINTR)
517      break;
518    if(timeout_ms > 0) {
519      pending_ms = timeout_ms - elapsed_ms;
520      if(pending_ms <= 0)
521        break;
522    }
523  } while(r == -1);
524
525  if(r < 0)
526    return -1;
527  if(r == 0)
528    return 0;
529
530  r = 0;
531  for(i = 0; i < nfds; i++) {
532    ufds[i].revents = 0;
533    if(ufds[i].fd == CURL_SOCKET_BAD)
534      continue;
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)
542      r++;
543  }
544
545#endif  /* HAVE_POLL_FINE */
546
547  return r;
548}
549
550#ifdef TPF
551/*
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.
556 *
557 * Return values are the same as select's.
558 */
559int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
560                       fd_set* excepts, struct timeval* tv)
561{
562   int rc;
563
564   rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
565   tpf_process_signals();
566   return(rc);
567}
568#endif /* TPF */
569