(fhandler_base::lseek): Include high order bits in return.
J. Johnston
jjohnstn@redhat.com
Wed Nov 19 14:48:00 GMT 2003
Thanks Corinna. Patch applied. I'll have to think about your proposal to put
the definitions in _syslist.h.
-- Jeff J.
Corinna Vinschen wrote:
> On Mon, Nov 17, 2003 at 08:58:42PM -0500, J. Johnston wrote:
>
>>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.
>
>
> Yes, any application call to lseek is redirected automatically 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?
>
>
> These wrappers in libc/syscalls aren't used by Cygwin. Cygwin provides
> its own functions. See winsup/cygwin/cygwin.din. E. g. the close call
> is exported as
>
> close
> _close = close
>
> which means, the close call is also exported as _close.
>
> I debugged Brian's testcase and it turned out that the following happened
> to the offset value:
>
> fseeko64 calls _lseek64_r, offset is 0x12a05f200.
> _lseek64_r calls _lseek64, offset is 0x12a05f200.
>
> _lseek64 is implemented in Cygwin.
>
> _lseek64 calls SetFilePointer, pos returned is 0x12a05f200.
> _lseek64 explicitely returns 0x12a05f200.
>
> Now we're back in newlib.
>
> _lseek64_r stores the return value of _lseek64 in the local variable
> `ret'. Looking into ret right after the call to _lseek64 shows that
> ret has lost its upper bits:
>
> (gdb) p/x ret
> $1 = 0x2a05f200
>
> The cause for that behaviour is, that newlib is missing prototypes for
> all 64 bit syscalls (_open64, _fstat64, _lseek64) it uses.
>
> This doesn't lead to problems for all the other functions. Only _lseek64
> is affected, because it's the only function returning a value which is
> bigger than int. That means, due to the missing prototype, the returned
> value is taken from only one register, instead of from two registers as
> would be necessary for the 8 byte type _off64_t.
>
> For the sake of testing I added an extern declaration of _lseek64 to
> _lseek64_r like this:
>
> extern _off64_t _lseek64 (int, _off64_t, int);
>
> which solved the above problem. fseeko returned the expected value of
> 0x12a05f201.
>
> However, the correct solution would be to declare all syscalls used by
> newlib at one point.
>
> I propose the below patch which matches the already existing layout.
> It might be a good idea, though, to move all syscall declarations
> into a special file. They could be declared in _syslist.h, for instance.
> BSD has a header file called sys/sysproto.h, which would be fine, too.
>
> Corinna
>
>
> * libc/include/sys/fcntl.h: Declare _open64.
> * libc/include/sys/stat.h: Declare _fstat64.
> * libc/include/sys/unistd.h: Declare _lseek64.
>
> Index: libc/include/sys/fcntl.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/sys/fcntl.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 fcntl.h
> --- libc/include/sys/fcntl.h 5 Sep 2000 18:29:53 -0000 1.2
> +++ libc/include/sys/fcntl.h 18 Nov 2003 12:49:47 -0000
> @@ -171,6 +171,9 @@ extern int fcntl _PARAMS ((int, int, ...
> of newlib. */
> extern int _open _PARAMS ((const char *, int, ...));
> extern int _fcntl _PARAMS ((int, int, ...));
> +#ifdef __LARGE64_FILES
> +extern int _open64 _PARAMS ((const char *, int, ...));
> +#endif
>
> #ifdef __cplusplus
> }
> Index: libc/include/sys/stat.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/sys/stat.h,v
> retrieving revision 1.13
> diff -u -p -r1.13 stat.h
> --- libc/include/sys/stat.h 26 Aug 2003 20:54:04 -0000 1.13
> +++ libc/include/sys/stat.h 18 Nov 2003 12:49:48 -0000
> @@ -140,6 +140,9 @@ int _EXFUN(mknod,( const char *__path, m
> #ifndef __INSIDE_CYGWIN__
> int _EXFUN(_fstat,( int __fd, struct stat *__sbuf ));
> int _EXFUN(_stat,( const char *__path, struct stat *__sbuf ));
> +#ifdef __LARGE64_FILES
> +int _EXFUN(_fstat64,( int __fd, struct stat64 *__sbuf ));
> +#endif
> #endif
>
> #endif /* !_STAT_H_ */
> Index: libc/include/sys/unistd.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/sys/unistd.h,v
> retrieving revision 1.45
> diff -u -p -r1.45 unistd.h
> --- libc/include/sys/unistd.h 10 Sep 2003 15:53:44 -0000 1.45
> +++ libc/include/sys/unistd.h 18 Nov 2003 12:49:48 -0000
> @@ -177,6 +177,9 @@ void * _EXFUN(_sbrk, (ptrdiff_t __incr
> int _EXFUN(_unlink, (const char *__path ));
> _READ_WRITE_RETURN_TYPE _EXFUN(_write, (int __fd, const void *__buf, size_t __nbyte ));
> int _EXFUN(_execve, (const char *__path, char * const __argv[], char * const __envp[] ));
> +#ifdef __LARGE64_FILES
> +_off64_t _EXFUN(_lseek64, (int, _off64_t, int));
> +#endif
>
> #if defined(__CYGWIN__) || defined(__rtems__) || defined(__sh__)
> #if !defined(__INSIDE_CYGWIN__)
>
More information about the Newlib
mailing list