MINOR: tree-wide: always consider EWOULDBLOCK in addition to EAGAIN
Some older systems may routinely return EWOULDBLOCK for some syscalls
while we tend to check only for EAGAIN nowadays. Modern systems define
EWOULDBLOCK as EAGAIN so that solves it, but on a few older ones (AIX,
VMS etc) both are different, and for portability we'd need to test for
both or we never know if we risk to confuse some status codes with
plain errors.
There were few entries, the most annoying ones are the switch/case
because they require to only add the entry when it differs, but the
other ones are really trivial.
diff --git a/src/check.c b/src/check.c
index c39561a..fdc82f5 100644
--- a/src/check.c
+++ b/src/check.c
@@ -369,7 +369,7 @@
*/
static inline int unclean_errno(int err)
{
- if (err == EAGAIN || err == EINPROGRESS ||
+ if (err == EAGAIN || err == EWOULDBLOCK || err == EINPROGRESS ||
err == EISCONN || err == EALREADY)
return 0;
return err;
diff --git a/src/connection.c b/src/connection.c
index bc47ac8..d37ad76 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -811,7 +811,7 @@
if (ret < 0) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_recv(conn->handle.fd);
goto not_ready;
}
@@ -1287,7 +1287,7 @@
if (ret < 0) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_recv(conn->handle.fd);
goto not_ready;
}
@@ -1581,7 +1581,7 @@
if (errno == EINTR) {
continue;
}
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_recv(conn->handle.fd);
goto not_ready;
}
diff --git a/src/dns.c b/src/dns.c
index 9785c6e..4a776a1 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -101,7 +101,7 @@
ret = send(fd, buf, len, 0);
if (ret < 0) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
struct ist myist;
myist = ist2(buf, len);
@@ -155,7 +155,7 @@
return -1;
if ((ret = recv(fd, data, size, 0)) < 0) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_recv(fd);
return 0;
}
@@ -333,7 +333,7 @@
ret = send(fd, dns_msg_trash, len, 0);
if (ret < 0) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_send(fd);
goto out;
}
diff --git a/src/fd.c b/src/fd.c
index c2dfcf1..c983b8c 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -666,7 +666,7 @@
ret = poll(poll_events, fd - start, 0);
if (ret >= 0)
break;
- } while (errno == EAGAIN || errno == EINTR || errno == ENOMEM);
+ } while (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR || errno == ENOMEM);
if (ret)
ret = fd - start;
diff --git a/src/log.c b/src/log.c
index 36d6d36..de9561d 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1725,7 +1725,7 @@
if (sent < 0) {
static char once;
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
_HA_ATOMIC_INC(&dropped_logs);
else if (!once) {
once = 1; /* note: no need for atomic ops here */
@@ -3533,7 +3533,7 @@
if (ret < 0) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
fd_cant_recv(fd);
goto out;
}
diff --git a/src/mworker.c b/src/mworker.c
index 2bc3b77..ccfcb5c 100644
--- a/src/mworker.c
+++ b/src/mworker.c
@@ -384,7 +384,7 @@
if (ret == -1) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_recv(fd);
return;
}
diff --git a/src/proto_quic.c b/src/proto_quic.c
index b7d50df..eb3a316 100644
--- a/src/proto_quic.c
+++ b/src/proto_quic.c
@@ -467,9 +467,9 @@
/* should normally not happen but if so, indicates that it's OK */
conn->flags &= ~CO_FL_WAIT_L4_CONN;
}
- else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
+ else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
char *msg;
- if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRNOTAVAIL) {
msg = "no free ports";
conn->err_code = CO_ER_FREE_PORTS;
}
diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c
index c63f02a..b244dd1 100644
--- a/src/proto_sockpair.c
+++ b/src/proto_sockpair.c
@@ -489,6 +489,9 @@
}
switch (errno) {
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
case EAGAIN:
ret = CO_AC_DONE; /* nothing more to accept */
if (fdtab[l->rx.fd].state & (FD_POLL_HUP|FD_POLL_ERR)) {
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 4aaac9d..738d2d1 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -514,9 +514,9 @@
/* should normally not happen but if so, indicates that it's OK */
conn->flags &= ~CO_FL_WAIT_L4_CONN;
}
- else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
+ else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
char *msg;
- if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRNOTAVAIL) {
msg = "no free ports";
conn->err_code = CO_ER_FREE_PORTS;
}
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 663369d..2db4fa2 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -298,9 +298,9 @@
else if (errno == EISCONN) {
conn->flags &= ~CO_FL_WAIT_L4_CONN;
}
- else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
+ else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
char *msg;
- if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EADDRNOTAVAIL) {
msg = "can't connect to destination unix socket, check backlog size on the server";
conn->err_code = CO_ER_FREE_PORTS;
}
diff --git a/src/quic_sock.c b/src/quic_sock.c
index 3baf3fd..b6d2d18 100644
--- a/src/quic_sock.c
+++ b/src/quic_sock.c
@@ -289,7 +289,7 @@
do {
ret = recvfrom(fd, dgram_buf, max_sz, 0,
(struct sockaddr *)&saddr, &saddrlen);
- if (ret < 0 && errno == EAGAIN) {
+ if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
fd_cant_recv(fd);
goto out;
}
@@ -339,7 +339,7 @@
if (ret < try)
break;
}
- else if (ret == 0 || errno == EAGAIN || errno == ENOTCONN || errno == EINPROGRESS) {
+ else if (ret == 0 || errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOTCONN || errno == EINPROGRESS) {
/* TODO must be handle properly. It is justified for UDP ? */
ABORT_NOW();
}
diff --git a/src/raw_sock.c b/src/raw_sock.c
index cc72e60..b161f90 100644
--- a/src/raw_sock.c
+++ b/src/raw_sock.c
@@ -94,7 +94,7 @@
if (ret == 0)
goto out_read0;
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* there are two reasons for EAGAIN :
* - nothing in the socket buffer (standard)
* - pipe is full
@@ -191,7 +191,7 @@
SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
if (ret <= 0) {
- if (ret == 0 || errno == EAGAIN) {
+ if (ret == 0 || errno == EAGAIN || errno == EWOULDBLOCK) {
fd_cant_send(conn->handle.fd);
break;
}
@@ -301,7 +301,7 @@
else if (ret == 0) {
goto read0;
}
- else if (errno == EAGAIN || errno == ENOTCONN) {
+ else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOTCONN) {
/* socket buffer exhausted */
fd_cant_recv(conn->handle.fd);
break;
@@ -395,7 +395,7 @@
if (!count)
fd_stop_send(conn->handle.fd);
}
- else if (ret == 0 || errno == EAGAIN || errno == ENOTCONN || errno == EINPROGRESS) {
+ else if (ret == 0 || errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOTCONN || errno == EINPROGRESS) {
/* nothing written, we need to poll for write first */
fd_cant_send(conn->handle.fd);
break;
diff --git a/src/sock.c b/src/sock.c
index 7ccdbd3..f4d8ba4 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -126,6 +126,9 @@
sockaddr_free(&addr);
switch (errno) {
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
case EAGAIN:
ret = CO_AC_DONE; /* nothing more to accept */
if (fdtab[l->rx.fd].state & (FD_POLL_HUP|FD_POLL_ERR)) {
@@ -925,7 +928,7 @@
goto shut;
if (len < 0) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* connection not closed yet */
fd_cant_recv(fd);
break;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index fd2aff9..9212186 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6503,7 +6503,7 @@
/* For SSL_ERROR_SYSCALL, make sure to clear the error
* stack before shutting down the connection for
* reading. */
- if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN))
+ if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN || errno == EWOULDBLOCK))
goto clear_ssl_error;
/* otherwise it's a real error */
goto out_error;