curl-library
curl_multi question
Date: Fri, 10 Aug 2007 10:00:22 +0530
Hello,
I'm using curl_multi to transfer multiple files from a particular web page.
When i use CURLOPT_WRITEDATA and CURLOPT_WRITEFUNCTION, I'm getting a
segmentation violation at curl_multi_perform. If i do not use them,
I'm able to transfer the files, but the output is written to stdout.
Two Questions:
1. How can i write the data to files when i use curl_multi
2. If this is the way to write data to files, then why the
segmentation violation?
Find the code attached below.
Thanks in advance,
Surya
================================
#include <sys/select.h>
#include <curl/curl.h>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <sstream>
using namespace std ;
typedef struct
{
string filename ;
FILE *fp ;
}OutFile;
map <int, OutFile> files;
static size_t write_function (void* buffer, size_t size, size_t nmemb,
void *stream)
{
OutFile *out = (OutFile*)stream ;
if (out && !out->fp)
{
out->fp = fopen (out->filename.c_str(), "wb") ;
if (!out->fp) return (-1) ;
}
return fwrite (buffer, size, nmemb, out->fp) ;
}
CURL* set_handle (const string& site, const string& code, int idx)
{
OutFile outfile ;
outfile.filename = ("out-") ;
outfile.filename += code ;
outfile.fp = NULL ;
files [idx] = outfile ;
CURL *handle = curl_easy_init() ;
curl_easy_setopt(handle, CURLOPT_URL, site.c_str()) ;
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1) ;
/*
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_function) ;
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &outfile) ;
*/
return handle ;
}
int main (void)
{
vector<CURL *> handles;
CURLM *multi_handle;
int still_running ;
int msgs_left ;
int num_handles (3) ;
handles.reserve(num_handles) ;
CURLMsg *msg ;
string site
("http://getquote.icicidirect.com/trading/equity/trading_stock_quote.asp")
;
vector<string> codes ;
vector<string> sites ;
codes.push_back ("ICIBAN") ;
codes.push_back ("HINFC") ;
codes.push_back ("DLFLIM") ;
char error_buffer[CURL_ERROR_SIZE] ;
for (int i = 0; i < num_handles; ++i)
{
ostringstream os ;
os << "http://getquote.icicidirect.com/trading/equity/trading_stock_quote.asp"
<< "?Symbol=" << codes[i] << ends ;
sites.push_back (os.str()) ;
handles.push_back (set_handle(sites[i], codes[i], i)) ;
}
for (int i = 0; i < num_handles; ++i)
multi_handle = curl_multi_init();
for (int i=0; i<num_handles; i++)
curl_multi_add_handle(multi_handle, handles[i]);
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
while(still_running) {
struct timeval timeout;
int rc; /* select() return code */
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc)
{
case -1:
cout << "SELECT ERROR" << endl ;
break;
case 0:
cout << "TIME OUT" << endl ;
break;
default:
cout << "IN DEFAULT" << endl ;
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running)) ;
break;
}
}
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<num_handles)); ++idx)
{
found = (msg->easy_handle == handles[idx]);
cout << codes[idx] << " transfer completed with status "
<< msg->data.result << endl ;
if (files[idx].fp) fclose (files[idx].fp) ;
}
}
}
curl_multi_cleanup(multi_handle);
/* Free the CURL handles */
for (int i=0; i<num_handles; i++)
curl_easy_cleanup(handles[i]);
handles.clear() ;
}
===========================
Received on 2007-08-10