diff --git a/CHANGES b/CHANGES index c58379095b9bfdde97d355f3c70a4cc6cab2f087..22d356454e05745c95d8ea56e3a9ec9fd5353fa4 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ Changelog +Daniel (16 January 2007) +- Armel Asselin improved libcurl to behave a lot better when an easy handle + doing an FTP transfer is removed from a multi handle before completion. The + fix also fixed the "alive counter" to be correct on "premature removal" for + all protocols. + Dan F (16 January 2007) - Fixed a small memory leak in tftp uploads discovered by curl's memory leak detector. Also changed tftp downloads to URL-unescape the downloaded diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 5f2ec0a70c7668d14a9396286a0b44731717af4c..1aa4c497a9fd49fd2778109d7e489c9138c6edb9 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -51,6 +51,8 @@ This release includes the following bugfixes: o base64 encoding/decoding works on non-ASCII platforms o large file downloads o CURLOPT_COOKIELIST set to "ALL" crash + o easy handle removal from multi handle before completion + o TFTP upload memory leak Other curl-related news: @@ -71,6 +73,7 @@ advice from friends like these: Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell, Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd, Robson Braga Araujo, David McCreedy, Robert Foreman, Nathanael Nerode, - Victor Snezhko, Linus Nielsen Feltzing, Toby Peterson + Victor Snezhko, Linus Nielsen Feltzing, Toby Peterson, Dan Fandrich, + Armel Asselin Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/file.c b/lib/file.c index 602299d010135b41894b7e4b820ce62ae3d1c0ed..b247a7736e60cc8fa51f0f2b5361c9eae58d1dbb 100644 --- a/lib/file.c +++ b/lib/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -165,7 +165,7 @@ CURLcode Curl_file_connect(struct connectdata *conn) file->fd = fd; if(!conn->data->set.upload && (fd == -1)) { failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path); - Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE); + Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); return CURLE_FILE_COULDNT_READ_FILE; } @@ -173,10 +173,11 @@ CURLcode Curl_file_connect(struct connectdata *conn) } CURLcode Curl_file_done(struct connectdata *conn, - CURLcode status) + CURLcode status, bool premature) { struct FILEPROTO *file = conn->data->reqdata.proto.file; (void)status; /* not used */ + (void)premature; /* not used */ Curl_safefree(file->freepath); if(file->fd != -1) diff --git a/lib/file.h b/lib/file.h index f78acfe63b3dcdd55f0d1be40c8d0c9d05033fb9..20a1c4c063e7498b6db654117cdcc8a1be461dd1 100644 --- a/lib/file.h +++ b/lib/file.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,7 +25,7 @@ ***************************************************************************/ #ifndef CURL_DISABLE_FILE CURLcode Curl_file(struct connectdata *, bool *done); -CURLcode Curl_file_done(struct connectdata *, CURLcode); +CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature); CURLcode Curl_file_connect(struct connectdata *); #endif #endif diff --git a/lib/ftp.c b/lib/ftp.c index 4b6139edf841f7bd556dfe2642974fa9dbc48279..900def4bba84f33cf323195fbea230298187e163 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -2964,7 +2964,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn, * * Input argument is already checked for validity. */ -CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) +CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature) { struct SessionHandle *data = conn->data; struct FTP *ftp = data->reqdata.proto.ftp; @@ -2998,8 +2998,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) /* the connection stays alive fine even though this happened */ /* fall-through */ case CURLE_OK: /* doesn't affect the control connection's status */ - ftpc->ctl_valid = was_ctl_valid; - break; + if (!premature) { + ftpc->ctl_valid = was_ctl_valid; + break; + } + /* until we cope better with prematurely ended requests, let them + * fallback as if in complete failure */ default: /* by default, an error means the control connection is wedged and should not be used anymore */ ftpc->ctl_valid = FALSE; @@ -3048,7 +3052,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; - if(!ftp->no_transfer && !status) { + if(!ftp->no_transfer && !status && !premature) { /* * Let's see what the server says about the transfer we just performed, * but lower the timeout as sometimes this connection has died while the @@ -3081,7 +3085,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) } } - if(result) + if(result || premature) /* the response code from the transfer showed an error already so no use checking further */ ; @@ -3123,7 +3127,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) ftpc->dont_check = FALSE; /* Send any post-transfer QUOTE strings? */ - if(!status && !result && data->set.postquote) + if(!status && !result && !premature && data->set.postquote) result = ftp_sendquote(conn, data->set.postquote); return result; diff --git a/lib/ftp.h b/lib/ftp.h index c85d89e4a8ade4c4fac05a7909c1712a6d511a29..2949d3259dd5a43223d9707063b1bad075e7e467 100644 --- a/lib/ftp.h +++ b/lib/ftp.h @@ -25,7 +25,7 @@ #ifndef CURL_DISABLE_FTP CURLcode Curl_ftp(struct connectdata *conn, bool *done); -CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode); +CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature); CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done); CURLcode Curl_ftp_disconnect(struct connectdata *conn); CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); diff --git a/lib/http.c b/lib/http.c index 0387298c1ff6cc8f0a2271949fd3725789094baf..babe3f11125adb4ea557ac802a5d81d5c6195402 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1503,11 +1503,12 @@ int Curl_https_getsock(struct connectdata *conn, */ CURLcode Curl_http_done(struct connectdata *conn, - CURLcode status) + CURLcode status, bool premature) { struct SessionHandle *data = conn->data; struct HTTP *http =data->reqdata.proto.http; struct Curl_transfer_keeper *k = &data->reqdata.keep; + (void)premature; /* not used */ /* set the proper values (possibly modified on POST) */ conn->fread = data->set.fread; /* restore */ diff --git a/lib/http.h b/lib/http.h index 1c8ee7e3905be865b755cb61b4af7aca5d297a44..7b4b6339a174467dd6e0f0cf1f06811cd819344c 100644 --- a/lib/http.h +++ b/lib/http.h @@ -35,7 +35,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, /* protocol-specific functions set up to be called by the main engine */ CURLcode Curl_http(struct connectdata *conn, bool *done); -CURLcode Curl_http_done(struct connectdata *, CURLcode); +CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature); CURLcode Curl_http_connect(struct connectdata *conn, bool *done); CURLcode Curl_https_connecting(struct connectdata *conn, bool *done); int Curl_https_getsock(struct connectdata *conn, diff --git a/lib/multi.c b/lib/multi.c index 0411cc908c907cfc63cc1e0e9c1c8bc69e69caa4..e10f5e43448dfe9b88a2744f005d4ab323661ed6 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -512,9 +512,11 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, } if(easy) { + bool premature = easy->state != CURLM_STATE_COMPLETED; + /* If the 'state' is not INIT or COMPLETED, we might need to do something nice to put the easy_handle in a good known state when this returns. */ - if(easy->state != CURLM_STATE_COMPLETED) + if(premature) /* this handle is "alive" so we need to count down the total number of alive connections when this is removed */ multi->num_alive--; @@ -547,7 +549,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, /* Curl_done() clears the conn->data field to lose the association between the easy handle and the connection */ - Curl_done(&easy->easy_conn, easy->result); + Curl_done(&easy->easy_conn, easy->result, premature); if(easy->easy_conn) /* the connection is still alive, set back the association to enable @@ -802,7 +804,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, char *gotourl; Curl_posttransfer(easy->easy_handle); - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); + easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE); /* We make sure that the pipe broken flag is reset because in this case, it isn't an actual break */ easy->easy_handle->state.pipe_broke = FALSE; @@ -950,7 +952,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(easy->result) { /* failure detected */ Curl_posttransfer(easy->easy_handle); - Curl_done(&easy->easy_conn, easy->result); + Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ } @@ -1017,7 +1019,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(easy->easy_handle); - Curl_done(&easy->easy_conn, easy->result); + Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ } @@ -1050,7 +1052,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(easy->easy_handle); - Curl_done(&easy->easy_conn, easy->result); + Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ } @@ -1169,7 +1171,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, easy->easy_conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; } Curl_posttransfer(easy->easy_handle); - Curl_done(&easy->easy_conn, easy->result); + Curl_done(&easy->easy_conn, easy->result, FALSE); } else if(TRUE == done) { char *newurl; @@ -1188,7 +1190,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, newurl = easy->easy_handle->reqdata.newurl; easy->easy_handle->reqdata.newurl = NULL; } - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); + easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE); if(easy->result == CURLE_OK) easy->result = Curl_follow(easy->easy_handle, newurl, retry); if(CURLE_OK == easy->result) { @@ -1224,7 +1226,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if (!easy->easy_handle->state.cancelled) { /* post-transfer command */ - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); + easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE); /* after we have DONE what we're supposed to do, go COMPLETED, and it doesn't matter what the Curl_done() returned! */ diff --git a/lib/ssh.c b/lib/ssh.c index ed596be54e7eb889adab83dce63beac79fd08168..9d277a3d5cb43fee00a9d271e06f0352103972c3 100644 --- a/lib/ssh.c +++ b/lib/ssh.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * -* Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. +* Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -568,9 +568,11 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done) return res; } -CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status) +CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status, + bool premature) { struct SSHPROTO *scp = conn->data->reqdata.proto.ssh; + (void)premature; /* not used */ Curl_safefree(scp->path); scp->path = NULL; @@ -891,9 +893,11 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done) return res; } -CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status) +CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status, + bool premature) { struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh; + (void)premature; /* not used */ Curl_safefree(sftp->path); sftp->path = NULL; diff --git a/lib/ssh.h b/lib/ssh.h index b491a76849fe6b2ec35aa7e7fd5d642dfa087de4..d9144903ba26eb23a8b5cb69df79acb825f88648 100644 --- a/lib/ssh.h +++ b/lib/ssh.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -29,7 +29,7 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done); CURLcode Curl_scp_do(struct connectdata *conn, bool *done); -CURLcode Curl_scp_done(struct connectdata *conn, CURLcode); +CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature); ssize_t Curl_scp_send(struct connectdata *conn, int sockindex, void *mem, size_t len); @@ -37,7 +37,7 @@ ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex, char *mem, size_t len); CURLcode Curl_sftp_do(struct connectdata *conn, bool *done); -CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode); +CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode, bool premature); ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex, void *mem, size_t len); diff --git a/lib/telnet.c b/lib/telnet.c index 14ff11d2c59b8bb294b03142f918088c90908d06..97d22b788abd1a138a0a5ab17f05e42dbe1f0080 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1073,10 +1073,11 @@ void telrcv(struct connectdata *conn, } } -CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status) +CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature) { struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet; (void)status; /* unused */ + (void)premature; /* not used */ curl_slist_free_all(tn->telnet_vars); diff --git a/lib/telnet.h b/lib/telnet.h index bb30f083fff350a2cd196ea0b2965ca44f661ada..693abf3f86d8ac659e7522d703a4a34cab010437 100644 --- a/lib/telnet.h +++ b/lib/telnet.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,6 +25,6 @@ ***************************************************************************/ #ifndef CURL_DISABLE_TELNET CURLcode Curl_telnet(struct connectdata *conn, bool *done); -CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode); +CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature); #endif #endif diff --git a/lib/tftp.c b/lib/tftp.c index 6f1dfaa3605d73548c169171611938516693b1ed..9ec1a15122c6eab4421703a839429f84a756d92c 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -77,6 +77,7 @@ #include "connect.h" #include "strerror.h" #include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "url.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -288,7 +289,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) } /* As RFC3617 describes the separator slash is not actually part of the file name so we skip the always-present first letter of the path string. */ - filename = curl_easy_unescape(data, &state->conn->data->reqdata.path[1], 0, NULL); + filename = curl_easy_unescape(data, &state->conn->data->reqdata.path[1], 0, + NULL); snprintf((char *)&state->spacket.data[2], TFTP_BLOCKSIZE, "%s%c%s%c", filename, '\0', mode, '\0'); @@ -622,9 +624,11 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done) * The done callback * **********************************************************/ -CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status) +CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status, + bool premature) { (void)status; /* unused */ + (void)premature; /* not used */ #if 0 free(conn->data->reqdata.proto.tftp); diff --git a/lib/tftp.h b/lib/tftp.h index 1120e26a5335c1bde63df94206b22506dcd5c4d4..c7125417b9938e663c3f38c96d95cb6a1f420152 100644 --- a/lib/tftp.h +++ b/lib/tftp.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,6 +26,6 @@ #ifndef CURL_DISABLE_TFTP CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done); CURLcode Curl_tftp(struct connectdata *conn, bool *done); -CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode); +CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature); #endif #endif diff --git a/lib/transfer.c b/lib/transfer.c index ee3c9851cfdd4a75c4cea7bb20cf4b1ff5e9fa93..45117c7091a10d459728d2703dabd50b4353a92a 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -2303,7 +2303,7 @@ Curl_connect_host(struct SessionHandle *data, to the new URL */ urlchanged = data->change.url_changed; if ((CURLE_OK == res) && urlchanged) { - res = Curl_done(conn, res); + res = Curl_done(conn, res, FALSE); if(CURLE_OK == res) { char *gotourl = strdup(data->change.url); res = Curl_follow(data, gotourl, FALSE); @@ -2379,7 +2379,7 @@ CURLcode Curl_perform(struct SessionHandle *data) if(data->set.connect_only) { /* keep connection open for application to use the socket */ conn->bits.close = FALSE; - res = Curl_done(&conn, CURLE_OK); + res = Curl_done(&conn, CURLE_OK, FALSE); break; } res = Curl_do(&conn, &do_done); @@ -2412,14 +2412,14 @@ CURLcode Curl_perform(struct SessionHandle *data) /* Always run Curl_done(), even if some of the previous calls failed, but return the previous (original) error code */ - res2 = Curl_done(&conn, res); + res2 = Curl_done(&conn, res, FALSE); if(CURLE_OK == res) res = res2; } else /* Curl_do() failed, clean up left-overs in the done-call */ - res2 = Curl_done(&conn, res); + res2 = Curl_done(&conn, res, FALSE); /* * Important: 'conn' cannot be used here, since it may have been closed diff --git a/lib/url.c b/lib/url.c index 123d75b6768fc4537c175cdeec3167dc2ad0c507..91cb57e2e3fdbb552c91f9702e59e145b29d7c02 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4087,7 +4087,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, CURLcode Curl_done(struct connectdata **connp, - CURLcode status) /* an error if this is called after an + CURLcode status, bool premature) /* an error if this is called after an error was detected */ { CURLcode result; @@ -4127,7 +4127,7 @@ CURLcode Curl_done(struct connectdata **connp, /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) - result = conn->curl_done(conn, status); + result = conn->curl_done(conn, status, premature); else result = CURLE_OK; @@ -4193,7 +4193,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) infof(data, "Re-used connection seems dead, get a new one\n"); conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(&conn, result); /* we are so done with this */ + result = Curl_done(&conn, result, FALSE); /* we are so done with this */ /* conn may no longer be a good pointer */ diff --git a/lib/url.h b/lib/url.h index b92467350e0fff65f3aeece9e655a8b661c2caa2..ecbd45f73eefe10f9c1a3f2cbe360edcada55272 100644 --- a/lib/url.h +++ b/lib/url.h @@ -39,7 +39,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, bool *protocol_connect); CURLcode Curl_do(struct connectdata **, bool *done); CURLcode Curl_do_more(struct connectdata *); -CURLcode Curl_done(struct connectdata **, CURLcode); +CURLcode Curl_done(struct connectdata **, CURLcode, bool premature); CURLcode Curl_disconnect(struct connectdata *); CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); diff --git a/lib/urldata.h b/lib/urldata.h index e2cc0d158dd9181aeb70fac8d7f6e2cd633962c6..9537ce36bb817bb28d73080e1ae1b2bfbe0c7916 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -614,7 +614,7 @@ struct Curl_async { within the source when we need to cast between data pointers (such as NULL) and function pointers. */ typedef CURLcode (*Curl_do_more_func)(struct connectdata *); -typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode); +typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool); /*