From ec585831b88b8d4e1bd29ca9b90bc6f6d5d4e72d Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Thu, 1 May 2008 22:22:22 +0000 Subject: Reflow the OS/X sendfile implementation to proceed from writev(hd..iovec) to the sendfile/tr..iovec series, tallying these correctly. Submitted by: Geoff Greer and wrowe git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@652690 13f79535-47bb-0310-9956-ffa450edef68 --- network_io/unix/sendrecv.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'network_io') diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c index 3b43508c2..39dd199e7 100644 --- a/network_io/unix/sendrecv.c +++ b/network_io/unix/sendrecv.c @@ -413,7 +413,8 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file, apr_off_t nbytes = 0; apr_off_t bytes_to_send = *len; apr_size_t header_bytes_written = 0; - int rv; + int rv = 0; + int sent_headers = 0; /* Ignore flags for now. */ flags = 0; @@ -436,17 +437,24 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file, return arv; } } - - if (hdtr->numheaders) { - rv = writev(sock->socketdes, - hdtr->headers, - hdtr->numheaders); - if (rv > 0) { - header_bytes_written = rv; - rv = 0; + + if (!sent_headers) { + if (hdtr->numheaders) { + rv = writev(sock->socketdes, + hdtr->headers, + hdtr->numheaders); + if (rv > 0) { + header_bytes_written = rv; + sent_headers = 1; + rv = 0; + } + } + else { + sent_headers = 1; } } - else if (bytes_to_send) { + + if (bytes_to_send && sent_headers) { /* We won't dare call sendfile() if we don't have * header or file bytes to send because nbytes == 0 * means send the remaining file to EOF. @@ -464,12 +472,13 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file, if (errno == EAGAIN) { if (sock->timeout > 0) { sock->options |= APR_INCOMPLETE_WRITE; + rv = 0; } /* BSD's sendfile can return -1/EAGAIN even if it * sent bytes. Sanitize the result so we get normal EAGAIN * semantics w.r.t. bytes sent. */ - if (nbytes) { + else if (nbytes) { /* normal exit for a big file & non-blocking io */ (*len) = nbytes + header_bytes_written; return APR_SUCCESS; @@ -486,19 +495,17 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file, } } } - else { + + if (sent_headers && !bytes_to_send) { /* just trailer bytes... use writev() */ rv = writev(sock->socketdes, hdtr->trailers, hdtr->numtrailers); if (rv > 0) { - nbytes = rv; + nbytes += rv; rv = 0; } - else { - nbytes = 0; - } } if ((rv == -1) && (errno == EAGAIN) && (sock->timeout > 0)) { -- cgit v1.2.1