From nobody Mon Jun 29 15:54:22 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gprSH1xGnz6jP6B for ; Mon, 29 Jun 2026 15:54:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gprSG6Pw8z3QQp for ; Mon, 29 Jun 2026 15:54:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782748462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Gh5+4LjuymAfPKlPE4xY8RtGttibL8adGs8a+MoJM4k=; b=lP06St5byKq8p6z1NyN4/laNsk6UbE1FjbRmfQv16sE02VgfUymzrw8I/HO4IvgCvM895O VCTqzj6pMnnXjMEyBj7PSTV5i2+PUW1f6mbQ0c1+k+17GgVa+a2TLigxQ4Mf6h4Mx62ctT Q03yR/BUroGD/Wkl4sUTXJbhZCE1khH5Nd3adxoQb3iL/bwPu6pfd9w/jPWSlTrfIRjIn5 OreVI2MmsR7GQHOQmBu8SmqWDhCldX0cFA9cPHrvgOuj/5C5Xh12J+VKfd15NY71VflMFV PMdwg09BGKgwmfGfx/RP+fSI/np8NNhqWn6UaNfNFzDKSfsI56NT806V442/hQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782748462; a=rsa-sha256; cv=none; b=CNUZp4myivzawiwpb+LpGSogtJKUhthc8D5Kjl9zaGgaifs0SnDBkIzoDamdRwhhVHEhnf epuqzv8bcX4sjtH7ssmUD74Q8tW7siRfbFyEx6dE1WuSOxLsGKrtBoh+LwEFnlX8E7SWjZ bikunkqb3a+W1Ah8GMNm5VQqvHb3Dax3g3NoTlK8OxUcQImd0QIkBXmPOXvH3YV8Fv4bBN 1wxgUX+sNyflNFtp3VvhC9GFb6W0lR38GB2X7mRRBANNfG7CGEbpCzHLJsuj875uO8IE3v SnlM2HbT3A0sjq+Dv5Lb3gZJHAW0oCN5tFtvnjdVIrvTvhFk4N+4kiJFjecUtQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782748462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Gh5+4LjuymAfPKlPE4xY8RtGttibL8adGs8a+MoJM4k=; b=U3honF3km0irabqzBnc4beyDp55RQMF82d8xeM+TnBu1JQlF5MzHJ1EI4oJ8AARdhRcs3b ZDO3twnFGV2vmEHGfnIebpcXl1DO27kgnmWQGRRJKOd8pMFYL3Om/FFgbyWJEN8pML3ftH AdfuzYFhV9YY8h3hEgxLsuBH3DfHXD+mPBEPy1NzshJVeIlB2vlXr/R7IkRdd0ubzU4K1N i/9r8YS7IG7ofqzusW58W4vDtDZ+oT7r8iscW2Un/s9dpclGm2AijLU3iAiyVkZTJWQ6Rw VA5++AXi2jKkDV6xqNj0a+OyrMkP0kq+kGhl+1u5AOKEf9GU8BYO18Ax4Z2/mg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gprSG4pTPz146T for ; Mon, 29 Jun 2026 15:54:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 39873 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 29 Jun 2026 15:54:22 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav Subject: git: da4d1ced75f3 - main - Revert "libfetch: Overhaul socket read / write" List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: da4d1ced75f3be17f8b089a364f642a04eb0d466 Auto-Submitted: auto-generated Date: Mon, 29 Jun 2026 15:54:22 +0000 Message-Id: <6a42952e.39873.38ad452c@gitrepo.freebsd.org> The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=da4d1ced75f3be17f8b089a364f642a04eb0d466 commit da4d1ced75f3be17f8b089a364f642a04eb0d466 Author: Dag-Erling Smørgrav AuthorDate: 2026-06-29 15:53:56 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2026-06-29 15:53:56 +0000 Revert "libfetch: Overhaul socket read / write" This reverts commit 298f37a71ae6d9f2cb0c2abd4ff2887e81e0942c. --- lib/libfetch/common.c | 206 ++++++++++++++++++++------------------------------ lib/libfetch/common.h | 4 +- 2 files changed, 83 insertions(+), 127 deletions(-) diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index c5fb45f70da2..88b5e5a2f096 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -1253,9 +1253,13 @@ fetch_ssl(conn_t *conn, const struct url *URL, int verbose) #endif } +#define FETCH_READ_WAIT -2 +#define FETCH_READ_ERROR -1 +#define FETCH_READ_DONE 0 + #ifdef WITH_SSL static ssize_t -fetch_ssl_read(SSL *ssl, void *buf, size_t len) +fetch_ssl_read(SSL *ssl, char *buf, size_t len) { ssize_t rlen; int ssl_err; @@ -1263,57 +1267,43 @@ fetch_ssl_read(SSL *ssl, void *buf, size_t len) rlen = SSL_read(ssl, buf, len); if (rlen < 0) { ssl_err = SSL_get_error(ssl, rlen); - switch (ssl_err) { - case SSL_ERROR_ZERO_RETURN: - return (0); - case SSL_ERROR_WANT_READ: - errno = EAGAIN; - return (-1); - case SSL_ERROR_SYSCALL: - return (-1); - default: - errno = EPROTO; - return (-1); + if (ssl_err == SSL_ERROR_WANT_READ || + ssl_err == SSL_ERROR_WANT_WRITE) { + return (FETCH_READ_WAIT); + } else { + ERR_print_errors_fp(stderr); + return (FETCH_READ_ERROR); } } return (rlen); } +#endif static ssize_t -fetch_ssl_write(SSL *ssl, void *buf, size_t len) +fetch_socket_read(int sd, char *buf, size_t len) { - ssize_t wlen; - int ssl_err; + ssize_t rlen; - wlen = SSL_write(ssl, buf, len); - if (wlen < 0) { - ssl_err = SSL_get_error(ssl, wlen); - switch (ssl_err) { - case SSL_ERROR_ZERO_RETURN: - return (0); - case SSL_ERROR_WANT_WRITE: - errno = EAGAIN; - return (-1); - case SSL_ERROR_SYSCALL: - return (-1); - default: - errno = EPROTO; - return (-1); + rlen = read(sd, buf, len); + if (rlen < 0) { + if (errno == EAGAIN || (errno == EINTR && fetchRestartCalls)) { + return (FETCH_READ_WAIT); + } else { + return (FETCH_READ_ERROR); } } - return (wlen); + return (rlen); } -#endif /* - * Read from a connection w/ timeout + * Read a character from a connection w/ timeout */ ssize_t -fetch_read(conn_t *conn, void *buf, size_t len) +fetch_read(conn_t *conn, char *buf, size_t len) { struct timeval now, timeout, delta; struct pollfd pfd; - ssize_t rlen, total; + ssize_t rlen; int deltams; if (fetchTimeout > 0) { @@ -1322,10 +1312,10 @@ fetch_read(conn_t *conn, void *buf, size_t len) } deltams = INFTIM; + memset(&pfd, 0, sizeof pfd); pfd.fd = conn->sd; - pfd.events = POLLIN; + pfd.events = POLLIN | POLLERR; - total = 0; for (;;) { /* * The socket is non-blocking. Instead of the canonical @@ -1333,8 +1323,8 @@ fetch_read(conn_t *conn, void *buf, size_t len) * * 1) call read() or SSL_read(). * 2) if we received some data, return it. - * 3) if read() or SSL_read() signaled EOF, return. - * 4) if an error occurred, return -1. + * 3) if an error occurred, return -1. + * 4) if read() or SSL_read() signaled EOF, return. * 5) if we did not receive any data but we're not at EOF, * call poll(). * @@ -1351,26 +1341,14 @@ fetch_read(conn_t *conn, void *buf, size_t len) rlen = fetch_ssl_read(conn->ssl, buf, len); else #endif - rlen = read(conn->sd, buf, len); - if (rlen > 0) { - /* something was read */ - total += rlen; - len -= rlen; - if (len == 0) - break; - /* a partial read is success */ - break; - } else if (rlen == 0) { - /* connection closed */ + rlen = fetch_socket_read(conn->sd, buf, len); + if (rlen >= 0) { break; - } else if (errno != EAGAIN) { - /* error */ - if (errno == EINTR && fetchRestartCalls) - continue; + } else if (rlen == FETCH_READ_ERROR) { fetch_syserr(); - break; + return (-1); } - /* check what's left of our timeout */ + // assert(rlen == FETCH_READ_WAIT); if (fetchTimeout > 0) { gettimeofday(&now, NULL); if (!timercmp(&timeout, &now, >)) { @@ -1382,19 +1360,16 @@ fetch_read(conn_t *conn, void *buf, size_t len) deltams = delta.tv_sec * 1000 + delta.tv_usec / 1000; } - /* wait for the socket to become readable */ + errno = 0; + pfd.revents = 0; if (poll(&pfd, 1, deltams) < 0) { - if (errno == EAGAIN) - continue; if (errno == EINTR && fetchRestartCalls) continue; - break; + fetch_syserr(); + return (-1); } } - /* a partial read is success */ - if (rlen < 0 && total == 0) - return (-1); - return (total); + return (rlen); } @@ -1451,7 +1426,7 @@ fetch_getln(conn_t *conn) * Write to a connection w/ timeout */ ssize_t -fetch_write(conn_t *conn, const void *buf, size_t len) +fetch_write(conn_t *conn, const char *buf, size_t len) { struct iovec iov; @@ -1472,65 +1447,17 @@ fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt) ssize_t wlen, total; int deltams; - if (fetchTimeout > 0) { + memset(&pfd, 0, sizeof pfd); + if (fetchTimeout) { + pfd.fd = conn->sd; + pfd.events = POLLOUT | POLLERR; gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } - deltams = INFTIM; - pfd.fd = conn->sd; - pfd.events = POLLOUT; - total = 0; - for (;;) { - /* - * The socket is non-blocking. Instead of the canonical - * poll() -> write(), we do the following: - * - * 1) call write() or SSL_write(). - * 2) if we wrote everything, return success. - * 3) if write() or SSL_write() signaled EOF before we - * wrote everything, return -1. - * 4) if an error occurred, return -1. - * 5) if we did not write everything but we're not at EOF, - * call poll(). - */ -#ifdef WITH_SSL - if (conn->ssl != NULL) { - wlen = fetch_ssl_write(conn->ssl, - iov->iov_base, iov->iov_len); - } else -#endif - wlen = writev(conn->sd, iov, iovcnt); - if (wlen > 0) { - /* something was written */ - total += wlen; - /* skip iovs which were completely written */ - while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) { - wlen -= iov->iov_len; - iov++; - iovcnt--; - } - /* are we done? */ - if (iovcnt == 0) - break; - /* skip written portion of current iov */ - iov->iov_len -= wlen; - iov->iov_base = __DECONST(char *, iov->iov_base) + wlen; - /* a partial write is incomplete */ - continue; - } else if (wlen == 0) { - /* connection closed */ - break; - } else if (errno != EAGAIN) { - /* error */ - if (errno == EINTR && fetchRestartCalls) - continue; - fetch_syserr(); - break; - } - /* check what's left of our timeout */ - if (fetchTimeout > 0) { + while (iovcnt > 0) { + while (fetchTimeout && pfd.revents == 0) { gettimeofday(&now, NULL); if (!timercmp(&timeout, &now, >)) { errno = ETIMEDOUT; @@ -1540,19 +1467,48 @@ fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt) timersub(&timeout, &now, &delta); deltams = delta.tv_sec * 1000 + delta.tv_usec / 1000; + errno = 0; + pfd.revents = 0; + if (poll(&pfd, 1, deltams) < 0) { + /* POSIX compliance */ + if (errno == EAGAIN) + continue; + if (errno == EINTR && fetchRestartCalls) + continue; + return (-1); + } } - /* wait for the socket to become writeable */ - if (poll(&pfd, 1, deltams) < 0) { - if (errno == EAGAIN) - continue; + errno = 0; +#ifdef WITH_SSL + if (conn->ssl != NULL) + wlen = SSL_write(conn->ssl, + iov->iov_base, iov->iov_len); + else +#endif + wlen = writev(conn->sd, iov, iovcnt); + if (wlen == 0) { + /* we consider a short write a failure */ + /* XXX perhaps we shouldn't in the SSL case */ + errno = EPIPE; + fetch_syserr(); + return (-1); + } + if (wlen < 0) { if (errno == EINTR && fetchRestartCalls) continue; return (-1); } + total += wlen; + while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) { + wlen -= iov->iov_len; + iov++; + iovcnt--; + } + if (iovcnt > 0) { + iov->iov_len -= wlen; + iov->iov_base = __DECONST(char *, iov->iov_base) + wlen; + } } - /* a partial write is failure */ - if (iovcnt > 0) - return (-1); return (total); } diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index 479c5e03c0d1..06089aae5451 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -119,9 +119,9 @@ conn_t *fetch_ref(conn_t *); int fetch_ssl_cb_verify_crt(int, X509_STORE_CTX*); #endif int fetch_ssl(conn_t *, const struct url *, int); -ssize_t fetch_read(conn_t *, void *, size_t); +ssize_t fetch_read(conn_t *, char *, size_t); int fetch_getln(conn_t *); -ssize_t fetch_write(conn_t *, const void *, size_t); +ssize_t fetch_write(conn_t *, const char *, size_t); ssize_t fetch_writev(conn_t *, struct iovec *, int); int fetch_putln(conn_t *, const char *, size_t); int fetch_close(conn_t *);