ftello loosing upper 32 bits via _lseek64

Brian Ford ford@vss.fsi.com
Tue Nov 18 19:34:00 GMT 2003

I know this doesn't belong on cygwin-patches anymore, but is
cygwin-developers, or just plain cygwin more appropriate?

On Mon, 17 Nov 2003, J. Johnston wrote:

> Brian Ford wrote:
> > On Mon, 17 Nov 2003, Brian Ford wrote:
> >>On Mon, 17 Nov 2003, Corinna Vinschen wrote:
> >>>On Mon, Nov 17, 2003 at 03:40:46PM -0600, Brian Ford wrote:
> >>>>On Mon, 17 Nov 2003, Brian Ford wrote:
> >>>>>This bug fix got our app past its first problem with > 2 Gig files, but
> >>>>>then it tripped over ftello.  I'm still trying to figure that one out.
> >>>>>
> >>>>>It looks like it got a 32 bit sign extended value somewhere.  Any help would
> >>>>>be appreciated.  Thanks.
> >>>>>
> >>>>Well, that somewhere is ftello64.c line 111.  fp->_offset has a 32 bit
> >>>>sign extended value.  Anybody know how it got there?
> >>>
> >>>That can't be it.  fp is of type FILE which is actually mapped to
> >>>__sFILE64 in 64 bit case.  See newlib/libc/include/sys/reent.h.
> >>>_offset is of type _off64_t there.
> >>>
> >>I think you misunderstood.  fp->_offset is a 64 bit type, but at the
> >>ftello call in question, it contains a value that must have come from a 32
> >>bit sign extension.  That's why I asked for help, because I have to figure
> >>out what/who put it there.
> >>
> > I have attached a test case that shows the problem.  It is on line 58 of
> > lseekr.c.
> >
> > I can't seem to find the actual problem tonight and I'm tired so I'm going
> > home.
> >
> IIRC, Cygwin redirects your calls to the appropriate 64-bit I/O code and thus,
> should not be allowing you to call lseek and should instead redirect your call
> to lseek64.  Now, there isn't currently an lseek64 in the libc/syscalls
> directory which contains syscall wrappers used by Cygwin.  Corinna, if I add the
> appropriate wrappers, would that help or does Cygwin provide its own wrappers?
You are correct.  I was in too big of a rush to go home, and I had a bad

The problem actually lies at line 61 of newlib/libc/reent/lseek64r.c.
When I look at the return from _lseek64 in gdb, it is correct.
Furthermore, the variable being assinged to (ret) is 64 bit.  But, the
value it gets is truncated at the 32 bit mark.

This seems to be a bit over my head.  I can't see why that would happen
unless it is something like an incorrect/missing prototype issue.  With
the maze of includes, it could take me some time to track that down.

Dig, dig, dig...  Ah yes, looking at the preprocessor output for that
file, there is no _lseek64 prototype.

Next question: How do we get one?

Could someone who knows how Cygwin glues to newlib better than I take a
quick look?  Thanks.

Test case still attached.

Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
Phone: 314-551-8460
Fax:   314-551-8444
-------------- next part --------------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

    FILE *fp;
    off_t p, q;
    char c;

    long long size = 5000000000LL;
    int fd = open("junk", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
    lseek(fd, size, SEEK_SET);
    write(fd, "x", 1);

    fp = fopen("junk", "r");

    p = fseeko(fp, size, SEEK_SET);
    fprintf(stderr, "%c ", fgetc(fp));
    q = ftello(fp);

    fprintf(stderr,"%llx %llx %llx\n",size,p, q);

More information about the Newlib mailing list