1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

gopher: check remaining time left during write busy loop

Prior to this change gopher's blocking code would block forever,
ignoring any set timeout value.

Assisted-by: Jay Satiro
Reviewed-by: Daniel Stenberg

Similar to #5220 and #5221
Closes #5214
This commit is contained in:
Marc Hoersken 2020-04-12 14:03:38 +02:00 committed by Jay Satiro
parent d590908318
commit be28bc2241

View File

@ -28,6 +28,7 @@
#include <curl/curl.h> #include <curl/curl.h>
#include "transfer.h" #include "transfer.h"
#include "sendf.h" #include "sendf.h"
#include "connect.h"
#include "progress.h" #include "progress.h"
#include "gopher.h" #include "gopher.h"
#include "select.h" #include "select.h"
@ -83,8 +84,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
char *query = data->state.up.query; char *query = data->state.up.query;
char *sel = NULL; char *sel = NULL;
char *sel_org = NULL; char *sel_org = NULL;
timediff_t timeout_ms;
ssize_t amount, k; ssize_t amount, k;
size_t len; size_t len;
int what;
*done = TRUE; /* unconditionally */ *done = TRUE; /* unconditionally */
@ -139,19 +142,29 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
else else
break; break;
timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
if(timeout_ms < 0) {
result = CURLE_OPERATION_TIMEDOUT;
break;
}
if(!timeout_ms || timeout_ms > TIME_T_MAX)
timeout_ms = TIME_T_MAX;
/* Don't busyloop. The entire loop thing is a work-around as it causes a /* 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 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 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 possible to send now will be sent in the doing function repeatedly
until the entire request is sent. until the entire request is sent.
Wait a while for the socket to be writable. Note that this doesn't
acknowledge the timeout.
*/ */
if(SOCKET_WRITABLE(sockfd, 100) < 0) { what = SOCKET_WRITABLE(sockfd, (time_t)timeout_ms);
if(what < 0) {
result = CURLE_SEND_ERROR; result = CURLE_SEND_ERROR;
break; break;
} }
else if(!what) {
result = CURLE_OPERATION_TIMEDOUT;
break;
}
} }
free(sel_org); free(sel_org);