select: return error from "lethal" poll/select errors

Adds two new error codes: CURLE_UNRECOVERABLE_POLL and
CURLM_UNRECOVERABLE_POLL one each for the easy and the multi interfaces.

Reported-by: Harry Sintonen
Fixes #8921
Closes #8961
This commit is contained in:
Daniel Stenberg 2022-06-08 11:03:07 +02:00
parent 7007324a6a
commit 5912da253b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
10 changed files with 37 additions and 8 deletions

View File

@ -265,6 +265,8 @@ QUIC connection error. This error may be caused by an SSL library error. QUIC
is the protocol used for HTTP/3 transfers. is the protocol used for HTTP/3 transfers.
.IP "CURLE_SSL_CLIENTCERT (98)" .IP "CURLE_SSL_CLIENTCERT (98)"
SSL Client Certificate required. SSL Client Certificate required.
.IP "CURLE_UNRECOVERABLE_POLL (99)"
An internal call to poll() or select() returned error that is not recoverable.
.IP "CURLE_OBSOLETE*" .IP "CURLE_OBSOLETE*"
These error codes will never be returned. They were used in an old libcurl These error codes will never be returned. They were used in an old libcurl
version and are currently unused. version and are currently unused.
@ -309,6 +311,8 @@ Wakeup is unavailable or failed.
A function was called with a bad parameter. A function was called with a bad parameter.
.IP "CURLM_ABORTED_BY_CALLBACK (11)" .IP "CURLM_ABORTED_BY_CALLBACK (11)"
A multi handle callback returned error. A multi handle callback returned error.
.IP "CURLM_UNRECOVERABLE_POLL (12)"
An internal call to poll() or select() returned error that is not recoverable.
.SH "CURLSHcode" .SH "CURLSHcode"
The "share" interface will return a CURLSHcode to indicate when an error has The "share" interface will return a CURLSHcode to indicate when an error has
occurred. Also consider \fIcurl_share_strerror(3)\fP. occurred. Also consider \fIcurl_share_strerror(3)\fP.

View File

@ -320,6 +320,7 @@ CURLE_TFTP_UNKNOWNID 7.15.0
CURLE_TOO_MANY_REDIRECTS 7.5 CURLE_TOO_MANY_REDIRECTS 7.5
CURLE_UNKNOWN_OPTION 7.21.5 CURLE_UNKNOWN_OPTION 7.21.5
CURLE_UNKNOWN_TELNET_OPTION 7.7 7.21.5 CURLE_UNKNOWN_TELNET_OPTION 7.7 7.21.5
CURLE_UNRECOVERABLE_POLL 7.84.0
CURLE_UNSUPPORTED_PROTOCOL 7.1 CURLE_UNSUPPORTED_PROTOCOL 7.1
CURLE_UPLOAD_FAILED 7.16.3 CURLE_UPLOAD_FAILED 7.16.3
CURLE_URL_MALFORMAT 7.1 CURLE_URL_MALFORMAT 7.1
@ -523,6 +524,7 @@ CURLM_OK 7.9.6
CURLM_OUT_OF_MEMORY 7.9.6 CURLM_OUT_OF_MEMORY 7.9.6
CURLM_RECURSIVE_API_CALL 7.59.0 CURLM_RECURSIVE_API_CALL 7.59.0
CURLM_UNKNOWN_OPTION 7.15.4 CURLM_UNKNOWN_OPTION 7.15.4
CURLM_UNRECOVERABLE_POLL 7.84.0
CURLM_WAKEUP_FAILURE 7.68.0 CURLM_WAKEUP_FAILURE 7.68.0
CURLMIMEOPT_FORMESCAPE 7.81.0 CURLMIMEOPT_FORMESCAPE 7.81.0
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0 CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0

View File

@ -613,6 +613,7 @@ typedef enum {
CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */ CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
CURLE_PROXY, /* 97 - proxy handshake error */ CURLE_PROXY, /* 97 - proxy handshake error */
CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */ CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */
CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -75,6 +75,7 @@ typedef enum {
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */ CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
CURLM_ABORTED_BY_CALLBACK, CURLM_ABORTED_BY_CALLBACK,
CURLM_UNRECOVERABLE_POLL,
CURLM_LAST CURLM_LAST
} CURLMcode; } CURLMcode;

View File

