summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Hoersken <info@marc-hoersken.de>2020-04-12 14:03:38 +0200
committerJay Satiro <raysatiro@yahoo.com>2020-04-12 18:32:14 -0400
commitbe28bc2241212bbcbe4b7ac67ee1882955b5f7f3 (patch)
tree4749d35d26d1623f9a210db0588da7bb069f31af
parentd59090831892210c2b0d38e92b492d6b36a3c70c (diff)
downloadcurl-be28bc2241212bbcbe4b7ac67ee1882955b5f7f3.tar.gz
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
-rw-r--r--lib/gopher.c21
1 files 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 <curl/curl.h>
#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);