These functions are available since msvcr70.dll. For older msvcrt versions
provide emulation via _fstat32(), _stat32() and _wstat32() functions. These
functions have only truncated 32-bit file size and timestamp support. Real
64-bit non-truncated file size and timestamp information is retrieved via
the WinAPI calls. For _stat64() and _wstat64() use FindFirstFile() call and
for _fstat64() use GetFileInformationByHandle() call. Same thing is doing
msvcrt DLL library for other stat functions.
Functions _fstat64() and _stat64() are already used by mingw-w64 crt, so
ensure that they are present in every CRT import library.
---
mingw-w64-crt/Makefile.am | 8 +++-
mingw-w64-crt/include/filetime_to_time64.h | 13 ++++++
mingw-w64-crt/lib-common/msvcrt.def.in | 6 +--
mingw-w64-crt/stdio/_fstat64.c | 50 ++++++++++++++++++++++
mingw-w64-crt/stdio/_stat64.c | 48 +++++++++++++++++++++
mingw-w64-crt/stdio/_wstat64.c | 48 +++++++++++++++++++++
6 files changed, 169 insertions(+), 4 deletions(-)
create mode 100644 mingw-w64-crt/include/filetime_to_time64.h
create mode 100644 mingw-w64-crt/stdio/_fstat64.c
create mode 100644 mingw-w64-crt/stdio/_stat64.c
create mode 100644 mingw-w64-crt/stdio/_wstat64.c
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index f2f1e6f8160a..f37a25cb83c6 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -522,11 +522,14 @@ src_msvcrt32=\
misc/wcstoumax.c \
misc/wctob.c \
stdio/_fseeki64.c \
+ stdio/_fstat64.c \
stdio/_fstat64i32.c \
stdio/_scprintf.c \
stdio/_scwprintf.c \
+ stdio/_stat64.c \
stdio/_vscprintf.c \
stdio/_vscwprintf.c \
+ stdio/_wstat64.c \
string/wcstok.c
# Files included in libmsvcrt-os.a (for msvcrt.dll) on x86_64
@@ -774,10 +777,13 @@ src_pre_msvcr70=\
misc/strtoumax.c \
misc/wcstoimax.c \
misc/wcstoumax.c \
+ stdio/_fstat64.c \
stdio/_scprintf.c \
stdio/_scwprintf.c \
+ stdio/_stat64.c \
stdio/_vscprintf.c \
- stdio/_vscwprintf.c
+ stdio/_vscwprintf.c \
+ stdio/_wstat64.c
src_pre_msvcr71=\
misc/_set_purecall_handler.c
diff --git a/mingw-w64-crt/include/filetime_to_time64.h
b/mingw-w64-crt/include/filetime_to_time64.h
new file mode 100644
index 000000000000..2d8459844a5f
--- /dev/null
+++ b/mingw-w64-crt/include/filetime_to_time64.h
@@ -0,0 +1,13 @@
+/**
+ * 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.
+ */
+
+static inline __time64_t filetime_to_time64(FILETIME *filetime)
+{
+ unsigned long long value = ((unsigned long long)filetime->dwHighDateTime
<< 32) | filetime->dwLowDateTime;
+ if (value == 0) return 0; /* 0 has special meaning - not set */
+ /* conversion from unsigned 64-bit FILETIME (1601-01-01 in
100-nanoseconds) to signed 64-bit UNIX timestamp (1970-01-01 in seconds) */
+ return (value - 116444736000000000LL) / 10000000;
+}
diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in
b/mingw-w64-crt/lib-common/msvcrt.def.in
index 7a029b8d423a..afc6092f5bdc 100644
--- a/mingw-w64-crt/lib-common/msvcrt.def.in
+++ b/mingw-w64-crt/lib-common/msvcrt.def.in
@@ -1153,20 +1153,20 @@ F_I386(_chkesp)
_ctime64
_findfirst64
_findnext64
-_fstat64
+F_NON_I386(_fstat64) ; i386 _fstat64 replaced by emu
_ftime64
_futime64
_gmtime64
_localtime64
_mktime64
F_X86_ANY(_osplatform DATA)
-_stat64
+F_NON_I386(_stat64) ; i386 _stat64 replaced by emu
_time64
_utime64
_wctime64
_wfindfirst64
_wfindnext64
-_wstat64
+F_NON_I386(_wstat64) ; i386 _wstat64 replaced by emu
_wutime64
; These symbols were added in Windows 2000 SP4 OS system version of msvcrt.dll
diff --git a/mingw-w64-crt/stdio/_fstat64.c b/mingw-w64-crt/stdio/_fstat64.c
new file mode 100644
index 000000000000..0c059499b7e7
--- /dev/null
+++ b/mingw-w64-crt/stdio/_fstat64.c
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+
+#define __CRT__NO_INLINE
+#include <sys/stat.h>
+#include <io.h>
+#include <windows.h>
+
+#include "filetime_to_time64.h"
+
+static int __cdecl emu__fstat64(int fd, struct _stat64 *stat)
+{
+ BY_HANDLE_FILE_INFORMATION fi;
+ struct _stat32 st;
+ int ret = _fstat32(fd, &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;
+ if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &fi)) {
+ stat->st_size = ((_off64_t)fi.nFileSizeHigh << 32) | fi.nFileSizeLow;
+ stat->st_atime = filetime_to_time64(&fi.ftLastAccessTime);
+ stat->st_mtime = filetime_to_time64(&fi.ftLastWriteTime);
+ stat->st_ctime = filetime_to_time64(&fi.ftCreationTime);
+ } else {
+ stat->st_size = st.st_size; /* truncated value */
+ stat->st_atime = st.st_atime; /* truncated value */
+ stat->st_mtime = st.st_mtime; /* truncated value */
+ stat->st_ctime = st.st_ctime; /* truncated value */
+ }
+ return 0;
+}
+
+#define RETT int
+#define FUNC _fstat64
+#define ARGS 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 *);
diff --git a/mingw-w64-crt/stdio/_stat64.c b/mingw-w64-crt/stdio/_stat64.c
new file mode 100644
index 000000000000..71247f0e4eab
--- /dev/null
+++ b/mingw-w64-crt/stdio/_stat64.c
@@ -0,0 +1,48 @@
+/**
+ * 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.
+ */
+
+#define __CRT__NO_INLINE
+#include <sys/stat.h>
+#include <windows.h>
+
+#include "filetime_to_time64.h"
+
+static int __cdecl emu__stat64(const char *path, struct _stat64 *stat)
+{
+ HANDLE handle;
+ WIN32_FIND_DATAA fi;
+ struct _stat32 st;
+ int ret = _stat32(path, &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;
+ handle = FindFirstFileA(path, &fi);
+ if (handle != INVALID_HANDLE_VALUE) {
+ FindClose(handle);
+ stat->st_size = ((_off64_t)fi.nFileSizeHigh << 32) | fi.nFileSizeLow;
+ stat->st_atime = filetime_to_time64(&fi.ftLastAccessTime);
+ stat->st_mtime = filetime_to_time64(&fi.ftLastWriteTime);
+ stat->st_ctime = filetime_to_time64(&fi.ftCreationTime);
+ } else {
+ stat->st_size = st.st_size; /* truncated value */
+ stat->st_atime = st.st_atime; /* truncated value */
+ stat->st_mtime = st.st_mtime; /* truncated value */
+ stat->st_ctime = st.st_ctime; /* truncated value */
+ }
+ return 0;
+}
+
+#define RETT int
+#define FUNC _stat64
+#define ARGS const char *path, struct _stat64 *stat
+#define CALL path, stat
+#include "msvcrt_or_emu_glue.h"
diff --git a/mingw-w64-crt/stdio/_wstat64.c b/mingw-w64-crt/stdio/_wstat64.c
new file mode 100644
index 000000000000..9d5a39ebc79d
--- /dev/null
+++ b/mingw-w64-crt/stdio/_wstat64.c
@@ -0,0 +1,48 @@
+/**
+ * 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.
+ */
+
+#define __CRT__NO_INLINE
+#include <sys/stat.h>
+#include <windows.h>
+
+#include "filetime_to_time64.h"
+
+static int __cdecl emu__wstat64(const wchar_t *path, struct _stat64 *stat)
+{
+ HANDLE handle;
+ WIN32_FIND_DATAW fi;
+ struct _stat32 st;
+ int ret = _wstat32(path, &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;
+ handle = FindFirstFileW(path, &fi);
+ if (handle != INVALID_HANDLE_VALUE) {
+ FindClose(handle);
+ stat->st_size = ((_off64_t)fi.nFileSizeHigh << 32) | fi.nFileSizeLow;
+ stat->st_atime = filetime_to_time64(&fi.ftLastAccessTime);
+ stat->st_mtime = filetime_to_time64(&fi.ftLastWriteTime);
+ stat->st_ctime = filetime_to_time64(&fi.ftCreationTime);
+ } else {
+ stat->st_size = st.st_size; /* truncated value */
+ stat->st_atime = st.st_atime; /* truncated value */
+ stat->st_mtime = st.st_mtime; /* truncated value */
+ stat->st_ctime = st.st_ctime; /* truncated value */
+ }
+ return 0;
+}
+
+#define RETT int
+#define FUNC _wstat64
+#define ARGS const wchar_t *path, struct _stat64 *stat
+#define CALL path, stat
+#include "msvcrt_or_emu_glue.h"
--
2.20.1
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public