curl-library
curl_easy_duphandle() and multi_interface problem
Date: Tue, 20 Jan 2004 13:49:28 +0100
Hi All,
I'm using a CVS version of libCurl. I've created 3 instance of
CURL* by duplicating them with curl_easy_duphandle().
No problem appear when duplicating the handle and I assign to
each of them an HTTP URL to retrieve.
I'm also using the curl_multi() interface with a select like
in the examples.
The downloading seems work but when I want to read the result,
I've a segmentation fault.
(gdb) run
Starting program:
/home/younes/programs/EDTK/edtk-1.0/examples/dominos/net
Program received signal SIGSEGV, Segmentation fault.
0x40031889 in Curl_getinfo (data=0x805b678, info=134592120) at
getinfo.c:173
warning: Source file is more recent than executable.
173 *param_longp = data->info.proxyauthavail;
this is my code :
-------------------------------------------------------------------------------------------------------------------
typedef struct MemoryStructResult {
unsigned char *effective_url;
unsigned char *memory;
unsigned char *error;
unsigned char *mime_type;
unsigned long http_code;
unsigned short curl_error_code;
size_t size;
} result_t;
inline void
multi_interface_test(void)
{
char *sites[] =
{
"http://www.w3c.org",
"http://search.cpan.org/recent",
};
int HANDLECOUNT =sizeof(sites)/sizeof(sites[0]);
result_t *chunks[HANDLECOUNT];
CURL *handles[HANDLECOUNT];
CURLM *multi_handle;
int still_running; /* keep number of running handles */
int i, fd;
CURLMsg *msg; /* for picking up messages with the transfer
status */
int msgs_left; /* how many messages are left */
struct timeval timeout;
int rc; /* select() return code */
int maxfd;
result_t *input_chunk;
CURL *input_handle;
/* init a multi stack */
multi_handle = curl_multi_init();
/* Allocate one chunk per transfer */
/* This initialize my input_chunk (allocate memory ...)*/
input_chunk =createMemoryStruct();
/* Allocate one CURL handle per transfer */
/* here I set a lot of curl parameters like,
CURLOPT_MAXFILESIZE, CURLOPT_MAXCONNECTS, CURLOPT_ENCODING ...*/
input_handle = init(input_chunk);
/*I clone the input_handle HANDLECOUNT times*/
for (i=0; i < HANDLECOUNT; i++)
{
if((handles[i] =curl_easy_duphandle(input_handle)) != NULL)
{
/* set the options (I left out a few, you'll get the
point anyway) */
curl_easy_setopt(handles[i], CURLOPT_URL, sites[i]);
/* Set a different URL to download*/
/* add the individual transfers */
curl_multi_add_handle(multi_handle, handles[i]);
}
else
{
printf(">>>>> curl_easy_duphandle error when cloning
[%d]\n", i);
exit(1);
}
}
/* we start some action by calling perform right away */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
while(still_running)
{
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite,
&fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc)
{
case -1:
/* select error */
/* Set when errors occurs */
/* Free the last allocated memory */
/*setError(chunks[i], res, url);*/
perror(-1);
break;
case 0:
/* timeout */
/* Set when errors occurs */
/* Free the last allocated memory */
break;
default:
/* timeout or readable/writable sockets */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
/*printf("still_running : %d\n", still_running);*/
break;
}
}
/* See how the transfers went */
while ((msg = curl_multi_info_read(multi_handle, &msgs_left)))
{
if (msg->msg == CURLMSG_DONE)
{
int idx, found = 0;
/* Find out which handle this message is about */
for (idx=0; (!found && (idx < HANDLECOUNT)); idx++)
found = (msg->easy_handle == handles[idx]);
for (i=0; i < HANDLECOUNT; i++)
{
if (idx == i)
{
printf("[%d] Transfer completed with status
%d\n", idx,msg->data.result);
}
}
}
else
{
printf("CURLMSG_NOT_DONE\n");
}
}
/* cleanup memory */
curl_multi_cleanup(multi_handle);
/* Gets Results */
for (i=0; i<HANDLECOUNT; i++)
{
/* Get the Curlcode */
curl_easy_getinfo(handles[i], CURLINFO_HTTP_CODE,
&(chunks[i]->http_code));
/* Get the effective URL */
curl_easy_getinfo(handles[i], CURLINFO_EFFECTIVE_URL,
&(chunks[i]->effective_url));
/* Get the mime type of the content */
curl_easy_getinfo(handles[i], CURLINFO_CONTENT_TYPE,
&(chunks[i]->mime_type));
}
/* Free the CURL handles */
for (i=0; i<HANDLECOUNT; i++)
{
/* curl_easy_cleanup(handles[i]); */
cleanup_chunk(chunks[i]);
cleanup(handles[i]); /* curl_easy_cleanup() */
}
/* curl_easy_cleanup(input_chunk); */
cleanup_chunk(input_chunk);
cleanup(input_handle); /* curl_easy_cleanup() */
}
What's the problem? Is it incompatible to use
curl_easy_duphandle() with the curl_multi interface ???
Best Regards,
Taz
Accédez au courrier électronique de La Poste : www.laposte.net ;
3615 LAPOSTENET (0,34€/mn) ; tél : 08 92 68 13 50 (0,34€/mn)
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
Received on 2004-01-20