socket: introduce `SOCK_EAGAIN()` and use it
No binary (build failed)
—
(log yok)
| @@ -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]; | |
| @@ -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. | |
| */ | |
| @@ -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; | |
| } | |
| @@ -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; | |
| } | |
| @@ -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; | |
| @@ -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; | |
| @@ -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; | |
| } | |