[RFD] Trying to move Cygwin over to 64 bit file access

J. Johnston jjohnstn@redhat.com
Tue Jun 11 12:56:00 GMT 2002

Corinna Vinschen wrote:
> Hi,
> we're currently in Cygwin trying to get rid of some restrictions given
> by too small datatypes.  You did perhaps already see that some datatypes
> aren't defined anymore in newlib if compiling under Cygwin.  This is
> due to the fact that we moved most of that stuff into special Cygwin
> files (e. g. cygwin/types.h, cygwin/stat.h).
> The way we are going is trying to be backward compatible.  Old
> applications using 32 bit file access should still work under a 64 bit
> Cygwin.  Therefore we are changing Cygwin internally to 64 bit but we
> keep the entry points for the old applications to jump into e. g.
> lseek() while there's also a function lseek64() which is used if a
> newly compiled application is calling lseek().
> There's obviously also the time "in between", where we are changing
> headers and Cygwin itself, while applications still link against the
> 32 bit types and functions.
> Therefore the types exist in two variations, e. g. __off32_t and
> __off64_t.  By using the define __CYGWIN_USE_BIG_TYPES__ the
> application is getting the old 32 or the new 64 bit types.
> Well, two problems are still left.
> - newlib is internally using `off_t'.  This doesn't fit well in our
>   concept, obviously.  To build correctly, the functions using off_t
>   would either have to be changed to use __off64_t if they are only
>   used internally or to use __off32_t if the off_t is used as parameter
>   to an exported function.
>   Apparently this doesn't work with any other target since these
>   datatypes aren't defined there.
> - The crux is the datatype fpos_t.  This datatype is supposed to be
>   the same size as off_t.  So it has to switched over to 64 bit the
>   same way as off_t.  Unfortunately fpos_t is used for a member of
>   __sFILE, too.  This makes life really hard.  Ignoring the problems
>   with the naming convention, using a __fpos32_t would keep the FILE
>   functions from being able to seek correclty in big files, using
>   __fpos64_t would change the size of FILE and so we have another
>   datatype which has to exist in a 32 and a 64 bit version: FILE.
>   This in turn requires to have two versions of nearly *every* FILE
>   function.

Actually, this should be relatively straightforward.  What you need to
do is to extend the current __sFILE structure and create a new __sFILE64.
You still need the old __sFILE struct.  The new structure adds a 64-bit 
offset field to the end and changes the prototype of the _seek function pointer.  
You also need to add a new flag to stdio.h (0x8000 is still available) which means "this
is a 64-bit offset file".  The flag gets set on by fopen64 which returns a
struct __sFILE64 pointer.  You can set fopen -> fopen64 and FILE to be struct __sFILE64
by default so it is all hidden for new code.

Now, the I/O functions take a FILE pointer.  You can let the code
look at the magic bit and decide whether to treat the code as a
32-bit FILE or a 64-bit FILE and then simply recast the pointer only when
necessary (e.g. when you check or update the file offset or when you access
the _seek function pointer).  There are a few spots in the library where
a FILE is declared directly (e.g. vfprintf.c, sscanf.c) and then a pointer to the FILE is used
to call another I/O function.  Since some of this code copies bits from another
FILE, it has to either clear the flag or use a FILE64 by default and recast on the call.

For the REENT struct you can just always let the default std streams default as 32-bit
files.  If there is any reason to check, you can always look at the difference
between the original stdin, stdout, and stderr pointers which will tell you which
type of FILE was used at compilation time.

-- Jeff J.

More information about the Newlib mailing list