You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2008/04/24 22:26:41 UTC

svn commit: r651398 - in /apr/apr/branches/1.3.x: CHANGES network_io/unix/sendrecv.c

Author: wrowe
Date: Thu Apr 24 13:26:35 2008
New Revision: 651398

URL: http://svn.apache.org/viewvc?rev=651398&view=rev
Log:
Support OS/X sendfile by using writev rather than the miscounted sendfile's
hdtr iovecs.

Submitted by: Geoff Greer <angryparsley mipsisrisc.com>
Backports: r651395

Modified:
    apr/apr/branches/1.3.x/CHANGES
    apr/apr/branches/1.3.x/network_io/unix/sendrecv.c

Modified: apr/apr/branches/1.3.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/CHANGES?rev=651398&r1=651397&r2=651398&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/CHANGES [utf-8] (original)
+++ apr/apr/branches/1.3.x/CHANGES [utf-8] Thu Apr 24 13:26:35 2008
@@ -1,6 +1,9 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 1.3.0
 
+  *) Support OS/X sendfile by using writev in lieu of hdtr vecs
+     miscounted by the OS.  [Geoff Greer <angryparsley mipsisrisc.com>]
+
   *) Implement apr_proc_wait_all_procs for windows.
      The implementation uses tool help library present
      on Windows 2000 and later. APR_ENOTIMPL is returned

Modified: apr/apr/branches/1.3.x/network_io/unix/sendrecv.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/network_io/unix/sendrecv.c?rev=651398&r1=651397&r2=651398&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/network_io/unix/sendrecv.c (original)
+++ apr/apr/branches/1.3.x/network_io/unix/sendrecv.c Thu Apr 24 13:26:35 2008
@@ -411,8 +411,9 @@
                                  apr_size_t * len, apr_int32_t flags)
 {
     apr_off_t nbytes = *len;
+    apr_off_t bytes_to_send = *len;
+    apr_size_t header_bytes_written = 0;
     int rv;
-    struct sf_hdtr headerstruct;
 
     /* Ignore flags for now. */
     flags = 0;
@@ -421,12 +422,10 @@
         hdtr = &no_hdtr;
     }
 
-    headerstruct.headers = hdtr->headers;
-    headerstruct.hdr_cnt = hdtr->numheaders;
-    headerstruct.trailers = hdtr->trailers;
-    headerstruct.trl_cnt = hdtr->numtrailers;
-
-    /* BSD can send the headers/footers as part of the system call */
+    /* OS X can send the headers/footers as part of the system call, 
+     * but how it counts bytes isn't documented properly. We use 
+     * writev() instead.
+     */
     do {
         if (sock->options & APR_INCOMPLETE_WRITE) {
             apr_status_t arv;
@@ -437,18 +436,33 @@
                 return arv;
             }
         }
-        if (nbytes) {
+        
+        if (hdtr->numheaders) {
+            rv = writev(sock->socketdes,
+                        hdtr->headers,
+                        hdtr->numheaders);
+            if (rv > 0) {
+                header_bytes_written = rv;
+                rv = 0;
+            }
+            else {
+                header_bytes_written = 0;
+            }
+        }
+        else if (bytes_to_send) {
             /* 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.
              */
+            nbytes = bytes_to_send;
             rv = sendfile(file->filedes, /* file to be sent */
                           sock->socketdes, /* socket */
                           *offset,       /* where in the file to start */
                           &nbytes,       /* number of bytes to write/written */
-                          &headerstruct, /* Headers/footers */
+                          NULL,          /* Headers/footers */
                           flags);        /* undefined, set to 0 */
 
+            bytes_to_send -= nbytes;
             if (rv == -1) {
                 if (errno == EAGAIN) {
                     if (sock->timeout > 0) {
@@ -460,7 +474,7 @@
                      */
                     if (nbytes) {
                         /* normal exit for a big file & non-blocking io */
-                        (*len) = nbytes;
+                        (*len) = nbytes + header_bytes_written;
                         return APR_SUCCESS;
                     }
                 }
@@ -470,11 +484,11 @@
                     /* Most likely the file got smaller after the stat.
                      * Return an error so the caller can do the Right Thing.
                      */
-                    (*len) = nbytes;
+                    (*len) = nbytes + header_bytes_written;
                     return APR_EOF;
                 }
             }
-        }    
+        }
         else {
             /* just trailer bytes... use writev()
              */