Cygwin: define FILE as struct __sFILE64, not as __sFILE

Until Cygwin 3.3.6, we define __LARGE64_FILES unconditionally, so we
were using the type __sFILE64 even for 64 bit.  That was lazy and wrong.
so commit 2902b3a09e ("Cygwin: drop requirement to build newlib's
stdio64") tried to fix that.

Unfortunately this patch forgot to take the exposure of the typename
__sFILE64 in userspace into account.  This leads to trouble in C++ due
to name mangling.

Commit 0f376ae220 tried to fix this by just renaming __sFILE to
__sFILE64 by using a macro.  While __sFILE and __sFILE64 are the same
size, they are not exactly congruent.

To avoid backward compatibility problems, make sure to define FILE
as the  real __sFILE64, and make sure that __sFILE is not defined at
all on Cygwin.

Fixes: 0f376ae220 ("Cygwin: rename __sFILE to __sFILE64 for backward
compatibility")
Fixes: 2902b3a09e ("Cygwin: drop requirement to build newlib's stdio64")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2022-12-08 16:03:06 +01:00
parent 6429a7a7f6
commit 55de3fdd0e
2 changed files with 17 additions and 7 deletions

View File

@ -144,6 +144,11 @@ struct __sbuf {
#define _REENT_SMALL_CHECK_INIT(ptr) /* nothing */ #define _REENT_SMALL_CHECK_INIT(ptr) /* nothing */
/* Cygwin must use __sFILE64 for backward compatibility, even though
it's not defining __LARGE64_FILES anymore. To make sure that __sFILE
is never defined, disable it here explicitely. */
#ifndef __CYGWIN__
struct __sFILE { struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */ unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */ int _r; /* read space left for getc() */
@ -195,13 +200,24 @@ struct __sFILE {
int _flags2; /* for future use */ int _flags2; /* for future use */
}; };
#endif /* !__CYGWIN__ */
#ifdef __CUSTOM_FILE_IO__ #ifdef __CUSTOM_FILE_IO__
/* Get custom _FILE definition. */ /* Get custom _FILE definition. */
#include <sys/custom_file.h> #include <sys/custom_file.h>
#else /* !__CUSTOM_FILE_IO__ */ #else /* !__CUSTOM_FILE_IO__ */
#ifdef __LARGE64_FILES /* Cygwin must use __sFILE64 for backward compatibility, even though
it's not defining __LARGE64_FILES anymore. It also has to make
sure the name is the same to satisfy C++ name mangling. Overloading
_fpos64_t just fixes a build problem. The _seek64 function is
actually never used without __LARGE64_FILES being defined. */
#if defined (__LARGE64_FILES) || defined (__CYGWIN__)
#ifdef __CYGWIN__
#define _fpos64_t _fpos_t
#endif
struct __sFILE64 { struct __sFILE64 {
unsigned char *_p; /* current position in (some) buffer */ unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */ int _r; /* read space left for getc() */

View File

@ -49,12 +49,6 @@ extern inline struct _reent *__getreent (void)
#define __FILENAME_MAX__ 4096 /* Keep in sync with PATH_MAX in limits.h. */ #define __FILENAME_MAX__ 4096 /* Keep in sync with PATH_MAX in limits.h. */
/* Unfortunately we defined __LARGE64_FILES until Cygwin 3.3.6, so
FILE was based on `struct __sFILE64'. The name is exposed into
userspace and consequentially used in C++ name mangling. We must
redefine __sFILE as __sFILE64 to stay backward compatible. */
#define __sFILE __sFILE64
/* The following block of macros is required to build newlib correctly for /* The following block of macros is required to build newlib correctly for
Cygwin. Changing them in applications has no or not the desired effect. Cygwin. Changing them in applications has no or not the desired effect.
Just leave them alone. */ Just leave them alone. */