Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2008 00:15:54 -0800
From:      Greg Lewis <glewis@eyesbeyond.com>
To:        Michael Allman <msa@allman.ms>
Cc:        landonf@macports.org, freebsd-java@freebsd.org
Subject:   Re: bsd implementation of Java_sun_nio_ch_FileChannelImpl_transferTo0 ignores "count" argument
Message-ID:  <20080118081554.GA4645@misty.eyesbeyond.com>
In-Reply-To: <20080117200016.P64623@yvyyl.pfbsg.arg>
References:  <20080117200016.P64623@yvyyl.pfbsg.arg>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Jan 17, 2008 at 08:13:00PM -0800, Michael Allman wrote:
> There's a bug in the bsd patch to FileChannelImpl.c, as described in the 
> subject of this message.  FYI, I have verified this using the "current" 
> jdk16 freebsd patchset found here:
> 
> http://www.eyesbeyond.com/freebsddom/java/JDK16JRLConfirm.html

D'oh...there certainly is.

> I haven't fully analyzed the impact of this defect.  I can say that in my 
> case, if I call FileChannel.transferTo(0, 100, socketChannel), where 100 
> is less than the length of the file in question, it transfers the entire 
> file to the destination.  According to the docs for this method, it should 
> only transfer a maximum of 100 bytes.  This is key to my particular usage 
> of this method.

The problem is that it ignores the count entirely and just transfers the
whole thing.

> I can attempt to provide a patch, but C is not my thing, and I could not 
> make a reliable claim as to the correctness of my patch.  Also, there's 
> the whole license issue.  Fixing this seems simple enough, though.  I 
> would like to help insofar as I can.

Something like this maybe? (Untested)

--- ../../j2se/src/solaris/native/sun/nio/ch/FileChannelImpl.c	6 Mar 2007 17:45:05 -0000	1.11
+++ ../../j2se/src/solaris/native/sun/nio/ch/FileChannelImpl.c	18 Jan 2008 08:11:36 -0000
@@ -264,11 +264,12 @@
         return IOS_THROWN;
     }
 
-    while ((r = pread(srcFD, buf, 4096, offset)) > 0) {
+    while (count > 0 && (r = pread(srcFD, buf, (count < 4096) ? count : 4096, offset)) > 0) {
         w = write(dstFD, buf, r);
         if (w == -1)
 	    break;
         offset += w;
+        count -= w;
     }
     free(buf);
 

> Also, I know this is getting pushy, but it seems like fixing this issue 
> would be a great time to replace the current implementation of this method 
> with a true bsd sendfile() call.  I could give that a try, too.

As noted in the comments, you can't since the BSD implementation of
sendfile(2) expects to be sending the file to a socket, not just any old
file descriptor.  Solaris and Linux are both ok with any old fd.

-- 
Greg Lewis                          Email   : glewis@eyesbeyond.com
Eyes Beyond                         Web     : http://www.eyesbeyond.com
Information Technology              FreeBSD : glewis@FreeBSD.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080118081554.GA4645>