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