From be28bc2241212bbcbe4b7ac67ee1882955b5f7f3 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Sun, 12 Apr 2020 14:03:38 +0200 Subject: [PATCH] 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 --- lib/gopher.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/gopher.c b/lib/gopher.c index b296c62d1..1c613934d 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -28,6 +28,7 @@ #include #include "transfer.h" #include "sendf.h" +#include "connect.h" #include "progress.h" #include "gopher.h" #include "select.h" @@ -83,8 +84,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) char *query = data->state.up.query; char *sel = NULL; char *sel_org = NULL; + timediff_t timeout_ms; ssize_t amount, k; size_t len; + int what; *done = TRUE; /* unconditionally */ @@ -139,19 +142,29 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) else 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 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. */ - if(SOCKET_WRITABLE(sockfd, 100) < 0) { + what = SOCKET_WRITABLE(sockfd, (time_t)timeout_ms); + if(what < 0) { result = CURLE_SEND_ERROR; break; } + else if(!what) { + result = CURLE_OPERATION_TIMEDOUT; + break; + } } free(sel_org);