diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2010-08-24 23:14:00 +0200 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2010-08-25 14:21:25 +0200 | 
| commit | cb64c987a062a9c16ab997415a1440182edb069a (patch) | |
| tree | 93a2d9084e84e58608d1dfa1cdeb7fb6f994395a /lib | |
| parent | 67d16160184493c6717e4e572fafed7467af4983 (diff) | |
gopher: fix memory leak and busyloop
The fix for the busyloop really only is a temporary work-around.  It
causes a BLOCKING behavior which is a NO-NO. This function should rather
be split up in a do and a doing piece where the pieces that aren't
possible to send now will be sent in the doing function repeatedly until
the entire request is sent.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/gopher.c | 32 | 
1 files changed, 26 insertions, 6 deletions
| diff --git a/lib/gopher.c b/lib/gopher.c index 2fab6dabe..6fe740f75 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -76,6 +76,8 @@  #include "strequal.h"  #include "gopher.h"  #include "rawstr.h" +#include "select.h" +#include "url.h"  #define _MPRINTF_REPLACE /* use our functions only */  #include <curl/mprintf.h> @@ -122,6 +124,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)    curl_off_t *bytecount = &data->req.bytecount;    char *path = data->state.path;    char *sel; +  char *sel_org = NULL;    ssize_t amount, k;    *done = TRUE; /* unconditionally */ @@ -139,19 +142,21 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)      /* ... then turn ? into TAB for search servers, Veronica, etc. ... */      j = strlen(newp); -    if (j) -      for(i=0; i<j; i++) -        newp[i] = ((newp[i] == '?') ? '\x09' : newp[i]); +    for(i=0; i<j; i++) +      if(newp[i] == '?') +        newp[i] = '\x09';      /* ... and finally unescape */      sel = curl_easy_unescape(data, newp, 0, &len);      if (!sel)        return CURLE_OUT_OF_MEMORY; +    sel_org = sel;    } -  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer -     is sent, which could be sizeable with long selectors. */ +  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is +     sent, which could be sizeable with long selectors. */    k = strlen(sel); +    for(;;) {      result = Curl_write(conn, sockfd, sel, k, &amount);      if (CURLE_OK == result) { /* Which may not have written it all! */ @@ -159,11 +164,26 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)        sel += amount;        if (k < 1)          break; /* but it did write it all */ -    } else { +    } +    else {        failf(data, "Failed sending Gopher request"); +      Curl_safefree(sel_org);        return result;      } +    /* Don't busyloop. The entire loop thing is a work-around as it causes a +       BLOCKING behavior which is a NO-NO. This function should rather be +       split up in a do and a doing piece where the pieces that aren't +       possible to send now will be sent in the doing function repeatedly +       until the entire request is sent. + +       Wait a while for the socket to be writable. Note that this doesn't +       acknowledge the timeout. +    */ +    Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);    } + +  Curl_safefree(sel_org); +    /* We can use Curl_sendf to send the terminal \r\n relatively safely and       save allocing another string/doing another _write loop. */    result = Curl_sendf(sockfd, conn, "\r\n"); | 
