mirror of
https://github.com/curl/curl.git
synced 2026-08-25 07:33:36 +03:00
socket: introduce SOCK_EAGAIN() and use it
To contain the logic of checking for both `EWOULDBLOCK` and/or `EAGAIN` depending on platform/availability. Also to avoid checking for both if they mapp to the same value, and to avoid PP guards around use. This also ensures `EAGAIN` is consistently not checked on Windows, where headers defined it, but `SOCKERRNO` never returns it, because curl maps it to `WSAGetLastError()`. If they map to the same value, checking them both in an `if` expression trips GCC warning `-Wlogical-op` (the same way it triggers duplicate case value error in `switch`). Also: - replace two `switch()` statements with the new macro. - tests/server/sws: make two outliers use the new macro that were only checking for `EWOULDBLOCK` before this patch, in `connect_to()`. - move variables to the left-side of expressions, where missing. - rustls: use a variant of this macro that uses raw `EWOULDBLOCK`. Tried tracing it back to the origins, but I couldn't figure out if this is working as expected on all supported Windows versions in Rust. It seems to be using `GetLastError()`, according to https://docs.rs/system_error/0.2.0/system_error/, which would be probably incorrect. Notes: - it's probably a good idea to assign `SOCKERRNO` to a variable before passing it to this macro. Cherry-picked from #21893 Closes #21992
This commit is contained in:
parent
7c51a33877
commit
879a1514c3
7 changed files with 63 additions and 95 deletions
|
|
@ -939,32 +939,19 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
|||
static CURLcode socket_connect_result(struct Curl_easy *data,
|
||||
const char *ipaddress, int error)
|
||||
{
|
||||
switch(error) {
|
||||
case SOCKEINPROGRESS:
|
||||
case SOCKEWOULDBLOCK:
|
||||
#ifdef EAGAIN
|
||||
#if (EAGAIN) != (SOCKEWOULDBLOCK)
|
||||
/* On some platforms EAGAIN and EWOULDBLOCK are the
|
||||
* same value, and on others they are different, hence
|
||||
* the odd #if
|
||||
*/
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#endif
|
||||
if(error == SOCKEINPROGRESS || SOCK_EAGAIN(error))
|
||||
return CURLE_OK;
|
||||
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
{
|
||||
VERBOSE(char buffer[STRERROR_LEN]);
|
||||
infof(data, "Immediate connect fail for %s: %s", ipaddress,
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
NOVERBOSE((void)ipaddress);
|
||||
}
|
||||
data->state.os_errno = error;
|
||||
/* connect failed */
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
{
|
||||
VERBOSE(char buffer[STRERROR_LEN]);
|
||||
infof(data, "Immediate connect fail for %s: %s", ipaddress,
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
NOVERBOSE((void)ipaddress);
|
||||
}
|
||||
data->state.os_errno = error;
|
||||
/* connect failed */
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
struct cf_socket_ctx {
|
||||
|
|
@ -1560,22 +1547,12 @@ static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
|
||||
if(!curlx_sztouz(rv, pnwritten)) {
|
||||
int sockerr = SOCKERRNO;
|
||||
|
||||
if(
|
||||
#ifdef USE_WINSOCK
|
||||
/* This is how Windows does it */
|
||||
(SOCKEWOULDBLOCK == sockerr)
|
||||
#else
|
||||
/* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||
due to its inability to send off data without blocking. We therefore
|
||||
treat both error codes the same here */
|
||||
(SOCKEWOULDBLOCK == sockerr) ||
|
||||
(EAGAIN == sockerr) || (SOCKEINTR == sockerr) ||
|
||||
(SOCKEINPROGRESS == sockerr)
|
||||
if(SOCK_EAGAIN(sockerr)
|
||||
#ifndef USE_WINSOCK
|
||||
|| (sockerr == SOCKEINTR) || (sockerr == SOCKEINPROGRESS)
|
||||
#endif
|
||||
) {
|
||||
/* EWOULDBLOCK */
|
||||
result = CURLE_AGAIN;
|
||||
result = CURLE_AGAIN; /* EWOULDBLOCK */
|
||||
}
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
|
|
@ -1626,21 +1603,12 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
|
||||
if(!curlx_sztouz(rv, pnread)) {
|
||||
int sockerr = SOCKERRNO;
|
||||
|
||||
if(
|
||||
#ifdef USE_WINSOCK
|
||||
/* This is how Windows does it */
|
||||
(SOCKEWOULDBLOCK == sockerr)
|
||||
#else
|
||||
/* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||
due to its inability to send off data without blocking. We therefore
|
||||
treat both error codes the same here */
|
||||
(SOCKEWOULDBLOCK == sockerr) ||
|
||||
(EAGAIN == sockerr) || (SOCKEINTR == sockerr)
|
||||
if(SOCK_EAGAIN(sockerr)
|
||||
#ifndef USE_WINSOCK
|
||||
|| (sockerr == SOCKEINTR)
|
||||
#endif
|
||||
) {
|
||||
/* EWOULDBLOCK */
|
||||
result = CURLE_AGAIN;
|
||||
result = CURLE_AGAIN; /* EWOULDBLOCK */
|
||||
}
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue