s3: Fix some nonempty blank lines
[ira/wip.git] / source3 / lib / recvfile.c
index 513742ce8f8edfa298ab3f0721fe85588d55ebd2..ea0159642137390a0f7e57a123684e6e63e47581 100644 (file)
@@ -145,8 +145,10 @@ ssize_t sys_recvfile(int fromfd,
                        SMB_OFF_T offset,
                        size_t count)
 {
-       static bool try_splice_call = true;
+       static int pipefd[2] = { -1, -1 };
+       static bool try_splice_call = false;
        size_t total_written = 0;
+       loff_t splice_offset = offset;
 
        DEBUG(10,("sys_recvfile: from = %d, to = %d, "
                "offset=%.0f, count = %lu\n",
@@ -171,31 +173,46 @@ ssize_t sys_recvfile(int fromfd,
                                count);
        }
 
-       while (total_written < count) {
-               ssize_t ret = splice(fromfd,
-                                       NULL,
-                                       tofd,
-                                       &offset,
-                                       count,
-                                       0);
-               if (ret == -1) {
-                       if (errno != EINTR) {
-                               if (total_written == 0 &&
-                                               (errno == EBADF || errno == EINVAL)) {
-                                       try_splice_call = false;
-                                       return default_sys_recvfile(fromfd,
-                                                               tofd,
-                                                               offset,
-                                                               count);
-                               }
-                               break;
+       if ((pipefd[0] == -1) && (pipe(pipefd) == -1)) {
+               try_splice_call = false;
+               return default_sys_recvfile(fromfd, tofd, offset, count);
+       }
+
+       while (count > 0) {
+               int nread, to_write;
+
+               nread = splice(fromfd, NULL, pipefd[1], NULL,
+                              MIN(count, 16384), SPLICE_F_MOVE);
+               if (nread == -1) {
+                       if (errno == EINTR) {
+                               continue;
+                       }
+                       if (total_written == 0 &&
+                           (errno == EBADF || errno == EINVAL)) {
+                               try_splice_call = false;
+                               return default_sys_recvfile(fromfd, tofd,
+                                                           offset, count);
                        }
-                       continue;
+                       break;
                }
-               total_written += ret;
-               count -= ret;
+
+               to_write = nread;
+               while (to_write > 0) {
+                       int thistime;
+                       thistime = splice(pipefd[0], NULL, tofd,
+                                         &splice_offset, to_write,
+                                         SPLICE_F_MOVE);
+                       if (thistime == -1) {
+                               goto done;
+                       }
+                       to_write -= thistime;
+               }
+
+               total_written += nread;
+               count -= nread;
        }
 
+ done:
        if (total_written < count) {
                int saved_errno = errno;
                if (drain_socket(fromfd, count-total_written) !=