]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tree-wide: always consider EWOULDBLOCK in addition to EAGAIN
authorWilly Tarreau <w@1wt.eu>
Mon, 25 Apr 2022 18:32:15 +0000 (20:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 25 Apr 2022 18:32:15 +0000 (20:32 +0200)
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.

14 files changed:
src/check.c
src/connection.c
src/dns.c
src/fd.c
src/log.c
src/mworker.c
src/proto_quic.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_uxst.c
src/quic_sock.c
src/raw_sock.c
src/sock.c
src/ssl_sock.c

index c39561a508fcf57be410932cd607073ad6fcad7e..fdc82f526c689c25fbf7bdf1bc94bef96bd9b5aa 100644 (file)
@@ -369,7 +369,7 @@ static const struct analyze_status analyze_statuses[HANA_STATUS_SIZE] = {           /* 0:
  */
 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;
index bc47ac886c82522e6ff67253a798ed0879bffa8b..d37ad76d96f57db07db7a47931cb3140f4f7f3f5 100644 (file)
@@ -811,7 +811,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
                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 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
                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 @@ int conn_recv_socks4_proxy_response(struct connection *conn)
                        if (errno == EINTR) {
                                continue;
                        }
-                       if (errno == EAGAIN) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                fd_cant_recv(conn->handle.fd);
                                goto not_ready;
                        }
index 9785c6e199e8efb08c291ee80a077c463cb32a04..4a776a1effab32070c6f07e6496d2222fb8f8b98 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -101,7 +101,7 @@ int dns_send_nameserver(struct dns_nameserver *ns, void *buf, size_t len)
 
                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 @@ ssize_t dns_recv_nameserver(struct dns_nameserver *ns, void *data, size_t size)
                        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 @@ static void dns_resolve_send(struct dgram_conn *dgram)
 
                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;
                        }
index c2dfcf1d6d1d18ae1d7183db66097888b46f6757..c983b8c9aa90e2da284d1c054886995ab1134a0c 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -666,7 +666,7 @@ void my_closefrom(int start)
                        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;
index 36d6d36cabaa96d4ab6c477a83a5a7cc35867efe..de9561d84a4adb569f32e43b6e57ad8c16d47f0f 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1725,7 +1725,7 @@ static inline void __do_send_log(struct logsrv *logsrv, int nblogger, int level,
        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 @@ void syslog_fd_handler(int fd)
                        if (ret < 0) {
                                if (errno == EINTR)
                                        continue;
-                               if (errno == EAGAIN)
+                               if (errno == EAGAIN || errno == EWOULDBLOCK)
                                        fd_cant_recv(fd);
                                goto out;
                        }
index 2bc3b776f14646b3ccb78f40e1ed32f4d4ca2f8d..ccfcb5c6b7193279f40a30c73d23e44bb1e0afa5 100644 (file)
@@ -384,7 +384,7 @@ void mworker_accept_wrapper(int fd)
                if (ret == -1) {
                        if (errno == EINTR)
                                continue;
-                       if (errno == EAGAIN) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                fd_cant_recv(fd);
                                return;
                        }
index b7d50df36d7bc0970e2763bdeccdd4b11ee4bc35..eb3a316df321c8c741aff5e71358d7a3624cc3cd 100644 (file)
@@ -467,9 +467,9 @@ int quic_connect_server(struct connection *conn, int flags)
                        /* 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;
                        }
index c63f02ae101ee4d8dda27527d2ab9f6f2efab8d9..b244dd1b369e361b8af1917cc9e859a7d14f0fa6 100644 (file)
@@ -489,6 +489,9 @@ struct connection *sockpair_accept_conn(struct listener *l, int *status)
        }
 
        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)) {
index 4aaac9d82f24baa4044c15c54b2db0fe086a0bfc..738d2d113f8c5c6c7319f6128a35f589b7475912 100644 (file)
@@ -514,9 +514,9 @@ int tcp_connect_server(struct connection *conn, int flags)
                        /* 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;
                        }
index 663369db435341dc60ede186405d39b1804893ea..2db4fa20b0b40bce19f53fdd22c30a7d1071745f 100644 (file)
@@ -298,9 +298,9 @@ static int uxst_connect_server(struct connection *conn, int flags)
                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;
                        }
index 3baf3fd13377d2d92972eec45bc740c7219612bb..b6d2d18dca5e92075519e20dd34e53f06bac5f34 100644 (file)
@@ -289,7 +289,7 @@ void quic_sock_fd_iocb(int fd)
        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 @@ size_t qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t count,
                        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();
                }
index cc72e6023fafa6e0a2574c0f48cf3ea5d620e5c8..b161f90f24a75abb8cdc0aa0d49abe91bacf8569 100644 (file)
@@ -94,7 +94,7 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
                        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 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
                             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 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu
                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 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
                        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;
index 7ccdbd3baaae7b25d4709d9f76b3562ee7181cef..f4d8ba4d07aad435a817427c411d9677f9145d7e 100644 (file)
@@ -126,6 +126,9 @@ struct connection *sock_accept_conn(struct listener *l, int *status)
        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 @@ int sock_drain(struct connection *conn)
                        goto shut;
 
                if (len < 0) {
-                       if (errno == EAGAIN) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                /* connection not closed yet */
                                fd_cant_recv(fd);
                                break;
index fd2aff92a6baba7a96589f7fa41a54044f6f90ce..92121860eade1f3376921f689a50828518d7e908 100644 (file)
@@ -6503,7 +6503,7 @@ static size_t ssl_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu
                        /* 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;