1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, 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/* used for test case 533, 534 and 535 */ 23 24#include "test.h" 25 26#include <sys/types.h> 27#include <sys/stat.h> 28#include <fcntl.h> 29 30#include "testutil.h" 31#include "warnless.h" 32#include "memdebug.h" 33 34#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000 35#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 36 37int test(char *URL) 38{ 39 int res = 0; 40 CURL *curl; 41 int running; 42 char done=FALSE; 43 CURLM *m = NULL; 44 int current=0; 45 struct timeval ml_start; 46 struct timeval mp_start; 47 char ml_timedout = FALSE; 48 char mp_timedout = FALSE; 49 50 if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { 51 fprintf(stderr, "curl_global_init() failed\n"); 52 return TEST_ERR_MAJOR_BAD; 53 } 54 55 if ((curl = curl_easy_init()) == NULL) { 56 fprintf(stderr, "curl_easy_init() failed\n"); 57 curl_global_cleanup(); 58 return TEST_ERR_MAJOR_BAD; 59 } 60 61 test_setopt(curl, CURLOPT_URL, URL); 62 test_setopt(curl, CURLOPT_VERBOSE, 1); 63 test_setopt(curl, CURLOPT_FAILONERROR, 1); 64 65 if ((m = curl_multi_init()) == NULL) { 66 fprintf(stderr, "curl_multi_init() failed\n"); 67 curl_easy_cleanup(curl); 68 curl_global_cleanup(); 69 return TEST_ERR_MAJOR_BAD; 70 } 71 72 if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) { 73 fprintf(stderr, "curl_multi_add_handle() failed, " 74 "with code %d\n", res); 75 curl_multi_cleanup(m); 76 curl_easy_cleanup(curl); 77 curl_global_cleanup(); 78 return TEST_ERR_MAJOR_BAD; 79 } 80 81 ml_timedout = FALSE; 82 ml_start = tutil_tvnow(); 83 84 fprintf(stderr, "Start at URL 0\n"); 85 86 while (!done) { 87 fd_set rd, wr, exc; 88 int max_fd; 89 struct timeval interval; 90 91 interval.tv_sec = 1; 92 interval.tv_usec = 0; 93 94 if (tutil_tvdiff(tutil_tvnow(), ml_start) > 95 MAIN_LOOP_HANG_TIMEOUT) { 96 ml_timedout = TRUE; 97 break; 98 } 99 mp_timedout = FALSE; 100 mp_start = tutil_tvnow(); 101 102 while (res == CURLM_CALL_MULTI_PERFORM) { 103 res = (int)curl_multi_perform(m, &running); 104 if (tutil_tvdiff(tutil_tvnow(), mp_start) > 105 MULTI_PERFORM_HANG_TIMEOUT) { 106 mp_timedout = TRUE; 107 break; 108 } 109 if (running <= 0) { 110 if(!current++) { 111 fprintf(stderr, "Advancing to URL 1\n"); 112 /* remove the handle we use */ 113 curl_multi_remove_handle(m, curl); 114 115 /* make us re-use the same handle all the time, and try resetting 116 the handle first too */ 117 curl_easy_reset(curl); 118 test_setopt(curl, CURLOPT_URL, libtest_arg2); 119 test_setopt(curl, CURLOPT_VERBOSE, 1); 120 test_setopt(curl, CURLOPT_FAILONERROR, 1); 121 122 /* re-add it */ 123 res = (int)curl_multi_add_handle(m, curl); 124 if(res) { 125 fprintf(stderr, "add handle failed: %d.\n", res); 126 res = 243; 127 break; 128 } 129 } 130 else 131 done = TRUE; /* bail out */ 132 break; 133 } 134 } 135 if (mp_timedout || done) 136 break; 137 138 if (res != CURLM_OK) { 139 fprintf(stderr, "not okay???\n"); 140 break; 141 } 142 143 FD_ZERO(&rd); 144 FD_ZERO(&wr); 145 FD_ZERO(&exc); 146 max_fd = 0; 147 148 if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) { 149 fprintf(stderr, "unexpected failured of fdset.\n"); 150 res = 189; 151 break; 152 } 153 154 if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) { 155 fprintf(stderr, "bad select??\n"); 156 res = 195; 157 break; 158 } 159 160 res = CURLM_CALL_MULTI_PERFORM; 161 } 162 163 if (ml_timedout || mp_timedout) { 164 if (ml_timedout) fprintf(stderr, "ml_timedout\n"); 165 if (mp_timedout) fprintf(stderr, "mp_timedout\n"); 166 fprintf(stderr, "ABORTING TEST, since it seems " 167 "that it would have run forever.\n"); 168 res = TEST_ERR_RUNS_FOREVER; 169 } 170 171test_cleanup: 172 173 curl_easy_cleanup(curl); 174 if(m) 175 curl_multi_cleanup(m); 176 curl_global_cleanup(); 177 178 return res; 179} 180