read() wont allow me to read files larger than 2 gig (on a 64bit)

Ben Hutchings ben at decadent.org.uk
Sun Dec 27 21:32:44 UTC 2009


On Fri, 2009-12-25 at 09:29 +0100, glide creme wrote:
> Hi
> Sorry if I'm asking on the wrong mailinglist,
> but I've asked on various forums and I havn't found a solution.
> 
> I can't read files larger than 2 gig on my ubuntu64bit using 'read()',
> the problem is not related to the allocation itself, which works.
> Attached is a sample program that illustrates this.
> 
> I've tried with various, compiler flags like
> -D_FILE_OFFSET_BITS=64
[...]

Since you are building a 64-bit program, you don't need to do anything
special.  If you were building a 32-bit program, you would need to use
-D_FILE_OFFSET_BITS=64.

I think your mistake is to assume that read() only returns a smaller
length than you requested if it encounters an error or end-of-file.  In
fact it can return a smaller length for any reason (though you will
rarely see this behaviour for regular files).  Here's a wrapper I have
used to provide the behaviour you want:

static ssize_t read_retry(int fd, void * buf, size_t count)
{
    ssize_t chunk, total = 0;

    do
    {
	chunk = read(fd, buf, count);
	if (chunk <= 0)
	{
	    if (total == 0)
		return chunk;
	    break;
	}
	total += chunk;
	buf = (char *)buf + chunk;
	count -= chunk;
    }
    while (count);

    return total;
}

Ben.

-- 
Ben Hutchings
Always try to do things in chronological order;
it's less confusing that way.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20091227/8646b127/attachment.sig>


More information about the kernel-team mailing list