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