Functions _fstat32i64 (alias of _fstati64), _stat32i64 (alias of _stati64)
and _wstat32i64 (alias of _wstati64) are available since msvcrt40.dll.
These functions returns 64-bit st_size and 32-bit file timestamps.

For pre-msvcrt40 CRT import libraries provides mingw-w64 emulation of those
functions via the _fstat64, _stat64 and _stat64 functions, which returns
both st_size and file timestamps in 64-bit precision.

When timestamp does not fit into the 32-bit field then sets field to invalid
value -1. This is behavior of msvcrt functions with 32-bit time_t fields.

Note that _fstat64, _stat64 and _stat64 functions are available in all CRT
import libraries, in pre-msvcr70 CRT import libraries they are emulated.
---
 mingw-w64-crt/Makefile.am         |  3 +++
 mingw-w64-crt/stdio/_fstat32i64.c | 42 +++++++++++++++++++++++++++++++
 mingw-w64-crt/stdio/_stat32i64.c  | 42 +++++++++++++++++++++++++++++++
 mingw-w64-crt/stdio/_wstat32i64.c | 42 +++++++++++++++++++++++++++++++
 4 files changed, 129 insertions(+)
 create mode 100644 mingw-w64-crt/stdio/_fstat32i64.c
 create mode 100644 mingw-w64-crt/stdio/_stat32i64.c
 create mode 100644 mingw-w64-crt/stdio/_wstat32i64.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 2b5c6e83d83d..76c12f682857 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -786,6 +786,9 @@ src_pre_msvcrt40=\
   misc/_dstbias.c \
   misc/dummy__setusermatherr.c \
   stdio/_filelengthi64.c \
+  stdio/_fstat32i64.c \
+  stdio/_stat32i64.c \
+  stdio/_wstat32i64.c \
   stdio/fgetpos.c \
   stdio/fsetpos.c
 
diff --git a/mingw-w64-crt/stdio/_fstat32i64.c 
b/mingw-w64-crt/stdio/_fstat32i64.c
new file mode 100644
index 000000000000..1bd63cd6001c
--- /dev/null
+++ b/mingw-w64-crt/stdio/_fstat32i64.c
@@ -0,0 +1,42 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <sys/stat.h>
+#include <stdint.h>
+
+/* When the file time does not fit into the st_Xtime field:
+ *           crtdll-msvcr71   msvcr80+
+ * st_Xtime       -1             -1
+ * 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.
+ */
+int __cdecl _fstat32i64(int _FileDes,struct _stat32i64 *_Stat)
+{
+  struct _stat64 st;
+  int ret=_fstat64(_FileDes,&st);
+  if (ret != 0)
+    return ret;
+  _Stat->st_dev=st.st_dev;
+  _Stat->st_ino=st.st_ino;
+  _Stat->st_mode=st.st_mode;
+  _Stat->st_nlink=st.st_nlink;
+  _Stat->st_uid=st.st_uid;
+  _Stat->st_gid=st.st_gid;
+  _Stat->st_rdev=st.st_rdev;
+  _Stat->st_size=st.st_size;
+  _Stat->st_atime=((st.st_atime > INT32_MAX) ? -1 : st.st_atime);
+  _Stat->st_mtime=((st.st_mtime > INT32_MAX) ? -1 : st.st_mtime);
+  _Stat->st_ctime=((st.st_ctime > INT32_MAX) ? -1 : st.st_ctime);
+  return 0;
+}
+int (__cdecl *__MINGW_IMP_SYMBOL(_fstat32i64))(int, struct _stat32i64 *) = 
_fstat32i64;
+
+#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 *);
diff --git a/mingw-w64-crt/stdio/_stat32i64.c b/mingw-w64-crt/stdio/_stat32i64.c
new file mode 100644
index 000000000000..641f2f556e29
--- /dev/null
+++ b/mingw-w64-crt/stdio/_stat32i64.c
@@ -0,0 +1,42 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <sys/stat.h>
+#include <stdint.h>
+
+/* When the file time does not fit into the st_Xtime field:
+ *           crtdll-msvcr71   msvcr80+
+ * st_Xtime       -1             -1
+ * 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.
+ */
+int __cdecl _stat32i64(const char *_Name,struct _stat32i64 *_Stat)
+{
+  struct _stat64 st;
+  int ret=_stat64(_Name,&st);
+  if (ret != 0)
+    return ret;
+  _Stat->st_dev=st.st_dev;
+  _Stat->st_ino=st.st_ino;
+  _Stat->st_mode=st.st_mode;
+  _Stat->st_nlink=st.st_nlink;
+  _Stat->st_uid=st.st_uid;
+  _Stat->st_gid=st.st_gid;
+  _Stat->st_rdev=st.st_rdev;
+  _Stat->st_size=st.st_size;
+  _Stat->st_atime=((st.st_atime > INT32_MAX) ? -1 : st.st_atime);
+  _Stat->st_mtime=((st.st_mtime > INT32_MAX) ? -1 : st.st_mtime);
+  _Stat->st_ctime=((st.st_ctime > INT32_MAX) ? -1 : st.st_ctime);
+  return 0;
+}
+int (__cdecl *__MINGW_IMP_SYMBOL(_stat32i64))(const char *, struct _stat32i64 
*) = _stat32i64;
+
+#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 *);
diff --git a/mingw-w64-crt/stdio/_wstat32i64.c 
b/mingw-w64-crt/stdio/_wstat32i64.c
new file mode 100644
index 000000000000..dab760069cbc
--- /dev/null
+++ b/mingw-w64-crt/stdio/_wstat32i64.c
@@ -0,0 +1,42 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <sys/stat.h>
+#include <stdint.h>
+
+/* When the file time does not fit into the st_Xtime field:
+ *           crtdll-msvcr71   msvcr80+
+ * st_Xtime       -1             -1
+ * 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.
+ */
+int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat)
+{
+  struct _stat64 st;
+  int ret=_wstat64(_Name,&st);
+  if (ret != 0)
+    return ret;
+  _Stat->st_dev=st.st_dev;
+  _Stat->st_ino=st.st_ino;
+  _Stat->st_mode=st.st_mode;
+  _Stat->st_nlink=st.st_nlink;
+  _Stat->st_uid=st.st_uid;
+  _Stat->st_gid=st.st_gid;
+  _Stat->st_rdev=st.st_rdev;
+  _Stat->st_size=st.st_size;
+  _Stat->st_atime=((st.st_atime > INT32_MAX) ? -1 : st.st_atime);
+  _Stat->st_mtime=((st.st_mtime > INT32_MAX) ? -1 : st.st_mtime);
+  _Stat->st_ctime=((st.st_ctime > INT32_MAX) ? -1 : st.st_ctime);
+  return 0;
+}
+int (__cdecl *__MINGW_IMP_SYMBOL(_wstat32i64))(const wchar_t *, struct 
_stat32i64 *) = _wstat32i64;
+
+#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 *);
-- 
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