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