Imported Upstream version 7.48.0
[platform/upstream/curl.git] / lib / select.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2015, 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 https://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 #ifdef __VXWORKS__
43 #include <strings.h>  /* bzero() in FD_SET */
44 #endif
45
46 #include <curl/curl.h>
47
48 #include "urldata.h"
49 #include "connect.h"
50 #include "select.h"
51 #include "warnless.h"
52
53 /* Convenience local macros */
54
55 #define elapsed_ms  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
56
57 int Curl_ack_eintr = 0;
58 #define error_not_EINTR (Curl_ack_eintr || error != EINTR)
59
60 /*
61  * Internal function used for waiting a specific amount of ms
62  * in Curl_socket_ready() and Curl_poll() when no file descriptor
63  * is provided to wait on, just being used to delay execution.
64  * WinSock select() and poll() timeout mechanisms need a valid
65  * socket descriptor in a not null file descriptor set to work.
66  * Waiting indefinitely with this function is not allowed, a
67  * zero or negative timeout value will return immediately.
68  * Timeout resolution, accuracy, as well as maximum supported
69  * value is system dependent, neither factor is a citical issue
70  * for the intended use of this function in the library.
71  *
72  * Return values:
73  *   -1 = system call error, invalid timeout value, or interrupted
74  *    0 = specified timeout has elapsed
75  */
76 int Curl_wait_ms(int timeout_ms)
77 {
78 #if !defined(MSDOS) && !defined(USE_WINSOCK)
79 #ifndef HAVE_POLL_FINE
80   struct timeval pending_tv;
81 #endif
82   struct timeval initial_tv;
83   int pending_ms;
84   int error;
85 #endif
86   int r = 0;
87
88   if(!timeout_ms)
89     return 0;
90   if(timeout_ms < 0) {
91     SET_SOCKERRNO(EINVAL);
92     return -1;
93   }
94 #if defined(MSDOS)
95   delay(timeout_ms);
96 #elif defined(USE_WINSOCK)
97   Sleep(timeout_ms);
98 #else
99   pending_ms = timeout_ms;
100   initial_tv = curlx_tvnow();
101   do {
102 #if defined(HAVE_POLL_FINE)
103     r = poll(NULL, 0, pending_ms);
104 #else
105     pending_tv.tv_sec = pending_ms / 1000;
106     pending_tv.tv_usec = (pending_ms % 1000) * 1000;
107     r = select(0, NULL, NULL, NULL, &pending_tv);
108 #endif /* HAVE_POLL_FINE */
109     if(r != -1)
110       break;
111     error = SOCKERRNO;
112     if(error && error_not_EINTR)
113       break;
114     pending_ms = timeout_ms - elapsed_ms;
115     if(pending_ms <= 0) {
116       r = 0;  /* Simulate a "call timed out" case */
117       break;
118     }
119   } while(r == -1);
120 #endif /* USE_WINSOCK */
121   if(r)
122     r = -1;
123   return r;
124 }
125
126 /*
127  * Wait for read or write events on a set of file descriptors. It uses poll()
128  * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
129  * otherwise select() is used.  An error is returned if select() is being used
130  * and a file descriptor is too large for FD_SETSIZE.
131  *
132  * A negative timeout value makes this function wait indefinitely,
133  * unles no valid file descriptor is given, when this happens the
134  * negative timeout is ignored and the function times out immediately.
135  *
136  * Return values:
137  *   -1 = system call error or fd >= FD_SETSIZE
138  *    0 = timeout
139  *    [bitmask] = action as described below
140  *
141  * CURL_CSELECT_IN - first socket is readable
142  * CURL_CSELECT_IN2 - second socket is readable
143  * CURL_CSELECT_OUT - write socket is writable
144  * CURL_CSELECT_ERR - an error condition occurred
145  */
146 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
147                       curl_socket_t readfd1,
148                       curl_socket_t writefd, /* socket to write to */
149                       long timeout_ms)       /* milliseconds to wait */
150 {
151 #ifdef HAVE_POLL_FINE
152   struct pollfd pfd[3];
153   int num;
154 #else
155   struct timeval pending_tv;
156   struct timeval *ptimeout;
157   fd_set fds_read;
158   fd_set fds_write;
159   fd_set fds_err;
160   curl_socket_t maxfd;
161 #endif
162   struct timeval initial_tv = {0, 0};
163   int pending_ms = 0;
164   int error;
165   int r;
166   int ret;
167
168   if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
169      (writefd == CURL_SOCKET_BAD)) {
170     /* no sockets, just wait */
171     r = Curl_wait_ms((int)timeout_ms);
172     return r;
173   }
174
175   /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
176      time in this function does not need to be measured. This happens
177      when function is called with a zero timeout or a negative timeout
178      value indicating a blocking call should be performed. */
179
180   if(timeout_ms > 0) {
181     pending_ms = (int)timeout_ms;
182     initial_tv = curlx_tvnow();
183   }
184
185 #ifdef HAVE_POLL_FINE
186
187   num = 0;
188   if(readfd0 != CURL_SOCKET_BAD) {
189     pfd[num].fd = readfd0;
190     pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
191     pfd[num].revents = 0;
192     num++;
193   }
194   if(readfd1 != CURL_SOCKET_BAD) {
195     pfd[num].fd = readfd1;
196     pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
197     pfd[num].revents = 0;
198     num++;
199   }
200   if(writefd != CURL_SOCKET_BAD) {
201     pfd[num].fd = writefd;
202     pfd[num].events = POLLWRNORM|POLLOUT;
203     pfd[num].revents = 0;
204     num++;
205   }
206
207   do {
208     if(timeout_ms < 0)
209       pending_ms = -1;
210     else if(!timeout_ms)
211       pending_ms = 0;
212     r = poll(pfd, num, pending_ms);
213     if(r != -1)
214       break;
215     error = SOCKERRNO;
216     if(error && error_not_EINTR)
217       break;
218     if(timeout_ms > 0) {
219       pending_ms = (int)(timeout_ms - elapsed_ms);
220       if(pending_ms <= 0) {
221         r = 0;  /* Simulate a "call timed out" case */
222         break;
223       }
224     }
225   } while(r == -1);
226
227   if(r < 0)
228     return -1;
229   if(r == 0)
230     return 0;
231
232   ret = 0;
233   num = 0;
234   if(readfd0 != CURL_SOCKET_BAD) {
235     if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
236       ret |= CURL_CSELECT_IN;
237     if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
238       ret |= CURL_CSELECT_ERR;
239     num++;
240   }
241   if(readfd1 != CURL_SOCKET_BAD) {
242     if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
243       ret |= CURL_CSELECT_IN2;
244     if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
245       ret |= CURL_CSELECT_ERR;
246     num++;
247   }
248   if(writefd != CURL_SOCKET_BAD) {
249     if(pfd[num].revents & (POLLWRNORM|POLLOUT))
250       ret |= CURL_CSELECT_OUT;
251     if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
252       ret |= CURL_CSELECT_ERR;
253   }
254
255   return ret;
256
257 #else  /* HAVE_POLL_FINE */
258
259   FD_ZERO(&fds_err);
260   maxfd = (curl_socket_t)-1;
261
262   FD_ZERO(&fds_read);
263   if(readfd0 != CURL_SOCKET_BAD) {
264     VERIFY_SOCK(readfd0);
265     FD_SET(readfd0, &fds_read);
266     FD_SET(readfd0, &fds_err);
267     maxfd = readfd0;
268   }
269   if(readfd1 != CURL_SOCKET_BAD) {
270     VERIFY_SOCK(readfd1);
271     FD_SET(readfd1, &fds_read);
272     FD_SET(readfd1, &fds_err);
273     if(readfd1 > maxfd)
274       maxfd = readfd1;
275   }
276
277   FD_ZERO(&fds_write);
278   if(writefd != CURL_SOCKET_BAD) {
279     VERIFY_SOCK(writefd);
280     FD_SET(writefd, &fds_write);
281     FD_SET(writefd, &fds_err);
282     if(writefd > maxfd)
283       maxfd = writefd;
284   }
285
286   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
287
288   do {
289     if(timeout_ms > 0) {
290       pending_tv.tv_sec = pending_ms / 1000;
291       pending_tv.tv_usec = (pending_ms % 1000) * 1000;
292     }
293     else if(!timeout_ms) {
294       pending_tv.tv_sec = 0;
295       pending_tv.tv_usec = 0;
296     }
297
298     /* WinSock select() must not be called with an fd_set that contains zero
299        fd flags, or it will return WSAEINVAL.  But, it also can't be called
300        with no fd_sets at all!  From the documentation:
301
302          Any two of the parameters, readfds, writefds, or exceptfds, can be
303          given as null. At least one must be non-null, and any non-null
304          descriptor set must contain at least one handle to a socket.
305
306        We know that we have at least one bit set in at least two fd_sets in
307        this case, but we may have no bits set in either fds_read or fd_write,
308        so check for that and handle it.  Luckily, with WinSock, we can _also_
309        ask how many bits are set on an fd_set.
310
311        It is unclear why WinSock doesn't just handle this for us instead of
312        calling this an error.
313
314        Note also that WinSock ignores the first argument, so we don't worry
315        about the fact that maxfd is computed incorrectly with WinSock (since
316        curl_socket_t is unsigned in such cases and thus -1 is the largest
317        value).
318     */
319 #ifdef USE_WINSOCK
320     r = select((int)maxfd + 1,
321                fds_read.fd_count ? &fds_read : NULL,
322                fds_write.fd_count ? &fds_write : NULL,
323                &fds_err, ptimeout);
324 #else
325     r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
326 #endif
327
328     if(r != -1)
329       break;
330     error = SOCKERRNO;
331     if(error && error_not_EINTR)
332       break;
333     if(timeout_ms > 0) {
334       pending_ms = timeout_ms - elapsed_ms;
335       if(pending_ms <= 0) {
336         r = 0;  /* Simulate a "call timed out" case */
337         break;
338       }
339     }
340   } while(r == -1);
341
342   if(r < 0)
343     return -1;
344   if(r == 0)
345     return 0;
346
347   ret = 0;
348   if(readfd0 != CURL_SOCKET_BAD) {
349     if(FD_ISSET(readfd0, &fds_read))
350       ret |= CURL_CSELECT_IN;
351     if(FD_ISSET(readfd0, &fds_err))
352       ret |= CURL_CSELECT_ERR;
353   }
354   if(readfd1 != CURL_SOCKET_BAD) {
355     if(FD_ISSET(readfd1, &fds_read))
356       ret |= CURL_CSELECT_IN2;
357     if(FD_ISSET(readfd1, &fds_err))
358       ret |= CURL_CSELECT_ERR;
359   }
360   if(writefd != CURL_SOCKET_BAD) {
361     if(FD_ISSET(writefd, &fds_write))
362       ret |= CURL_CSELECT_OUT;
363     if(FD_ISSET(writefd, &fds_err))
364       ret |= CURL_CSELECT_ERR;
365   }
366
367   return ret;
368
369 #endif  /* HAVE_POLL_FINE */
370
371 }
372
373 /*
374  * This is a wrapper around poll().  If poll() does not exist, then
375  * select() is used instead.  An error is returned if select() is
376  * being used and a file descriptor is too large for FD_SETSIZE.
377  * A negative timeout value makes this function wait indefinitely,
378  * unles no valid file descriptor is given, when this happens the
379  * negative timeout is ignored and the function times out immediately.
380  *
381  * Return values:
382  *   -1 = system call error or fd >= FD_SETSIZE
383  *    0 = timeout
384  *    N = number of structures with non zero revent fields
385  */
386 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
387 {
388 #ifndef HAVE_POLL_FINE
389   struct timeval pending_tv;
390   struct timeval *ptimeout;
391   fd_set fds_read;
392   fd_set fds_write;
393   fd_set fds_err;
394   curl_socket_t maxfd;
395 #endif
396   struct timeval initial_tv = {0, 0};
397   bool fds_none = TRUE;
398   unsigned int i;
399   int pending_ms = 0;
400   int error;
401   int r;
402
403   if(ufds) {
404     for(i = 0; i < nfds; i++) {
405       if(ufds[i].fd != CURL_SOCKET_BAD) {
406         fds_none = FALSE;
407         break;
408       }
409     }
410   }
411   if(fds_none) {
412     r = Curl_wait_ms(timeout_ms);
413     return r;
414   }
415
416   /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
417      time in this function does not need to be measured. This happens
418      when function is called with a zero timeout or a negative timeout
419      value indicating a blocking call should be performed. */
420
421   if(timeout_ms > 0) {
422     pending_ms = timeout_ms;
423     initial_tv = curlx_tvnow();
424   }
425
426 #ifdef HAVE_POLL_FINE
427
428   do {
429     if(timeout_ms < 0)
430       pending_ms = -1;
431     else if(!timeout_ms)
432       pending_ms = 0;
433     r = poll(ufds, nfds, pending_ms);
434     if(r != -1)
435       break;
436     error = SOCKERRNO;
437     if(error && error_not_EINTR)
438       break;
439     if(timeout_ms > 0) {
440       pending_ms = timeout_ms - elapsed_ms;
441       if(pending_ms <= 0) {
442         r = 0;  /* Simulate a "call timed out" case */
443         break;
444       }
445     }
446   } while(r == -1);
447
448   if(r < 0)
449     return -1;
450   if(r == 0)
451     return 0;
452
453   for(i = 0; i < nfds; i++) {
454     if(ufds[i].fd == CURL_SOCKET_BAD)
455       continue;
456     if(ufds[i].revents & POLLHUP)
457       ufds[i].revents |= POLLIN;
458     if(ufds[i].revents & POLLERR)
459       ufds[i].revents |= (POLLIN|POLLOUT);
460   }
461
462 #else  /* HAVE_POLL_FINE */
463
464   FD_ZERO(&fds_read);
465   FD_ZERO(&fds_write);
466   FD_ZERO(&fds_err);
467   maxfd = (curl_socket_t)-1;
468
469   for(i = 0; i < nfds; i++) {
470     ufds[i].revents = 0;
471     if(ufds[i].fd == CURL_SOCKET_BAD)
472       continue;
473     VERIFY_SOCK(ufds[i].fd);
474     if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
475                           POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
476       if(ufds[i].fd > maxfd)
477         maxfd = ufds[i].fd;
478       if(ufds[i].events & (POLLRDNORM|POLLIN))
479         FD_SET(ufds[i].fd, &fds_read);
480       if(ufds[i].events & (POLLWRNORM|POLLOUT))
481         FD_SET(ufds[i].fd, &fds_write);
482       if(ufds[i].events & (POLLRDBAND|POLLPRI))
483         FD_SET(ufds[i].fd, &fds_err);
484     }
485   }
486
487 #ifdef USE_WINSOCK
488   /* WinSock select() can't handle zero events.  See the comment about this in
489      Curl_check_socket(). */
490   if(fds_read.fd_count == 0 && fds_write.fd_count == 0
491      && fds_err.fd_count == 0) {
492     r = Curl_wait_ms(timeout_ms);
493     return r;
494   }
495 #endif
496
497   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
498
499   do {
500     if(timeout_ms > 0) {
501       pending_tv.tv_sec = pending_ms / 1000;
502       pending_tv.tv_usec = (pending_ms % 1000) * 1000;
503     }
504     else if(!timeout_ms) {
505       pending_tv.tv_sec = 0;
506       pending_tv.tv_usec = 0;
507     }
508
509 #ifdef USE_WINSOCK
510     r = select((int)maxfd + 1,
511                /* WinSock select() can't handle fd_sets with zero bits set, so
512                   don't give it such arguments.  See the comment about this in
513                   Curl_check_socket().
514                */
515                fds_read.fd_count ? &fds_read : NULL,
516                fds_write.fd_count ? &fds_write : NULL,
517                fds_err.fd_count ? &fds_err : NULL, ptimeout);
518 #else
519     r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
520 #endif
521     if(r != -1)
522       break;
523     error = SOCKERRNO;
524     if(error && error_not_EINTR)
525       break;
526     if(timeout_ms > 0) {
527       pending_ms = timeout_ms - elapsed_ms;
528       if(pending_ms <= 0) {
529         r = 0;  /* Simulate a "call timed out" case */
530         break;
531       }
532     }
533   } while(r == -1);
534
535   if(r < 0)
536     return -1;
537   if(r == 0)
538     return 0;
539
540   r = 0;
541   for(i = 0; i < nfds; i++) {
542     ufds[i].revents = 0;
543     if(ufds[i].fd == CURL_SOCKET_BAD)
544       continue;
545     if(FD_ISSET(ufds[i].fd, &fds_read))
546       ufds[i].revents |= POLLIN;
547     if(FD_ISSET(ufds[i].fd, &fds_write))
548       ufds[i].revents |= POLLOUT;
549     if(FD_ISSET(ufds[i].fd, &fds_err))
550       ufds[i].revents |= POLLPRI;
551     if(ufds[i].revents != 0)
552       r++;
553   }
554
555 #endif  /* HAVE_POLL_FINE */
556
557   return r;
558 }
559
560 #ifdef TPF
561 /*
562  * This is a replacement for select() on the TPF platform.
563  * It is used whenever libcurl calls select().
564  * The call below to tpf_process_signals() is required because
565  * TPF's select calls are not signal interruptible.
566  *
567  * Return values are the same as select's.
568  */
569 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
570                        fd_set* excepts, struct timeval* tv)
571 {
572    int rc;
573
574    rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
575    tpf_process_signals();
576    return rc;
577 }
578 #endif /* TPF */