Move LFS defines of stat64/fstat64 from _mingw_stat64.h to sys/stat.h. Move struct stat from _mingw_stat64.h to sys/stat.h.
Fix definition of POSIX struct stat to follow both _FILE_OFFSET_BITS and _USE_32BIT_TIME_T settings. Fix declaration of POSIX stat(), fstat() and mingw-w64 wstat() functions to follow all combinations of _FILE_OFFSET_BITS and _USE_32BIT_TIME_T settings. Declare fstat() as a function instead of macro. Define it as alias via __MINGW_ASM_CALL to one of the CRT _fstat* function based on _FILE_OFFSET_BITS and _USE_32BIT_TIME_T settings. In the same way declare stat() and wstat() as functions. But as alias to one of the mingw-w64 (w)stat* function. This is needed because msvcrt _(w)stat* functions have issue with trailing slash and requires mingw-w64 wrapper for POSIX compatibility. Additionally define struct stat64 for LFS functions stat64(), fstat64() and mingw-w64 function wstat64(). And again declare them as a functions instead of macro. Keyword stat has to be declared as a function, not as a macro because it would override effect of struct stat. Do not declare these stat/fstat/wstat functions when building the mingw-w64 runtime itself as it is not clear which of those stat[size] / fstat[size] / wstat[size] symbol should be used. Instead the mingw-w64 source file should call the appropriate ABI compatible *stat[size] function with corresponding ABI compatible struct _stat[size]. --- mingw-w64-crt/misc/crtdll_fstat.c | 1 + mingw-w64-crt/misc/ftw.c | 2 - mingw-w64-crt/misc/ftw64.c | 2 +- mingw-w64-crt/stdio/_fstat64.c | 5 +- mingw-w64-crt/stdio/stat64.c | 8 +-- mingw-w64-crt/stdio/wstat64.c | 7 +-- mingw-w64-headers/crt/_mingw_stat64.h | 23 +------- mingw-w64-headers/crt/sys/stat.h | 80 ++++++++++++++++++++------- 8 files changed, 72 insertions(+), 56 deletions(-) diff --git a/mingw-w64-crt/misc/crtdll_fstat.c b/mingw-w64-crt/misc/crtdll_fstat.c index f0b3b748b0eb..2fe5b1e9c342 100644 --- a/mingw-w64-crt/misc/crtdll_fstat.c +++ b/mingw-w64-crt/misc/crtdll_fstat.c @@ -24,5 +24,6 @@ int __attribute__ ((alias ("_fstat32"))) __cdecl _fstat(int fd, struct _stat32 * extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat32))))) (__cdecl *__MINGW_IMP_SYMBOL(_fstat))(int fd, struct _stat32 *stat); #undef fstat +struct stat; int __attribute__ ((alias ("_fstat32"))) __cdecl fstat(int fd, struct stat *stat); extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat32))))) (__cdecl *__MINGW_IMP_SYMBOL(fstat))(int fd, struct stat *stat); diff --git a/mingw-w64-crt/misc/ftw.c b/mingw-w64-crt/misc/ftw.c index e87ab5e2cd91..f520ef63da78 100644 --- a/mingw-w64-crt/misc/ftw.c +++ b/mingw-w64-crt/misc/ftw.c @@ -15,10 +15,8 @@ #include <dirent.h> #include <ftw.h> -#undef stat64 int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat); int __cdecl stat32i64(const char *_Filename, struct _stat32i64 *_Stat); -int __cdecl stat64(const char *_Filename, struct _stat64 *_Stat); int __cdecl stat64i32(const char *_Filename, struct _stat64i32 *_Stat); typedef struct dir_data_t { diff --git a/mingw-w64-crt/misc/ftw64.c b/mingw-w64-crt/misc/ftw64.c index 5595e76c656b..72e22a214e2a 100644 --- a/mingw-w64-crt/misc/ftw64.c +++ b/mingw-w64-crt/misc/ftw64.c @@ -6,5 +6,5 @@ #define FUNC_FTW ftw64 #define FUNC_NFTW nftw64 #define FUNC_STAT stat64 -#define STRUCT_STAT struct _stat64 +#define STRUCT_STAT struct stat64 #include "ftw.c" diff --git a/mingw-w64-crt/stdio/_fstat64.c b/mingw-w64-crt/stdio/_fstat64.c index 8df51a42aad9..28c5d73c1f55 100644 --- a/mingw-w64-crt/stdio/_fstat64.c +++ b/mingw-w64-crt/stdio/_fstat64.c @@ -44,6 +44,5 @@ static int __cdecl emu__fstat64(int fd, struct _stat64 *stat) #define CALL fd, stat #include "msvcrt_or_emu_glue.h" -#undef fstat64 -int __attribute__ ((alias ("_fstat64"))) __cdecl fstat64(int, struct _stat64 *); -extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat64))))) (__cdecl *__MINGW_IMP_SYMBOL(fstat64))(int, struct _stat64 *); +int __attribute__ ((alias ("_fstat64"))) __cdecl fstat64(int, struct stat64 *); +extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat64))))) (__cdecl *__MINGW_IMP_SYMBOL(fstat64))(int, struct stat64 *); diff --git a/mingw-w64-crt/stdio/stat64.c b/mingw-w64-crt/stdio/stat64.c index 0f1c73fe0946..930696faeeb5 100644 --- a/mingw-w64-crt/stdio/stat64.c +++ b/mingw-w64-crt/stdio/stat64.c @@ -9,14 +9,12 @@ char *__mingw_fix_stat_path(const char *_path); -#undef stat64 -int __cdecl stat64(const char *_Filename, struct _stat64 *_Stat); -int __cdecl stat64(const char *_Filename, struct _stat64 *_Stat) +int __cdecl stat64(const char *_Filename, struct stat64 *_Stat) { char *_path = __mingw_fix_stat_path(_Filename); - int ret = _stat64(_path, _Stat); + int ret = _stat64(_path, (struct _stat64 *)_Stat); if (_path != _Filename) free(_path); return ret; } -int (__cdecl *__MINGW_IMP_SYMBOL(stat64))(const char *, struct _stat64 *) = stat64; +int (__cdecl *__MINGW_IMP_SYMBOL(stat64))(const char *, struct stat64 *) = stat64; diff --git a/mingw-w64-crt/stdio/wstat64.c b/mingw-w64-crt/stdio/wstat64.c index 96b0475cf4ae..a496a54eb025 100644 --- a/mingw-w64-crt/stdio/wstat64.c +++ b/mingw-w64-crt/stdio/wstat64.c @@ -9,13 +9,12 @@ wchar_t *__mingw_fix_wstat_path(const wchar_t *_path); -int __cdecl wstat64(const wchar_t *_Filename, struct _stat64 *_Stat); -int __cdecl wstat64(const wchar_t *_Filename, struct _stat64 *_Stat) +int __cdecl wstat64(const wchar_t *_Filename, struct stat64 *_Stat) { wchar_t *_path = __mingw_fix_wstat_path(_Filename); - int ret = _wstat64(_path, _Stat); + int ret = _wstat64(_path, (struct _stat64 *)_Stat); if (_path != _Filename) free(_path); return ret; } -int (__cdecl *__MINGW_IMP_SYMBOL(wstat64))(const wchar_t *, struct _stat64 *) = wstat64; +int (__cdecl *__MINGW_IMP_SYMBOL(wstat64))(const wchar_t *, struct stat64 *) = wstat64; diff --git a/mingw-w64-headers/crt/_mingw_stat64.h b/mingw-w64-headers/crt/_mingw_stat64.h index 8ce097561116..84eabba9698b 100644 --- a/mingw-w64-headers/crt/_mingw_stat64.h +++ b/mingw-w64-headers/crt/_mingw_stat64.h @@ -1,5 +1,8 @@ #ifndef _STAT_DEFINED +/* __stat64 is needed for compatibility with msvc */ +#define __stat64 _stat64 + #ifdef _USE_32BIT_TIME_T #define _fstat _fstat32 #define _fstati64 _fstat32i64 @@ -30,22 +33,6 @@ __time32_t st_ctime; }; -#ifndef NO_OLDNAMES - struct stat { - _dev_t st_dev; - _ino_t st_ino; - unsigned short st_mode; - short st_nlink; - short st_uid; - short st_gid; - _dev_t st_rdev; - _off_t st_size; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; - }; -#endif /* NO_OLDNAMES */ - struct _stat32i64 { _dev_t st_dev; _ino_t st_ino; @@ -88,9 +75,5 @@ __time64_t st_ctime; }; -#define __stat64 _stat64 -#define stat64 _stat64 /* for POSIX */ -#define fstat64 _fstat64 /* for POSIX */ - #define _STAT_DEFINED #endif /* _STAT_DEFINED */ diff --git a/mingw-w64-headers/crt/sys/stat.h b/mingw-w64-headers/crt/sys/stat.h index 0c133cdc11fa..5d2e6dfaf031 100644 --- a/mingw-w64-headers/crt/sys/stat.h +++ b/mingw-w64-headers/crt/sys/stat.h @@ -124,31 +124,69 @@ extern "C" { #endif -#if !defined (RC_INVOKED) && !defined (NO_OLDNAMES) -int __cdecl fstat(int _Desc,struct stat *_Stat); -#ifdef _UCRT - __mingw_ovr int __cdecl stat(const char *_Filename,struct stat *_Stat) - { - return _stat(_Filename, (struct _stat *)_Stat); - } - __mingw_ovr int __cdecl wstat(const wchar_t *_Filename,struct stat *_Stat) - { - return _wstat(_Filename, (struct _stat *)_Stat); - } -#else -int __cdecl stat(const char *_Filename,struct stat *_Stat); -int __cdecl wstat(const wchar_t *_Filename,struct stat *_Stat); -#endif -#endif /* !RC_INVOKED && !NO_OLDNAMES */ - +#if !defined(NO_OLDNAMES) || defined(_POSIX) + +/* + * When building mingw-w64 CRT files it is required that the fstat, stat and + * wstat functions are not declared with __MINGW_ASM_CALL redirection. + * Otherwise the mingw-w64 would provide broken fstat, stat and wstat symbols. + * To prevent ABI issues, the mingw-w64 runtime should not call the fstat, + * stat and wstat functions, instead it should call the fixed-size variants. + */ +#ifndef _CRTBLD +struct stat { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + off_t st_size; /* off_t follows _FILE_OFFSET_BITS */ + time_t st_atime; /* time_t follows _USE_32BIT_TIME_T */ + time_t st_mtime; + time_t st_ctime; +}; #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) #ifdef _USE_32BIT_TIME_T -#define stat _stat32i64 -#define fstat _fstat32i64 +int __cdecl fstat(int _Desc, struct stat *_Stat) __MINGW_ASM_CALL(_fstat32i64); +int __cdecl stat(const char *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(stat32i64); +int __cdecl wstat(const wchar_t *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(wstat32i64); #else -#define stat _stat64 -#define fstat _fstat64 +int __cdecl fstat(int _Desc, struct stat *_Stat) __MINGW_ASM_CALL(_fstat64); +int __cdecl stat(const char *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(stat64); +int __cdecl wstat(const wchar_t *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(wstat64); #endif +#else +#ifdef _USE_32BIT_TIME_T +int __cdecl fstat(int _Desc, struct stat *_Stat) __MINGW_ASM_CALL(_fstat32); +int __cdecl stat(const char *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(stat32); +int __cdecl wstat(const wchar_t *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(wstat32); +#else +int __cdecl fstat(int _Desc, struct stat *_Stat) __MINGW_ASM_CALL(_fstat64i32); +int __cdecl stat(const char *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(stat64i32); +int __cdecl wstat(const wchar_t *_Filename, struct stat *_Stat) __MINGW_ASM_CALL(wstat64i32); +#endif +#endif +#endif + +struct stat64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __MINGW_EXTENSION __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; +int __cdecl fstat64(int _Desc, struct stat64 *_Stat); +int __cdecl stat64(const char *_Filename, struct stat64 *_Stat); +int __cdecl wstat64(const wchar_t *_Filename, struct stat64 *_Stat); + #endif #ifdef __cplusplus -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public