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
1 changed files with 17 additions and 4 deletions

View 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);