headers: Fix declaration of POSIX stat/fstat and LFS stat64/fstat64 functions
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].
Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/misc/crtdll_fstat.c b/mingw-w64-crt/misc/crtdll_fstat.c
index f0b3b74..2fe5b1e 100644
--- a/mingw-w64-crt/misc/crtdll_fstat.c
+++ b/mingw-w64-crt/misc/crtdll_fstat.c
@@ -24,5 +24,6 @@
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 e87ab5e..f520ef6 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 5595e76..72e22a2 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 8df51a4..28c5d73 100644
--- a/mingw-w64-crt/stdio/_fstat64.c
+++ b/mingw-w64-crt/stdio/_fstat64.c
@@ -44,6 +44,5 @@
#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 0f1c73f..930696f 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 96b0475..a496a54 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 8ce0975..84eabba 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 0c133cd..5d2e6df 100644
--- a/mingw-w64-headers/crt/sys/stat.h
+++ b/mingw-w64-headers/crt/sys/stat.h
@@ -124,31 +124,69 @@
#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