All 64-bit CRT libraries except the msvcrt.dll provides native _fstat32i64, _stat32i64 and _wstat32i64 functions. 64-bit system os msvcrt.dll is an exception and does not contain these function.
mingw-w64 already contains emulation of these functions for pre-msvcrt40 32-bit builds. Extend this emulation for 64-bit msvcrt.dll builds. --- mingw-w64-crt/Makefile.am | 6 ++++++ mingw-w64-crt/stdio/_fstat32i64.c | 12 ++++++++++-- mingw-w64-crt/stdio/_stat32i64.c | 12 ++++++++++-- mingw-w64-crt/stdio/_wstat32i64.c | 12 ++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index f603456693e4..85c87536f111 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -627,8 +627,11 @@ src_msvcrt64=\ misc/wctob.c \ stdio/_fseeki64.c \ stdio/_fstat32.c \ + stdio/_fstat32i64.c \ stdio/_stat32.c \ + stdio/_stat32i64.c \ stdio/_wstat32.c \ + stdio/_wstat32i64.c \ string/wcstok.c # Files included in libmsvcrt-os.a (for msvcrt.dll) on arm32 @@ -783,9 +786,12 @@ src_msvcrtarm64=\ misc/__initenv.c \ misc/__winitenv.c \ stdio/_fstat32.c \ + stdio/_fstat32i64.c \ stdio/_setmaxstdio.c \ stdio/_stat32.c \ + stdio/_stat32i64.c \ stdio/_wstat32.c \ + stdio/_wstat32i64.c \ stdio/gets.c if ARM64EC diff --git a/mingw-w64-crt/stdio/_fstat32i64.c b/mingw-w64-crt/stdio/_fstat32i64.c index d10c35577e5c..5d737d5e0cfb 100644 --- a/mingw-w64-crt/stdio/_fstat32i64.c +++ b/mingw-w64-crt/stdio/_fstat32i64.c @@ -6,6 +6,7 @@ #include <sys/stat.h> #include <stdint.h> +#include <errno.h> /* When the file time does not fit into the st_Xtime field: * crtdll-msvcr71 msvcr80+ @@ -13,8 +14,9 @@ * errno no change EINVAL * returns 0 0 * - * This file is used only for pre-msvcrt40 builds, - * So use the pre-msvcrt40 behavior - fills -1 without errno change. + * This file is used for 32-bit pre-msvcrt40 builds and 64-bit msvcrt.dll builds. + * So for 32-bit use the pre-msvcrt40 behavior - fills -1 without errno change. + * And for 64-bit use the msvcr80+ behavior - fills -1 with setting errno to EINVAL. */ int __cdecl _fstat32i64(int _FileDes,struct _stat32i64 *_Stat) { @@ -33,10 +35,16 @@ int __cdecl _fstat32i64(int _FileDes,struct _stat32i64 *_Stat) _Stat->st_atime=((st.st_atime < 0 || st.st_atime > INT32_MAX) ? -1 : st.st_atime); _Stat->st_mtime=((st.st_mtime < 0 || st.st_mtime > INT32_MAX) ? -1 : st.st_mtime); _Stat->st_ctime=((st.st_ctime < 0 || st.st_ctime > INT32_MAX) ? -1 : st.st_ctime); +#ifdef _WIN64 + if (_Stat->st_atime == -1 || _Stat->st_mtime == -1 || _Stat->st_ctime == -1) + errno = EINVAL; +#endif return 0; } int (__cdecl *__MINGW_IMP_SYMBOL(_fstat32i64))(int, struct _stat32i64 *) = _fstat32i64; +#ifndef _WIN64 #undef _fstati64 int __attribute__ ((alias ("_fstat32i64"))) __cdecl _fstati64(int, struct _stat32i64 *); extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat32i64))))) (__cdecl *__MINGW_IMP_SYMBOL(_fstati64))(int, struct _stat32i64 *); +#endif diff --git a/mingw-w64-crt/stdio/_stat32i64.c b/mingw-w64-crt/stdio/_stat32i64.c index 3d3d2702a051..e4a6f964c8d6 100644 --- a/mingw-w64-crt/stdio/_stat32i64.c +++ b/mingw-w64-crt/stdio/_stat32i64.c @@ -6,6 +6,7 @@ #include <sys/stat.h> #include <stdint.h> +#include <errno.h> /* When the file time does not fit into the st_Xtime field: * crtdll-msvcr71 msvcr80+ @@ -13,8 +14,9 @@ * errno no change EINVAL * returns 0 0 * - * This file is used only for pre-msvcrt40 builds, - * So use the pre-msvcrt40 behavior - fills -1 without errno change. + * This file is used for 32-bit pre-msvcrt40 builds and 64-bit msvcrt.dll builds. + * So for 32-bit use the pre-msvcrt40 behavior - fills -1 without errno change. + * And for 64-bit use the msvcr80+ behavior - fills -1 with setting errno to EINVAL. */ int __cdecl _stat32i64(const char *_Name,struct _stat32i64 *_Stat) { @@ -33,10 +35,16 @@ int __cdecl _stat32i64(const char *_Name,struct _stat32i64 *_Stat) _Stat->st_atime=((st.st_atime < 0 || st.st_atime > INT32_MAX) ? -1 : st.st_atime); _Stat->st_mtime=((st.st_mtime < 0 || st.st_mtime > INT32_MAX) ? -1 : st.st_mtime); _Stat->st_ctime=((st.st_ctime < 0 || st.st_ctime > INT32_MAX) ? -1 : st.st_ctime); +#ifdef _WIN64 + if (_Stat->st_atime == -1 || _Stat->st_mtime == -1 || _Stat->st_ctime == -1) + errno = EINVAL; +#endif return 0; } int (__cdecl *__MINGW_IMP_SYMBOL(_stat32i64))(const char *, struct _stat32i64 *) = _stat32i64; +#ifndef _WIN64 #undef _stati64 int __attribute__ ((alias ("_stat32i64"))) __cdecl _stati64(const char *, struct _stat32i64 *); extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_stat32i64))))) (__cdecl *__MINGW_IMP_SYMBOL(_stati64))(const char *, struct _stat32i64 *); +#endif diff --git a/mingw-w64-crt/stdio/_wstat32i64.c b/mingw-w64-crt/stdio/_wstat32i64.c index b6f2e0b0cab9..e7eaf0f027a9 100644 --- a/mingw-w64-crt/stdio/_wstat32i64.c +++ b/mingw-w64-crt/stdio/_wstat32i64.c @@ -6,6 +6,7 @@ #include <sys/stat.h> #include <stdint.h> +#include <errno.h> /* When the file time does not fit into the st_Xtime field: * crtdll-msvcr71 msvcr80+ @@ -13,8 +14,9 @@ * errno no change EINVAL * returns 0 0 * - * This file is used only for pre-msvcrt40 builds, - * So use the pre-msvcrt40 behavior - fills -1 without errno change. + * This file is used for 32-bit pre-msvcrt40 builds and 64-bit msvcrt.dll builds. + * So for 32-bit use the pre-msvcrt40 behavior - fills -1 without errno change. + * And for 64-bit use the msvcr80+ behavior - fills -1 with setting errno to EINVAL. */ int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat) { @@ -33,10 +35,16 @@ int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat) _Stat->st_atime=((st.st_atime < 0 || st.st_atime > INT32_MAX) ? -1 : st.st_atime); _Stat->st_mtime=((st.st_mtime < 0 || st.st_mtime > INT32_MAX) ? -1 : st.st_mtime); _Stat->st_ctime=((st.st_ctime < 0 || st.st_ctime > INT32_MAX) ? -1 : st.st_ctime); +#ifdef _WIN64 + if (_Stat->st_atime == -1 || _Stat->st_mtime == -1 || _Stat->st_ctime == -1) + errno = EINVAL; +#endif return 0; } int (__cdecl *__MINGW_IMP_SYMBOL(_wstat32i64))(const wchar_t *, struct _stat32i64 *) = _wstat32i64; +#ifndef _WIN64 #undef _wstati64 int __attribute__ ((alias ("_wstat32i64"))) __cdecl _wstati64(const wchar_t *, struct _stat32i64 *); extern int __attribute__ ((alias (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_wstat32i64))))) (__cdecl *__MINGW_IMP_SYMBOL(_wstati64))(const wchar_t *, struct _stat32i64 *); +#endif -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public