cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl_easy_duphandle() and multi_interface problem

From: taz3\.taz <taz3.taz_at_laposte.net>
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