Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37852353
en ru br
ALT Linux repositórios
S:1.7.0-alt4
D:1.2.12-alt2.1
5.0: 1.4.6-alt0.M51.1
4.1: 1.2.12-alt2
4.0: 1.2.8-alt1.2
+updates:1.2.8-alt1.2

Group :: Sistema/Bibliotecas
RPM: apr1

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs e FR  Repocop 

Patch: apr-1.4.4-alt-015_sendfile_lfs.dpatch
Download


 network_io/unix/sendrecv.c |   96 +++++++++++++++++++++++++++++--------------
 1 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index c133a26..d15ed69 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -247,39 +247,77 @@ static apr_hdtr_t no_hdtr;
 
 #if defined(__linux__) && defined(HAVE_WRITEV)
 
-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)
+/* Helper function for apr_socket_sendfile.
+ * Takes care of sendfile vs. sendfile64 (must be detected at runtime),
+ * EINTR restarting, and other details.  NOTE: does not necessarily
+ * update 'off', as callers don't need this.
+ */
+static
+ssize_t do_sendfile(int out, int in, apr_off_t *off, apr_size_t len)
 {
-    int rv, nbytes = 0, total_hdrbytes, i;
-    apr_status_t arv;
+#if !APR_HAS_LARGE_FILES
+    ssize_t ret;
+    do
+	ret = sendfile(out, in, off, len);
+    while (ret == -1 && errno == EINTR);
+    return ret;
+#else
 
-#if APR_HAS_LARGE_FILES && defined(HAVE_SENDFILE64)
-    apr_off_t off = *offset;
-#define sendfile sendfile64
+#ifdef HAVE_SENDFILE64
+    static int sendfile64_enosys;  /* sendfile64() syscall not found */
+#endif
+    off_t offtmp;
+    ssize_t ret;
 
-#elif APR_HAS_LARGE_FILES && SIZEOF_OFF_T == 4
-    /* 64-bit apr_off_t but no sendfile64(): fail if trying to send
-     * past the 2Gb limit. */
-    off_t off;
-    
-    if ((apr_int64_t)*offset + *len > INT_MAX) {
-        return EINVAL;
+    /* Multiple reports have shown sendfile failing with EINVAL if
+     * passed a >=2Gb count value on some 64-bit kernels.  It won't
+     * noticably hurt performance to limit each call to <2Gb at a time,
+     * so avoid that issue here.  (Round down to a common page size.) */
+    if (sizeof(off_t) == 8 && len > INT_MAX)
+        len = INT_MAX - 8191;
+
+    /* The simple and common case: we don't cross the LFS barrier */
+    if (sizeof(off_t) == 8 || (apr_int64_t)*off + len <= INT_MAX) {
+        offtmp = *off;
+        do
+            ret = sendfile(out, in, &offtmp, len);
+        while (ret == -1 && errno == EINTR);
+        return ret;
     }
-    
-    off = *offset;
 
-#else
-    off_t off = *offset;
+    /* From here down we know it's a 32-bit runtime */
+#ifdef HAVE_SENDFILE64
+    if (!sendfile64_enosys) {
+        do
+            ret = sendfile64(out, in, off, len);
+        while (ret == -1 && errno == EINTR);
 
-    /* Multiple reports have shown sendfile failing with EINVAL if
-     * passed a >=2Gb count value on some 64-bit kernels.  It won't
-     * noticably hurt performance to limit each call to <2Gb at a
-     * time, so avoid that issue here: */
-    if (sizeof(off_t) == 8 && *len > INT_MAX) {
-        *len = INT_MAX;
+        if (ret != -1 || errno != ENOSYS)
+            return ret;
+
+        sendfile64_enosys = 1;
     }
 #endif
+    if (*off > INT_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+    offtmp = *off;
+    do
+	ret = sendfile(out, in, &offtmp, len);
+    while (ret == -1 && errno == EINTR);
+    return ret;
+#endif /* APR_HAS_LARGE_FILES */
+}
+
+
+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)
+{
+    int rv, nbytes = 0, total_hdrbytes, i;
+    apr_status_t arv;
+    apr_off_t off = *offset;
 
     if (!hdtr) {
         hdtr = &no_hdtr;
@@ -325,12 +363,10 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
         goto do_select;
     }
 
-    do {
-        rv = sendfile(sock->socketdes,    /* socket */
+    rv = do_sendfile(sock->socketdes,    /* socket */
                       file->filedes, /* open file descriptor of the file to be sent */
                       &off,    /* where in the file to start */
                       *len);   /* number of bytes to send */
-    } while (rv == -1 && errno == EINTR);
 
     while ((rv == -1) && (errno == EAGAIN || errno == EWOULDBLOCK) 
                       && (sock->timeout > 0)) {
@@ -341,12 +377,10 @@ do_select:
             return arv;
         }
         else {
-            do {
-                rv = sendfile(sock->socketdes,    /* socket */
+	    rv = do_sendfile(sock->socketdes,    /* socket */
                               file->filedes, /* open file descriptor of the file to be sent */
                               &off,    /* where in the file to start */
                               *len);    /* number of bytes to send */
-            } while (rv == -1 && errno == EINTR);
         }
     }
 
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009