crtdll.dll's struct _stat is different than msvcrt.dll's struct _stat.
crtdll.dll's dev_t type (used in struct _stat) is short but msvcrt.dll's
dev_t type is unsigned int.

Fix this problem by providing mingw-w64 _stat32() and _fstat32() compatible
wrappers around crtdll.dll's _stat() and _fstat() functions. And then
redefining _stat, _fstat and fstat symbol aliases to the wrapper functions.

Advantage of this approach over adding #ifdef for crtdll builds into header
file for dev_t type is ABI compatibility between crtdll builds and other
CRT builds, at the expense of a bit more glue code in crtdll.dll import
library.

Note that mingw-w64 already provides custom stat() implantation which calls
_stat32() and therefore it already resolves to the correct function. No
need to update stat() function or its alias.

This change makes it possible to use stat functions from mingw-w64 header
files also with crtdll.dll library (via wrappers in crtdll import library).
---
 mingw-w64-crt/Makefile.am                    |  2 ++
 mingw-w64-crt/def-include/crt-aliases.def.in |  8 +++++
 mingw-w64-crt/lib32/crtdll.def.in            |  4 +--
 mingw-w64-crt/misc/crtdll_fstat.c            | 28 +++++++++++++++
 mingw-w64-crt/misc/crtdll_stat.c             | 30 ++++++++++++++++
 mingw-w64-crt/misc/crtdll_stat.h             | 36 ++++++++++++++++++++
 6 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 mingw-w64-crt/misc/crtdll_fstat.c
 create mode 100644 mingw-w64-crt/misc/crtdll_stat.c
 create mode 100644 mingw-w64-crt/misc/crtdll_stat.h

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 7607e31cbf2e..aa538c184ea6 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -662,6 +662,8 @@ src_msvcrtarm64=\
 src_crtdll=\
   misc/crtdll__getmainargs.c \
   misc/crtdll__ismbblead.c \
+  misc/crtdll_fstat.c \
+  misc/crtdll_stat.c \
   math/x86/_copysignf.c \
   misc/___mb_cur_max_func.c \
   misc/__badioinfo.c \
diff --git a/mingw-w64-crt/def-include/crt-aliases.def.in 
b/mingw-w64-crt/def-include/crt-aliases.def.in
index c74fa641f4e8..aa331fcda34b 100644
--- a/mingw-w64-crt/def-include/crt-aliases.def.in
+++ b/mingw-w64-crt/def-include/crt-aliases.def.in
@@ -65,7 +65,9 @@ ADD_UNDERSCORE(fileno)
 ; ADD_UNDERSCORE(flushall)
 ADD_UNDERSCORE(fputchar)
 #ifdef FIXED_SIZE_SYMBOLS
+#ifndef CRTDLL
 ADD_UNDERSCORE(fstat)
+#endif
 #else
 F32(fstat == _fstat32)
 F64(fstat == _fstat64i32)
@@ -130,7 +132,9 @@ ADD_UNDERSCORE(spawnve)
 ADD_UNDERSCORE(spawnvp)
 ADD_UNDERSCORE(spawnvpe)
 #endif
+#ifndef CRTDLL
 ; stat is provided by mingw to workaround trailing slash issue in _stat
+#endif
 #ifdef NO_STRCMPI_ALIAS
 ; Symbol _strcmpi is natively present and defined in the library def file
 ; So define strcmpi as an alias to _strcmpi
@@ -387,7 +391,9 @@ F64(_wfindnexti64 == _wfindnext64)
 
 ; This is list of stat symbol aliases, every CRT library has either stat 
symbols with SIZE suffix or without them
 #ifdef FIXED_SIZE_SYMBOLS
+#ifndef CRTDLL
 F32(_fstat32 == _fstat)
+#endif
 F64(_fstat64i32 == _fstat)
 #ifndef NO_I64_FIXED_SIZE
 F32(_fstat32i64 == _fstati64)
@@ -395,7 +401,9 @@ F32(_fstat32i64 == _fstati64)
 F64(_fstat64 == _fstati64)
 #endif
 #endif
+#ifndef CRTDLL
 F32(_stat32 == _stat)
+#endif
 F64(_stat64i32 == _stat)
 #ifndef NO_I64_FIXED_SIZE
 F32(_stat32i64 == _stati64)
diff --git a/mingw-w64-crt/lib32/crtdll.def.in 
b/mingw-w64-crt/lib32/crtdll.def.in
index 7988e75f9e92..1236eb2e8bac 100644
--- a/mingw-w64-crt/lib32/crtdll.def.in
+++ b/mingw-w64-crt/lib32/crtdll.def.in
@@ -193,7 +193,7 @@ _fpreset DATA
 _fputchar
 _fputwchar
 _fsopen
-_fstat
+__crtdll_fstat == _fstat ; crtdll.dll's _fstat is incompatible with 
mingw-w64's _fstat, real _fstat provided by emu
 _ftime
 _ftol
 _fullpath
