1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 88f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 228f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo/* <DESC> 238f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * using the multi interface to do a single download 248f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * </DESC> 258f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo */ 269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdio.h> 289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <string.h> 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* somewhat unix-specific */ 319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <sys/time.h> 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <unistd.h> 339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* curl stuff */ 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h> 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef _WIN32 38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define WAITMS(x) Sleep(x) 39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else 40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Portable sleep for platforms other than Windows. */ 41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define WAITMS(x) \ 42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct timeval wait = { 0, (x) * 1000 }; \ 43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)select(0, NULL, NULL, NULL, &wait); 44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Simply download a HTTP file. 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint main(void) 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURL *http_handle; 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLM *multi_handle; 539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int still_running; /* keep number of running handles */ 55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int repeats = 0; 56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_global_init(CURL_GLOBAL_DEFAULT); 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels http_handle = curl_easy_init(); 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* set the options (I left out a few, you'll get the point anyway) */ 629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/"); 639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* init a multi stack */ 659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels multi_handle = curl_multi_init(); 669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* add the individual transfers */ 689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_add_handle(multi_handle, http_handle); 699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* we start some action by calling perform right away */ 719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_perform(multi_handle, &still_running); 729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET do { 74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLMcode mc; /* curl_multi_wait() return code */ 75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int numfds; 769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* wait for activity, timeout or "nothing" */ 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); 799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 808f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(mc != CURLM_OK) { 818f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc); 82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* 'numfds' being zero means either a timeout or no file descriptors to 86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET wait for. Try timeout on first occurrence, then assume no file 87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET descriptors and no file descriptors to wait for means wait for 100 88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET milliseconds. */ 899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!numfds) { 91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET repeats++; /* count number of repeated zero numfds */ 92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(repeats > 1) { 93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET WAITMS(100); /* sleep 100 milliseconds */ 94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET repeats = 0; 989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_multi_perform(multi_handle, &still_running); 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } while(still_running); 1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_multi_remove_handle(multi_handle, http_handle); 1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_cleanup(http_handle); 1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_cleanup(multi_handle); 1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_global_cleanup(); 1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 112