← Commit list

879a1514c3

Viktor Szakats
Viktor Szakats
2026-06-12
SUCCESS Duration: 227s

Subject

socket: introduce `SOCK_EAGAIN()` and use it

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/cf-socket.c+18 -50
@@ -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];
lib/curl_setup.h+9 -0
@@ -1137,6 +1137,15 @@ typedef unsigned int curl_bit;
#define SOCKEWOULDBLOCK EWOULDBLOCK
#endif
+/* The socket error may be EWOULDBLOCK or on some systems EAGAIN when
+ it returned due to its inability to send/read data without blocking.
+ We treat both error codes the same here. */
+#if !defined(USE_WINSOCK) && EAGAIN != SOCKEWOULDBLOCK
+#define SOCK_EAGAIN(e) ((e) == SOCKEWOULDBLOCK || (e) == EAGAIN)
+#else
+#define SOCK_EAGAIN(e) ((e) == SOCKEWOULDBLOCK)
+#endif
+
/*
* Macro argv_item_t hides platform details to code using it.
*/
lib/socketpair.c+12 -24
@@ -232,16 +232,9 @@ static int wakeup_inet(curl_socket_t socks[2], bool nonblocking)
/* Do not block forever */
if(curlx_timediff_ms(curlx_now(), start) > (60 * 1000))
goto error;
- 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
) {
continue;
@@ -320,15 +313,12 @@ int Curl_wakeup_signal(curl_socket_t socks[2])
err = 0;
if(wakeup_write(socks[1], buf, sizeof(buf)) < 0) {
err = SOCKERRNO;
-#ifdef USE_WINSOCK
- if(err == SOCKEWOULDBLOCK)
- err = 0; /* wakeup is already ongoing */
-#else
- if(SOCKEINTR == err)
+#ifndef USE_WINSOCK
+ if(err == SOCKEINTR)
continue;
- if((err == SOCKEWOULDBLOCK) || (err == EAGAIN))
- err = 0; /* wakeup is already ongoing */
#endif
+ if(SOCK_EAGAIN(err))
+ err = 0; /* wakeup is already ongoing */
}
break;
}
@@ -346,15 +336,13 @@ CURLcode Curl_wakeup_consume(curl_socket_t socks[2], bool all)
if(!rc)
break;
else if(rc < 0) {
-#ifdef USE_WINSOCK
- if(SOCKERRNO == SOCKEWOULDBLOCK)
- break;
-#else
- if(SOCKEINTR == SOCKERRNO)
+ int sockerr = SOCKERRNO;
+#ifndef USE_WINSOCK
+ if(sockerr == SOCKEINTR)
continue;
- if((SOCKERRNO == SOCKEWOULDBLOCK) || (SOCKERRNO == EAGAIN))
- break;
#endif
+ if(SOCK_EAGAIN(sockerr))
+ break;
result = CURLE_READ_ERROR;
break;
}
lib/vquic/vquic.c+9 -11
@@ -165,12 +165,10 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf,
;
if(!curlx_sztouz(rv, psent)) {
- switch(SOCKERRNO) {
- case EAGAIN:
-#if EAGAIN != SOCKEWOULDBLOCK
- case SOCKEWOULDBLOCK:
-#endif
+ int sockerr = SOCKERRNO;
+ if(SOCK_EAGAIN(sockerr))
return CURLE_AGAIN;
+ switch(sockerr) {
case SOCKEMSGSIZE:
/* UDP datagram is too large; caused by PMTUD. Let it be lost. */
*psent = pktlen;
@@ -179,13 +177,13 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf,
if(pktlen > gsolen) {
/* GSO failure */
infof(data, "sendmsg() returned %zd (errno %d); disable GSO", rv,
- SOCKERRNO);
+ sockerr);
qctx->no_gso = TRUE;
return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent);
}
FALLTHROUGH();
default:
- failf(data, "sendmsg() returned %zd (errno %d)", rv, SOCKERRNO);
+ failf(data, "sendmsg() returned %zd (errno %d)", rv, sockerr);
result = CURLE_SEND_ERROR;
goto out;
}
@@ -206,7 +204,7 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf,
;
if(!curlx_sztouz(rv, psent)) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
result = CURLE_AGAIN;
goto out;
}
@@ -487,7 +485,7 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf,
(SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE))
;
if(mcount == -1) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
CURL_TRC_CF(data, cf, "ingress, recvmmsg -> EAGAIN");
goto out;
}
@@ -574,7 +572,7 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf,
(SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE))
;
if(!curlx_sztouz(rc, &nread)) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
goto out;
}
if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) {
@@ -644,7 +642,7 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf,
(SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE))
;
if(!curlx_sztouz(rv, &nread)) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
CURL_TRC_CF(data, cf, "ingress, recvfrom -> EAGAIN");
goto out;
}
lib/vtls/rustls.c+8 -2
@@ -45,6 +45,12 @@
#include "curlx/base64.h"
#endif
+#if EAGAIN != EWOULDBLOCK
+#define RAW_EAGAIN(e) ((e) == EWOULDBLOCK || (e) == EAGAIN)
+#else
+#define RAW_EAGAIN(e) ((e) == EWOULDBLOCK)
+#endif
+
struct rustls_ssl_backend_data {
const struct rustls_client_config *config;
struct rustls_connection *conn;
@@ -160,7 +166,7 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf,
io_ctx.data = data;
io_error = rustls_connection_read_tls(backend->conn, read_cb, &io_ctx,
&tls_bytes_read);
- if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
+ if(RAW_EAGAIN(io_error)) {
*err = CURLE_AGAIN;
return -1;
}
@@ -270,7 +276,7 @@ static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data,
while(rustls_connection_wants_write(rconn)) {
io_error = rustls_connection_write_tls(rconn, write_cb, &io_ctx,
&tlswritten);
- if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
+ if(RAW_EAGAIN(io_error)) {
CURL_TRC_CF(data, cf, "cf_send: EAGAIN after %zu bytes",
tlswritten_total);
return CURLE_AGAIN;
src/tool_cb_rea.c+1 -1
@@ -109,7 +109,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
#ifndef CURL_WINDOWS_UWP
rc = sread(per->infd, buffer, curlx_uztosi(sz * nmemb));
if(rc < 0) {
- if(SOCKERRNO == SOCKEWOULDBLOCK) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
errno = 0;
config->readbusy = TRUE;
return CURL_READFUNC_PAUSE;
tests/server/sws.c+6 -7
@@ -976,7 +976,7 @@ static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req)
retry:
written = swrite(sock, buffer, num);
if(written < 0) {
- if((SOCKEWOULDBLOCK == SOCKERRNO) || (EAGAIN == SOCKERRNO)) {
+ if(SOCK_EAGAIN(SOCKERRNO)) {
curlx_wait_ms(10);
goto retry;
}
@@ -1133,8 +1133,7 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req)
logmsg("Got %zd bytes from client", got);
}
- if((got == -1) &&
- ((SOCKERRNO == EAGAIN) || (SOCKERRNO == SOCKEWOULDBLOCK))) {
+ if((got == -1) && SOCK_EAGAIN(SOCKERRNO)) {
int rc;
fd_set input;
fd_set output;
@@ -1194,7 +1193,7 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req)
else if(got < 0) {
char errbuf[STRERROR_LEN];
int error = SOCKERRNO;
- if(EAGAIN == error || SOCKEWOULDBLOCK == error) {
+ if(SOCK_EAGAIN(error)) {
/* nothing to read at the moment */
return 0;
}
@@ -1335,7 +1334,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
if(rc) {
error = SOCKERRNO;
- if((error == SOCKEINPROGRESS) || (error == SOCKEWOULDBLOCK)) {
+ if((error == SOCKEINPROGRESS) || SOCK_EAGAIN(error)) {
fd_set output;
struct timeval timeout = { 0 };
timeout.tv_sec = 1; /* 1000 ms */
@@ -1353,7 +1352,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
error = SOCKERRNO;
if((error == 0) || (SOCKEISCONN == error))
goto success;
- else if((error != SOCKEINPROGRESS) && (error != SOCKEWOULDBLOCK))
+ else if((error != SOCKEINPROGRESS) && !SOCK_EAGAIN(error))
goto error;
}
else if(!rc) {
@@ -1822,7 +1821,7 @@ static curl_socket_t accept_connection(curl_socket_t sock)
if(msgsock == CURL_SOCKET_BAD) {
error = SOCKERRNO;
- if(EAGAIN == error || SOCKEWOULDBLOCK == error) {
+ if(SOCK_EAGAIN(error)) {
/* nothing to accept */
return 0;
}