@@ -364,7 +364,7 @@ _spawnve
 _spawnvp
 _spawnvpe
 _splitpath
-_stat
+__crtdll_stat == _stat ; crtdll.dll's _stat is incompatible with mingw-w64's 
_stat, real _stat provided by emu
 _statusfp
 _strcmpi
 _strdate
diff --git a/mingw-w64-crt/misc/crtdll_fstat.c 
b/mingw-w64-crt/misc/crtdll_fstat.c
new file mode 100644
index 000000000000..f0b3b748b0eb
--- /dev/null
+++ b/mingw-w64-crt/misc/crtdll_fstat.c
@@ -0,0 +1,28 @@
+/**
+ * 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 "crtdll_stat.h"
+
+/* Define _fstat32() function via crtdll.dll _fstat() function */
+_CRTIMP int __cdecl __crtdll_fstat(int fd, struct __crtdll_stat *crtdll_stat);
+int __cdecl _fstat32(int fd, struct _stat32 *stat)
+{
+  struct __crtdll_stat crtdll_stat;
+  int ret = __crtdll_fstat(fd, &crtdll_stat);
+  if (ret == 0)
+    copy_stat_members(stat, &crtdll_stat);
+  return ret;
+}
+int (__cdecl *__MINGW_IMP_SYMBOL(_fstat32))(int fd, struct _stat32 *stat) = 
_fstat32;
+
+#undef _fstat
+int __attribute__ ((alias ("_fstat32"))) __cdecl _fstat(int fd, struct _stat32 
*stat);
+extern int __attribute__ ((alias 
(__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_fstat32))))) (__cdecl 
*__MINGW_IMP_SYMBOL(_fstat))(int fd, struct _stat32 *stat);
+
+#undef fstat
+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/crtdll_stat.c b/mingw-w64-crt/misc/crtdll_stat.c
new file mode 100644
index 000000000000..f17bfbe93488
--- /dev/null
+++ b/mingw-w64-crt/misc/crtdll_stat.c
@@ -0,0 +1,30 @@
+/**
+ * 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 "crtdll_stat.h"
+
+/* Define _stat32() function via crtdll.dll _stat() function */
+_CRTIMP int __cdecl __crtdll_stat(const char *name, struct __crtdll_stat 
*crtdll_stat);
+int __cdecl _stat32(const char *name, struct _stat32 *stat)
+{
+  struct __crtdll_stat crtdll_stat;
+  int ret = __crtdll_stat(name, &crtdll_stat);
+  if (ret == 0)
+    copy_stat_members(stat, &crtdll_stat);
+  return ret;
+}
+int (__cdecl *__MINGW_IMP_SYMBOL(_stat32))(const char *name, struct _stat32 
*stat) = _stat32;
+
+#undef _stat
+int __attribute__ ((alias ("_stat32"))) __cdecl _stat(const char *name, struct 
_stat32 *stat);
+extern int __attribute__ ((alias 
(__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_stat32))))) (__cdecl 
*__MINGW_IMP_SYMBOL(_stat))(const char *name, struct _stat32 *stat);
+
+/*
+ * Function stat() (without leading underline) is provided by mingw-w64
+ * emulation due to trailing stash issue, so alias is not defined here.
+ * Emulation calls _stat32() function, which resolve to the correct one.
+ */
diff --git a/mingw-w64-crt/misc/crtdll_stat.h b/mingw-w64-crt/misc/crtdll_stat.h
new file mode 100644
index 000000000000..032e863ceb9b
--- /dev/null
+++ b/mingw-w64-crt/misc/crtdll_stat.h
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+/* crtdll.dll's dev_t is short, msvcrt.dll's dev_t is unsigned int */
+typedef short __crtdll_dev_t;
+
+struct __crtdll_stat {
+  __crtdll_dev_t st_dev;
+  _ino_t st_ino;
+  unsigned short st_mode;
+  short st_nlink;
+  short st_uid;
+  short st_gid;
+  __crtdll_dev_t st_rdev;
+  _off_t st_size;
+  __time32_t st_atime;
+  __time32_t st_mtime;
+  __time32_t st_ctime;
+};
+
+#define copy_stat_members(dest, src) do { \
+  (dest)->st_dev   = (src)->st_dev;       \
+  (dest)->st_ino   = (src)->st_ino;       \
+  (dest)->st_mode  = (src)->st_mode;      \
+  (dest)->st_nlink = (src)->st_nlink;     \
+  (dest)->st_uid   = (src)->st_uid;       \
+  (dest)->st_gid   = (src)->st_gid;       \
+  (dest)->st_rdev  = (src)->st_rdev;      \
+  (dest)->st_size  = (src)->st_size;      \
+  (dest)->st_atime = (src)->st_atime;     \
+  (dest)->st_mtime = (src)->st_mtime;     \
+  (dest)->st_ctime = (src)->st_ctime;     \
+} while (0)
-- 
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