Git init
[external/curl.git] / tests / libtest / lib507.c
1 /*****************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  */
9
10 #include "test.h"
11
12 #include "testutil.h"
13 #include "memdebug.h"
14
15 #define MAIN_LOOP_HANG_TIMEOUT     90 * 1000
16 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
17
18 int test(char *URL)
19 {
20   CURL* curls;
21   CURLM* multi;
22   int still_running;
23   int i = -1;
24   int res = 0;
25   CURLMsg *msg;
26   CURLMcode ret;
27   struct timeval ml_start;
28   struct timeval mp_start;
29   char ml_timedout = FALSE;
30   char mp_timedout = FALSE;
31
32   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
33     fprintf(stderr, "curl_global_init() failed\n");
34     return TEST_ERR_MAJOR_BAD;
35   }
36
37   if ((multi = curl_multi_init()) == NULL) {
38     fprintf(stderr, "curl_multi_init() failed\n");
39     curl_global_cleanup();
40     return TEST_ERR_MAJOR_BAD;
41   }
42
43   if ((curls = curl_easy_init()) == NULL) {
44     fprintf(stderr, "curl_easy_init() failed\n");
45     curl_multi_cleanup(multi);
46     curl_global_cleanup();
47     return TEST_ERR_MAJOR_BAD;
48   }
49
50   test_setopt(curls, CURLOPT_URL, URL);
51
52   if ((ret = curl_multi_add_handle(multi, curls)) != CURLM_OK) {
53     fprintf(stderr, "curl_multi_add_handle() failed, "
54             "with code %d\n", ret);
55     curl_easy_cleanup(curls);
56     curl_multi_cleanup(multi);
57     curl_global_cleanup();
58     return TEST_ERR_MAJOR_BAD;
59   }
60
61   mp_timedout = FALSE;
62   mp_start = tutil_tvnow();
63
64   do {
65     ret = curl_multi_perform(multi, &still_running);
66     if (tutil_tvdiff(tutil_tvnow(), mp_start) >
67         MULTI_PERFORM_HANG_TIMEOUT) {
68       mp_timedout = TRUE;
69       break;
70     }
71   } while (ret == CURLM_CALL_MULTI_PERFORM);
72
73   ml_timedout = FALSE;
74   ml_start = tutil_tvnow();
75
76   while ((!ml_timedout) && (!mp_timedout) && (still_running)) {
77     struct timeval timeout;
78     int rc;
79     fd_set fdread;
80     fd_set fdwrite;
81     fd_set fdexcep;
82     int maxfd;
83
84     FD_ZERO(&fdread);
85     FD_ZERO(&fdwrite);
86     FD_ZERO(&fdexcep);
87     timeout.tv_sec = 1;
88     timeout.tv_usec = 0;
89
90     if (tutil_tvdiff(tutil_tvnow(), ml_start) >
91         MAIN_LOOP_HANG_TIMEOUT) {
92       ml_timedout = TRUE;
93       break;
94     }
95
96     curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
97     rc = select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
98     switch(rc) {
99       case -1:
100         break;
101       case 0:
102       default:
103         mp_timedout = FALSE;
104         mp_start = tutil_tvnow();
105         do {
106           ret = curl_multi_perform(multi, &still_running);
107           if (tutil_tvdiff(tutil_tvnow(), mp_start) >
108               MULTI_PERFORM_HANG_TIMEOUT) {
109             mp_timedout = TRUE;
110             break;
111           }
112         } while (ret == CURLM_CALL_MULTI_PERFORM);
113         break;
114     }
115   }
116   if (ml_timedout || mp_timedout) {
117     if (ml_timedout) fprintf(stderr, "ml_timedout\n");
118     if (mp_timedout) fprintf(stderr, "mp_timedout\n");
119     fprintf(stderr, "ABORTING TEST, since it seems "
120             "that it would have run forever.\n");
121     i = TEST_ERR_RUNS_FOREVER;
122   }
123   else {
124     msg = curl_multi_info_read(multi, &still_running);
125     if(msg)
126       /* this should now contain a result code from the easy handle,
127          get it */
128       i = msg->data.result;
129   }
130
131 test_cleanup:
132
133   curl_multi_cleanup(multi);
134   curl_easy_cleanup(curls);
135   curl_global_cleanup();
136
137   if(res)
138     i = res;
139
140   return i; /* return the final return code */
141 }