(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