From 443a5314045169047070ad3a32e5134227d837dd Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Tue, 28 Jun 2022 11:23:22 +0000 Subject: apr_socket_sendv: unix: APR_INCOMPLETE_WRITE pre to post processing. Rather than precomputing requested_len before writev() and later comparing with what has been sent, we can walk the iovec after only to see if it's exhausted. This saves useless precomputation on error (e.g. nonblocking EAGAIN) and avoids a poteential invalid/overflowed requested_len should the iovec point to more than SIZE_MAX bytes. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902314 13f79535-47bb-0310-9956-ffa450edef68 --- network_io/unix/sendrecv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'network_io') diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c index b9e580b1b..1b965af50 100644 --- a/network_io/unix/sendrecv.c +++ b/network_io/unix/sendrecv.c @@ -196,13 +196,8 @@ apr_status_t apr_socket_sendv(apr_socket_t * sock, const struct iovec *vec, { #ifdef HAVE_WRITEV apr_ssize_t rv; - apr_size_t requested_len = 0; apr_int32_t i; - for (i = 0; i < nvec; i++) { - requested_len += vec[i].iov_len; - } - if (sock->options & APR_INCOMPLETE_WRITE) { sock->options &= ~APR_INCOMPLETE_WRITE; goto do_select; @@ -231,8 +226,16 @@ do_select: *len = 0; return errno; } - if ((sock->timeout > 0) && (rv < requested_len)) { - sock->options |= APR_INCOMPLETE_WRITE; + if (sock->timeout > 0) { + apr_size_t rv_len = rv; + for (i = 0; i < nvec; ++i) { + apr_size_t iov_len = vec[i].iov_len; + if (rv_len < iov_len) { + sock->options |= APR_INCOMPLETE_WRITE; + break; + } + rv_len -= iov_len; + } } (*len) = rv; return APR_SUCCESS; -- cgit v1.2.1