This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: FreeBSD port (29): sendfile


Bruno Haible <haible@ilog.fr> writes:

> James Antill writes:
> 
> > it's completely broken. If you pass NULL as the off_t
> > then it's supposed to use the off_t associated with the fd (just like
> > read and write) ...
> 
> That's what the submitted emulation does.
> 
> > your version will just silently drop data when
> > reading from a non-file as the src.
> 
> No, if you call it on an fd not supporting lseek, and with
> offset==NULL, the emulation will return -1 immediately. If, OTOH,
> the fd supports lseek, then no data will be lost, due to the lseek()
> call at the end.

 That would be an ok way of doing it (although you need to keep
retrying the lseek() and not just return -1, EINTR in the non pread()
case). However this isn't what your code does atm., from my reading of
it, it only dies when you pass an offset and have an fd that can't do
lseek()...

--- /dev/null	Fri Jul 12 03:09:05 2002
+++ glibc-20020627/sysdeps/posix/sendfile.c	Fri Jul 12 00:08:57 2002
@@ -0,0 +1,210 @@

[snip ... ]

+ssize_t
+sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
+{
[snip ... ]

+  if (count == 0)
+    return 0;
+
+#if !USE_PREAD
+  old_offset = 0;
+#endif
+  if (offset != NULL)
+    {

 Only run if offset isn't NULL, so not relevant [snip ... ].

+    }
+
+  /* Try to do it all in one swoop, through a malloc'ed buffer.  */
+  if (count > sizeof (stackbuf))
+    {

 Allocation stuff... [snip ... ]

+    }
+  else
+    {
+      buffer = stackbuf;
+      bufsize = sizeof (stackbuf);
+    }
+
+  written = 0;
+  notwritten = 0;
+  saved_errno = errno;
+  do
+    {
+      /* Read a chunk of data from IN_FD into the buffer, and write it
+	 to OUT_FD.  */
+      size_t count_this_round = (count <= bufsize ? count : bufsize);
+      ssize_t nbytesread;
+
+#if USE_PREAD
+      if (offset != NULL)
+	nbytesread = __libc_pread (in_fd, buffer, count_this_round,
+				   start_offset + written);
+      else
+#endif
+	nbytesread = __libc_read (in_fd, buffer, count_this_round);

 Now you've lost data.

-- 
James Antill -- james@and.org
The Hurd itself is aggressively multi-threaded and all of the locking has
been done with an eye towards multi-processor systems. That said, we have
not yet used a microkernel that stably supports multiple cpus.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]