summaryrefslogtreecommitdiff
path: root/network_io
diff options
context:
space:
mode:
authorWilliam A. Rowe Jr <wrowe@apache.org>2008-05-01 22:22:22 +0000
committerWilliam A. Rowe Jr <wrowe@apache.org>2008-05-01 22:22:22 +0000
commitec585831b88b8d4e1bd29ca9b90bc6f6d5d4e72d (patch)
treec070854258e87ceb056b4cc3edfeae788b4e7161 /network_io
parent0675c50d3476c3cb9ed14df81652a7fa9360d471 (diff)
downloadapr-ec585831b88b8d4e1bd29ca9b90bc6f6d5d4e72d.tar.gz
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 <angryparsley mipsisrisc.com> and wrowe git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@652690 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io')
-rw-r--r--network_io/unix/sendrecv.c39
1 files changed, 23 insertions, 16 deletions
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)) {