guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Bindings for ‘sendfile’


From: Ludovic Courtès
Subject: Re: [PATCH] Bindings for ‘sendfile’
Date: Thu, 21 Mar 2013 10:40:47 +0100
User-agent: Gnus/5.130005 (Ma Gnus v0.5) Emacs/24.2 (gnu/linux)

Hi Mark,

Mark H Weaver <address@hidden> skribis:

> address@hidden (Ludovic Courtès) writes:
>> I plan to commit the patch below, which adds bindings for ‘sendfile’.
>>
>> Comments?
>
> Looks great to me, modulo one comment below.

Thanks for the quick review!

> I especially like the fact that although it can make use of the
> non-standard Linux syscall, it works properly on all systems.  In
> response to suggestions by others that we create a "linux" module:
> I'd prefer to follow the good precedent set by Ludovic here.

Yeah.  (And experience has shown that POSIX largely follows GNU/Linux
nowadays.)

>> +  size_t c_count;
>> +  off_t c_offset;
>> +  ssize_t result;
>> +  int in_fd, out_fd;
>> +
>> +  VALIDATE_FD_OR_PORT (out_fd, out, 1);
>> +  VALIDATE_FD_OR_PORT (in_fd, in, 2);
>> +  c_count = scm_to_size_t (count);
>
> Since the code below will behave badly if 'c_count' does not fit in an
> 'ssize_t', we should validate here that it _does_ fit.

Oops, indeed.  (Note that sendfile(2) and write(2) have that problem:
they take a size_t and return a ssize_t...)

There was also the other issue of making sure we use the right function,
depending on _FILE_OFFSET_BITS & co.

Here are the changes compared to the previous patch:

diff --git a/libguile/filesys.c b/libguile/filesys.c
index 097b03a..6804db9 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -102,6 +102,10 @@
 # include <sys/sendfile.h>
 #endif
 
+/* Glibc's `sendfile' function.  */
+#define sendfile_or_sendfile64                 \
+  CHOOSE_LARGEFILE (sendfile, sendfile64)
+
 #include <full-read.h>
 #include <full-write.h>
 
@@ -1123,7 +1127,7 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
     }
 
   size_t c_count;
-  off_t c_offset;
+  scm_t_off c_offset;
   ssize_t result;
   int in_fd, out_fd;
 
@@ -1133,20 +1137,20 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
   c_offset = SCM_UNBNDP (offset) ? 0 : scm_to_off_t (offset);
 
 #ifdef HAVE_SENDFILE
-  result = sendfile (out_fd, in_fd,
+  result = sendfile_or_sendfile64 (out_fd, in_fd,
                                   SCM_UNBNDP (offset) ? NULL : &c_offset,
                                   c_count);
 
   /* Quoting the Linux man page: "In Linux kernels before 2.6.33, out_fd
      must refer to a socket.  Since Linux 2.6.33 it can be any file."
-     Fall back to read(2) and write(2) such an error happens.  */
+     Fall back to read(2) and write(2) when such an error occurs.  */
   if (result < 0 && errno != EINVAL && errno != ENOSYS)
     SCM_SYSERROR;
   else if (result < 0)
 #endif
   {
     char buf[8192];
-    size_t left;
+    size_t result, left;
 
     if (!SCM_UNBNDP (offset))
       {
@@ -1173,6 +1177,8 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
 
        result += obtained;
       }
+
+    return scm_from_size_t (result);
   }
 
   return scm_from_ssize_t (result);
WDYT?

Thanks,
Ludo’.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]