cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl crash using multiple muti-handles when resolve host failed.

From: Du xiaoyu <duxiaoyu_at_styleflying.com>
Date: Thu, 15 May 2008 12:30:52 +0800

Hello. everyone.

I'm here to subscribe a problem. maybe this is a bug or my fault.
My code crashed if I use multiple muti-handles ,
when resolve host failed, my program will crashed.
but if the network link is fine, even you create ten thread, every
thing is ok.
 
To simulate this sence.you should up you interface and then pull
out you twisted-pair line from you
computer.

this is my simple test code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <iconv.h>
#include <sys/stat.h>
#include <pthread.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <curl.h>

int download_file(char *url)
{
 printf("url is %s \n", url);
 char *up = malloc(strlen(url)+1);
 if (!up)
  return -1;
 strcpy(up, url);
 CURLMcode res= -1;
 CURLM *m;
 FILE *buffer_file;
 CURL *curl;
 buffer_file = fopen("/dev/null", "wb");
 
 if(buffer_file == NULL)
  return -1;

   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
 {
     printf("curl_global_init() failed\n");
      return -1;
   }

   if ((curl = curl_easy_init()) == NULL)
 {
      printf("curl_easy_init() failed\n");
      curl_global_cleanup();
      return -1;
   }
 if ((m = curl_multi_init()) == NULL) {
  fprintf(stderr, "curl_multi_init() failed\n");
  curl_easy_cleanup(curl);
  curl = NULL;
  curl_global_cleanup();
  return -1;
   }
 
   if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
     fprintf(stderr, "curl_multi_add_handle() failed, "
             "with code %d\n", res);
     curl_multi_cleanup(m);
     curl_easy_cleanup(curl);
     curl = NULL;
     curl_global_cleanup();
     return -1;
   }
  
 curl_easy_setopt(curl, CURLOPT_URL, up);
 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 8);
 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3);
 curl_easy_setopt(curl, CURLOPT_WRITEDATA,buffer_file);
   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
   curl_easy_setopt(curl, CURLOPT_HEADER, 0);
 int running = 1;
 while (running) {
  res = (int)curl_multi_perform(m, &running);
  printf("mutil ret code %s\n", curl_multi_strerror(res));
  if (running <= 0) {
   fprintf(stderr, "nothing left running.\n");
   pthread_exit(0);
   break;
  }
 }
 return res;
}
struct url_array{
 char buf[200];
} url[] = {
 {"http://www.baidu.com"},
 {"http://www.google.com"},
};

void html_sleep(int sec){
 int fd = socket(AF_INET, SOCK_DGRAM, 0);
 if (fd < 0)
  return;
 fd_set rset;
 struct timeval tv;
 FD_ZERO(&rset);
 FD_SET(fd, &rset);
 tv.tv_sec = sec;
 tv.tv_usec = 0;
 select(fd+1, &rset, NULL, NULL, &tv);
 close(fd);
}

void test2(int n)
{
 int ret;
 ret = download_file(url[n].buf);
 if (ret != CURLE_OK) {
  printf("\ntest %d ok bad content\n", n);
  }
 printf("test %d ok\n", n);
}

int main(int argc, char* argv[])
{
 int i = 0;
 int ret = 0;
 pthread_t thd;
 while(i<2) {

  ret = pthread_create(&thd, NULL, (void *)test2, (void *)i);
  if (ret != 0) {
   printf("pthread_create failed !\n");
   break;
  }
  else
   printf("start thread for %d\n", i);
 ++i;
 }
 while(1)
  html_sleep(3);
}



this is my output:
[root_at_192.168.0.188]#./demo
start thread for 0
start thread for 1
url is http://www.baidu.com
url is http://www.google.com
* name lookup timed out
* Couldn't resolve host 'www.baidu.com'
* Closing connection #0
nothing left running.
Killed

can anyone tell me what was wrong.

NETWORK Du Xiaoyu
Style Flying Tech.Co
+86(10)51627217-849
www.styleflying.com
Received on 2008-05-15