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 * multi interface and debug callback
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
379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelstypedef char bool;
389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define TRUE 1
399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic
419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsvoid dump(const char *text,
429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels          FILE *stream, unsigned char *ptr, size_t size,
439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels          bool nohex)
449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  size_t i;
469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  size_t c;
479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  unsigned int width=0x10;
499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(nohex)
519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* without the hex output, we can fit more on screen */
529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    width = 0x40;
539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels          text, (long)size, (long)size);
569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  for(i=0; i<size; i+= width) {
589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    fprintf(stream, "%4.4lx: ", (long)i);
609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(!nohex) {
629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* hex not disabled, show it */
639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      for(c = 0; c < width; c++)
649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        if(i+c < size)
659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels          fprintf(stream, "%02x ", ptr[i+c]);
669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        else
679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels          fputs("   ", stream);
689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    for(c = 0; (c < width) && (i+c < size); c++) {
719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* check for 0D0A; if found, skip past and start a new line of output */
728f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo      if(nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        i+=(c+2-width);
749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        break;
759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      }
769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      fprintf(stream, "%c",
779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels              (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* check again for 0D0A, to avoid an extra \n if it's at width */
798f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo      if(nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        i+=(c+3-width);
819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        break;
829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      }
839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fputc('\n', stream); /* newline */
859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  fflush(stream);
879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic
909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint my_trace(CURL *handle, curl_infotype type,
919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels             unsigned char *data, size_t size,
929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels             void *userp)
939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  const char *text;
959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  (void)userp;
979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  (void)handle; /* prevent compiler warning */
989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  switch (type) {
1009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLINFO_TEXT:
1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fprintf(stderr, "== Info: %s", data);
1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  default: /* in case a new one is introduced to shock us */
1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    return 0;
1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLINFO_HEADER_OUT:
1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    text = "=> Send header";
1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLINFO_DATA_OUT:
1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    text = "=> Send data";
1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLINFO_HEADER_IN:
1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    text = "<= Recv header";
1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLINFO_DATA_IN:
1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    text = "<= Recv data";
1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  dump(text, stderr, data, size, TRUE);
1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return 0;
1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/*
1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Simply download a HTTP file.
1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */
126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint main(void)
1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  CURL *http_handle;
1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  CURLM *multi_handle;
1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  int still_running; /* keep number of running handles */
1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  http_handle = curl_easy_init();
1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* set the options (I left out a few, you'll get the point anyway) */
1369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);
1409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* init a multi stack */
1429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  multi_handle = curl_multi_init();
1439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* add the individual transfers */
1459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_multi_add_handle(multi_handle, http_handle);
1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* we start some action by calling perform right away */
1489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_multi_perform(multi_handle, &still_running);
1499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
150e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  do {
1519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    struct timeval timeout;
1529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    int rc; /* select() return code */
153e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    CURLMcode mc; /* curl_multi_fdset() return code */
1549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fd_set fdread;
1569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fd_set fdwrite;
1579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fd_set fdexcep;
1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    int maxfd = -1;
1599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    long curl_timeo = -1;
1619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    FD_ZERO(&fdread);
1639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    FD_ZERO(&fdwrite);
1649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    FD_ZERO(&fdexcep);
1659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* set a suitable timeout to play around with */
1679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    timeout.tv_sec = 1;
1689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    timeout.tv_usec = 0;
1699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_multi_timeout(multi_handle, &curl_timeo);
1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(curl_timeo >= 0) {
1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      timeout.tv_sec = curl_timeo / 1000;
1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      if(timeout.tv_sec > 1)
1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        timeout.tv_sec = 1;
1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      else
1769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels        timeout.tv_usec = (curl_timeo % 1000) * 1000;
1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
1789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* get file descriptors from the transfers */
180e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
1819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1828f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo    if(mc != CURLM_OK) {
183e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
184e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      break;
185e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
187e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* On success the value of maxfd is guaranteed to be >= -1. We call
188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
189e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
190e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET       to sleep 100ms, which is the minimum suggested value in the
191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET       curl_multi_fdset() doc. */
192e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(maxfd == -1) {
194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef _WIN32
195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Sleep(100);
196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      rc = 0;
197e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else
198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      /* Portable sleep for platforms other than Windows. */
199e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
200e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      rc = select(0, NULL, NULL, NULL, &wait);
201e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    else {
204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      /* Note that on some platforms 'timeout' may be modified by select().
205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET         If you need access to the original value save a copy beforehand. */
206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
2089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
2099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    switch(rc) {
2109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    case -1:
2119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* select error */
2129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      still_running = 0;
2139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      printf("select() returns error, this is badness\n");
2149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      break;
2159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    case 0:
2169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    default:
2179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* timeout or readable/writable sockets */
2189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      curl_multi_perform(multi_handle, &still_running);
2199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      break;
2209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
221e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  } while(still_running);
2229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
2239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_multi_cleanup(multi_handle);
2249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_cleanup(http_handle);
2269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return 0;
2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
229