[Freeswitch-svn] [commit] r6096 - freeswitch/trunk/libs/apr/network_io/unix

Freeswitch SVN brian at freeswitch.org
Wed Oct 31 12:12:02 EDT 2007


Author: brian
Date: Wed Oct 31 12:12:01 2007
New Revision: 6096

Modified:
   freeswitch/trunk/libs/apr/network_io/unix/sendrecv.c

Log:
small fix to apr for OS X 10.5 for sendfile

Modified: freeswitch/trunk/libs/apr/network_io/unix/sendrecv.c
==============================================================================
--- freeswitch/trunk/libs/apr/network_io/unix/sendrecv.c	(original)
+++ freeswitch/trunk/libs/apr/network_io/unix/sendrecv.c	Wed Oct 31 12:12:01 2007
@@ -148,6 +148,8 @@
                                  apr_size_t *len)
 {
     apr_ssize_t rv;
+    
+    from->salen = sizeof(from->sa);
 
     do {
         rv = recvfrom(sock->socketdes, buf, (*len), flags, 
@@ -172,6 +174,8 @@
         return errno;
     }
 
+    apr_sockaddr_vars_set(from, from->sa.sin.sin_family, ntohs(from->sa.sin.sin_port));
+
     (*len) = rv;
     if (rv == 0 && sock->type == SOCK_STREAM) {
         return APR_EOF;
@@ -399,6 +403,109 @@
     return rv < 0 ? errno : APR_SUCCESS;
 }
 
+#elif defined(DARWIN)
+
+/* OS/X Release 10.5 or greater */
+apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
+                                 apr_hdtr_t * hdtr, apr_off_t * offset,
+                                 apr_size_t * len, apr_int32_t flags)
+{
+    apr_off_t nbytes = *len;
+    int rv;
+    struct sf_hdtr headerstruct;
+
+    /* Ignore flags for now. */
+    flags = 0;
+
+    if (!hdtr) {
+        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 */
+    do {
+        if (sock->options & APR_INCOMPLETE_WRITE) {
+            apr_status_t arv;
+            sock->options &= ~APR_INCOMPLETE_WRITE;
+            arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
+            if (arv != APR_SUCCESS) {
+                *len = 0;
+                return arv;
+            }
+        }
+        if (nbytes) {
+            /* 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.
+             */
+            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 */
+                          flags);        /* undefined, set to 0 */
+
+            if (rv == -1) {
+                if (errno == EAGAIN) {
+                    if (sock->timeout > 0) {
+                        sock->options |= APR_INCOMPLETE_WRITE;
+                    }
+                    /* 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) {
+                        /* normal exit for a big file & non-blocking io */
+                        (*len) = nbytes;
+                        return APR_SUCCESS;
+                    }
+                }
+            }
+            else {       /* rv == 0 (or the kernel is broken) */
+                if (nbytes == 0) {
+                    /* Most likely the file got smaller after the stat.
+                     * Return an error so the caller can do the Right Thing.
+                     */
+                    (*len) = nbytes;
+                    return APR_EOF;
+                }
+            }
+        }    
+        else {
+            /* just trailer bytes... use writev()
+             */
+            rv = writev(sock->socketdes,
+                        hdtr->trailers,
+                        hdtr->numtrailers);
+            if (rv > 0) {
+                nbytes = rv;
+                rv = 0;
+            }
+            else {
+                nbytes = 0;
+            }
+        }
+        if ((rv == -1) && (errno == EAGAIN) 
+                       && (sock->timeout > 0)) {
+            apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
+            if (arv != APR_SUCCESS) {
+                *len = 0;
+                return arv;
+            }
+        }
+    } while (rv == -1 && (errno == EINTR || errno == EAGAIN));
+
+    (*len) = nbytes;
+    if (rv == -1) {
+        return errno;
+    }
+    return APR_SUCCESS;
+}
+
 #elif defined(__FreeBSD__) || defined(__DragonFly__)
 
 /* Release 3.1 or greater */
@@ -407,7 +514,10 @@
                                  apr_size_t * len, apr_int32_t flags)
 {
     off_t nbytes = 0;
-    int rv, i;
+    int rv;
+#if defined(__FreeBSD_version) && __FreeBSD_version < 460001
+    int i;
+#endif
     struct sf_hdtr headerstruct;
     apr_size_t bytes_to_send = *len;
 
@@ -872,7 +982,9 @@
     for (i = 0; i < hdtr->numheaders; i++, curvec++) {
         sfv[curvec].sfv_fd = SFV_FD_SELF;
         sfv[curvec].sfv_flag = 0;
-        sfv[curvec].sfv_off = (apr_off_t)hdtr->headers[i].iov_base;
+        /* Cast to unsigned long to prevent sign extension of the
+         * pointer value for the LFS case; see PR 39463. */
+        sfv[curvec].sfv_off = (unsigned long)hdtr->headers[i].iov_base;
         sfv[curvec].sfv_len = hdtr->headers[i].iov_len;
         requested_len += sfv[curvec].sfv_len;
     }
@@ -896,7 +1008,7 @@
     for (i = 0; i < hdtr->numtrailers; i++, curvec++) {
         sfv[curvec].sfv_fd = SFV_FD_SELF;
         sfv[curvec].sfv_flag = 0;
-        sfv[curvec].sfv_off = (apr_off_t)hdtr->trailers[i].iov_base;
+        sfv[curvec].sfv_off = (unsigned long)hdtr->trailers[i].iov_base;
         sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
         requested_len += sfv[curvec].sfv_len;
     }



More information about the Freeswitch-svn mailing list