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

Reply via email to