]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
gopher: check remaining time left during write busy loop
authorMarc Hoersken <info@marc-hoersken.de>
Sun, 12 Apr 2020 12:03:38 +0000 (14:03 +0200)
committerJay Satiro <raysatiro@yahoo.com>
Sun, 12 Apr 2020 22:32:14 +0000 (18:32 -0400)
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

index b296c62d199db7b8c8a6be038aac7c10498548f9..1c613934daef1d93b21f6b4e517d810722315369 100644 (file)
@@ -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);