Commit 1a05a90f authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

David Phillips' FD_SETSIZE fix

parent dcea109b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -6,6 +6,10 @@

                                  Changelog

Daniel (18 November 2004)
- David Phillips fixed libcurl to not crash anymore when more than FD_SETSIZE
  file descriptors are in use. Test case 518 added to verify.

Daniel (15 November 2004)
- To test my fix for the CURLINFO_REDIRECT_TIME bug, I added time_redirect and
  num_redirects support to the -w writeout option for the command line tool.
+3 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ This release includes the following changes:

This release includes the following bugfixes:

 o now gracefully bails out when exceeding FD_SETSIZE file descriptors
 o CURLINFO_REDIRECT_TIME works
 o building with gssapi libs and hdeaders in the default dirs
 o curl_getdate() parsing of dates later than year 2037 with 32 bit time_t
@@ -43,6 +44,7 @@ advice from friends like these:

 Peter Wullinger, Guillaume Arluison, Alexander Krasnostavsky, Mohun Biswas,
 Tomas Pospisek, Gisle Vanem, Dan Fandrich, Paul Nolan, Andres Garcia,
 Tim Sneddon, Ian Gulliver, Jean-Philippe Barrette-LaPierre, Jeff Phillips
 Tim Sneddon, Ian Gulliver, Jean-Philippe Barrette-LaPierre, Jeff Phillips,
 Wojciech Zwiefka, David Phillips

        Thanks! (and sorry if I forgot to mention someone)
+3 −2
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
  memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c	\
  content_encoding.c share.c http_digest.c md5.c http_negotiate.c	\
  http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c	\
  hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c
  hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c	\
  select.c

HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h	\
  progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
@@ -16,4 +17,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
  http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h	\
  share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h	\
  inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h	\
  setup.h transfer.h
  setup.h transfer.h select.h
+3 −16
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@
#include "strerror.h"
#include "connect.h"
#include "memory.h"
#include "select.h"

/* The last #include file should be: */
#include "memdebug.h"
@@ -202,9 +203,6 @@ static
int waitconnect(curl_socket_t sockfd, /* socket */
                long timeout_msec)
{
  fd_set fd;
  fd_set errfd;
  struct timeval interval;
  int rc;
#ifdef mpeix
  /* Call this function once now, and ignore the results. We do this to
@@ -214,18 +212,7 @@ int waitconnect(curl_socket_t sockfd, /* socket */
#endif

  /* now select() until we get connect or timeout */
  FD_ZERO(&fd);
  FD_SET(sockfd, &fd);

  FD_ZERO(&errfd);
  FD_SET(sockfd, &errfd);

  interval.tv_sec = (int)(timeout_msec/1000);
  timeout_msec -= interval.tv_sec*1000;

  interval.tv_usec = timeout_msec*1000;

  rc = select(sockfd+1, NULL, &fd, &errfd, &interval);
  rc = Curl_select(CURL_SOCKET_BAD, sockfd, timeout_msec);
  if(-1 == rc)
    /* error, no connect here, try next */
    return WAITCONN_SELECT_ERROR;
@@ -234,7 +221,7 @@ int waitconnect(curl_socket_t sockfd, /* socket */
    /* timeout, no connect today */
    return WAITCONN_TIMEOUT;

  if(FD_ISSET(sockfd, &errfd))
  if(rc & CSELECT_ERR)
    /* error condition caught */
    return WAITCONN_FDSET_ERROR;

+7 −26
Original line number Diff line number Diff line
@@ -34,9 +34,6 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)

@@ -96,6 +93,7 @@
#include "strerror.h"
#include "memory.h"
#include "inet_ntop.h"
#include "select.h"

#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
@@ -162,8 +160,7 @@ static void freedirs(struct FTP *ftp)
 */
static CURLcode AllowServerConnect(struct connectdata *conn)
{
  fd_set rdset;
  struct timeval dt;
  int timeout_ms;
  struct SessionHandle *data = conn->data;
  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
  struct timeval now = Curl_tvnow();
@@ -171,10 +168,6 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
  long timeout = data->set.connecttimeout?data->set.connecttimeout:
    (data->set.timeout?data->set.timeout: 0);

  FD_ZERO(&rdset);

  FD_SET(sock, &rdset);

  if(timeout) {
    timeout -= timespent;
    if(timeout<=0) {
@@ -184,10 +177,9 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
  }

  /* we give the server 60 seconds to connect to us, or a custom timeout */
  dt.tv_sec = (int)(timeout?timeout:60);
  dt.tv_usec = 0;
  timeout_ms = (timeout?timeout:60) * 1000;

  switch (select(sock+1, &rdset, NULL, NULL, &dt)) {
  switch (Curl_select(sock, CURL_SOCKET_BAD, timeout_ms)) {
  case -1: /* error */
    /* let's die here */
    failf(data, "Error while waiting for server connect");
@@ -250,9 +242,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
  ssize_t gotbytes;
  char *ptr;
  long timeout;              /* timeout in seconds */
  struct timeval interval;
  fd_set rkeepfd;
  fd_set readfd;
  int interval_ms;
  struct SessionHandle *data = conn->data;
  char *line_start;
  int code=0; /* default ftp "error code" to return */
@@ -264,13 +254,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
  if (ftpcode)
    *ftpcode = 0; /* 0 for errors */

  FD_ZERO (&readfd);            /* clear it */
  FD_SET (sockfd, &readfd);     /* read socket */

  /* get this in a backup variable to be able to restore it on each lap in the
     select() loop */
  rkeepfd = readfd;

  ptr=buf;
  line_start = buf;

@@ -304,11 +287,9 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
    }

    if(!ftp->cache) {
      readfd = rkeepfd;            /* set every lap */
      interval.tv_sec = 1; /* use 1 second timeout intervals */
      interval.tv_usec = 0;
      interval_ms = 1 * 1000;  /* use 1 second timeout intervals */

      switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
      switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) {
      case -1: /* select() error, stop reading */
        result = CURLE_RECV_ERROR;
        failf(data, "FTP response aborted due to select() error: %d", errno);
Loading