@ -306,7 +306,7 @@ int Curl_resolver_getsock(struct Curl_easy *data,
* 2) wait for the timeout period to check for action on ares' sockets. * 2) wait for the timeout period to check for action on ares' sockets.
* 3) tell ares to act on all the sockets marked as "with action" * 3) tell ares to act on all the sockets marked as "with action"
* *
* return number of sockets it worked on * return number of sockets it worked on, or -1 on error
*/ */
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms) static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
@ -338,8 +338,11 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
break; break;
} }
if(num) if(num) {
nfds = Curl_poll(pfd, num, timeout_ms); nfds = Curl_poll(pfd, num, timeout_ms);
if(nfds < 0)
return -1;
}
else else
nfds = 0; nfds = 0;
@ -376,7 +379,8 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
DEBUGASSERT(dns); DEBUGASSERT(dns);
*dns = NULL; *dns = NULL;
waitperform(data, 0); if(waitperform(data, 0) < 0)
return CURLE_UNRECOVERABLE_POLL;
#ifndef HAVE_CARES_GETADDRINFO #ifndef HAVE_CARES_GETADDRINFO
/* Now that we've checked for any last minute results above, see if there are /* Now that we've checked for any last minute results above, see if there are
@ -475,7 +479,8 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
else else
timeout_ms = 1000; timeout_ms = 1000;
waitperform(data, timeout_ms); if(waitperform(data, timeout_ms) < 0)
return CURLE_UNRECOVERABLE_POLL;
result = Curl_resolver_is_resolved(data, entry); result = Curl_resolver_is_resolved(data, entry);
if(result || data->state.async.done) if(result || data->state.async.done)

View File

@ -549,6 +549,8 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
/* wait for activity or timeout */ /* wait for activity or timeout */
pollrc = Curl_poll(fds, numfds, ev->ms); pollrc = Curl_poll(fds, numfds, ev->ms);
if(pollrc < 0)
return CURLE_UNRECOVERABLE_POLL;
after = Curl_now(); after = Curl_now();

View File

@ -1312,6 +1312,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
#else #else
pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */ pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
#endif #endif
if(pollrc < 0)
return CURLM_UNRECOVERABLE_POLL;
if(pollrc > 0) { if(pollrc > 0) {
retcode = pollrc; retcode = pollrc;

View File

@ -352,8 +352,12 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
value). value).
*/ */
r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms); r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
if(r <= 0) if(r <= 0) {
if((r == -1) && (SOCKERRNO == EINTR))
/* make EINTR from select or poll not a "lethal" error */
r = 0;
return r; return r;
}
r = 0; r = 0;
for(i = 0; i < nfds; i++) { for(i = 0; i < nfds; i++) {

View File

@ -317,6 +317,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_SSL_CLIENTCERT: case CURLE_SSL_CLIENTCERT:
return "SSL Client Certificate required"; return "SSL Client Certificate required";
case CURLE_UNRECOVERABLE_POLL:
return "Unrecoverable error in select/poll";
/* error codes not used by current libcurl */ /* error codes not used by current libcurl */
case CURLE_OBSOLETE20: case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24: case CURLE_OBSOLETE24:
@ -400,6 +403,9 @@ curl_multi_strerror(CURLMcode error)
case CURLM_ABORTED_BY_CALLBACK: case CURLM_ABORTED_BY_CALLBACK:
return "Operation was aborted by an application callback"; return "Operation was aborted by an application callback";
case CURLM_UNRECOVERABLE_POLL:
return "Unrecoverable error in select/poll";
case CURLM_LAST: case CURLM_LAST:
break; break;
} }

View File

@ -131,7 +131,8 @@ e95: HTTP/3 error
e96: QUIC connection error e96: QUIC connection error
e97: proxy handshake error e97: proxy handshake error
e98: SSL Client Certificate required e98: SSL Client Certificate required
e99: Unknown error e99: Unrecoverable error in select/poll
e100: Unknown error
m-1: Please call curl_multi_perform() soon m-1: Please call curl_multi_perform() soon
m0: No error m0: No error
m1: Invalid multi handle m1: Invalid multi handle
@ -145,7 +146,8 @@ m8: API function called from within callback
m9: Wakeup is unavailable or failed m9: Wakeup is unavailable or failed
m10: A libcurl function was given a bad argument m10: A libcurl function was given a bad argument
m11: Operation was aborted by an application callback m11: Operation was aborted by an application callback
m12: Unknown error m12: Unrecoverable error in select/poll
m13: Unknown error
s0: No error s0: No error
s1: Unknown share option s1: Unknown share option
s2: Share currently in use s2: Share currently in use