All 64-bit CRT import libraries already provides _fstat64i32, _stat64i32 and _wstat64i32 function symbols. These symbols are either directly exported from 64-bit CRT DLL library or def file contains alias to other ABI compatible symbols (_fstat, _stat and _wstat).
Also all these functions _fstat64i32, _stat64i32 and _wstat64i32 are provided by msvcr80+ and UCRT, so ensure that mingw-w64 does not provide any replacement for msvcr80+ import libraries. And ensure that libmingwex.a library does not provide duplication of these symbols. For 32-bit pre-msvcr80 CRT import libraries provides mingw-w64 emulation via _fstat64, _stat64 and _wstat64, which just truncates 64-bit st_size (returned by _*stat64 function) to 32-bit st_size (which is ABI of _*stat64i32). Do not use any _mingw_no_trailing_slash workaround as for all these functions with underscore prefix, it is expected that behavior is same as for other stat functions with underscore prefix. These _fstat64i32, _stat64i32 and _wstat64i32 functions in msvcr80+ and UCRT DLL libraries do not touch output struct stat buffer on error. So do same thing in mingw-w64 emulation and remove memset(stat, 0, sizeof(stat)) call in failure path. And add missing __MINGW_IMP_SYMBOL import symbols into mingw-w64 emulation code for these functions as msvcr80+ import libraries already have them. --- mingw-w64-crt/Makefile.am | 10 +++- mingw-w64-crt/stdio/_fstat64i32.c | 18 ++++--- mingw-w64-crt/stdio/_stat64i32.c | 81 +++++-------------------------- mingw-w64-crt/stdio/_wstat64i32.c | 81 +++++-------------------------- 4 files changed, 41 insertions(+), 149 deletions(-) diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index f37a25cb83c6..1f2ab82f9bc6 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -527,9 +527,11 @@ src_msvcrt32=\ stdio/_scprintf.c \ stdio/_scwprintf.c \ stdio/_stat64.c \ + stdio/_stat64i32.c \ stdio/_vscprintf.c \ stdio/_vscwprintf.c \ stdio/_wstat64.c \ + stdio/_wstat64i32.c \ string/wcstok.c # Files included in libmsvcrt-os.a (for msvcrt.dll) on x86_64 @@ -611,6 +613,8 @@ src_msvcrtarm32=\ misc/__winitenv.c \ stdio/_fstat64i32.c \ stdio/_setmaxstdio.c \ + stdio/_stat64i32.c \ + stdio/_wstat64i32.c \ stdio/gets.c if !ENABLE_SOFTMATH @@ -810,6 +814,8 @@ src_pre_msvcr80=\ stdio/_fseeki64.c \ stdio/_fstat64i32.c \ stdio/_ftelli64.c \ + stdio/_stat64i32.c \ + stdio/_wstat64i32.c \ stdio/mingw_lock.c \ string/wcstok.c @@ -1009,8 +1015,8 @@ src_libmingwex=\ \ stdio/strtok_r.c \ stdio/_Exit.c stdio/_findfirst64i32.c stdio/_findnext64i32.c \ - stdio/_stat.c stdio/_stat64i32.c stdio/_wfindfirst64i32.c stdio/_wfindnext64i32.c \ - stdio/_wstat.c stdio/_wstat64i32.c stdio/asprintf.c \ + stdio/_stat.c stdio/_wfindfirst64i32.c stdio/_wfindnext64i32.c \ + stdio/_wstat.c stdio/asprintf.c \ stdio/fopen64.c stdio/fseeko32.c stdio/fseeko64.c stdio/ftello.c \ stdio/ftello64.c stdio/ftruncate64.c stdio/lltoa.c stdio/lltow.c stdio/lseek64.c \ \ diff --git a/mingw-w64-crt/stdio/_fstat64i32.c b/mingw-w64-crt/stdio/_fstat64i32.c index 57cc492d7731..93871c2f4717 100644 --- a/mingw-w64-crt/stdio/_fstat64i32.c +++ b/mingw-w64-crt/stdio/_fstat64i32.c @@ -1,3 +1,9 @@ +/** + * 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> @@ -5,10 +11,8 @@ int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat) { struct _stat64 st; int ret=_fstat64(_FileDes,&st); - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + if (ret != 0) + return ret; _Stat->st_dev=st.st_dev; _Stat->st_ino=st.st_ino; _Stat->st_mode=st.st_mode; @@ -16,10 +20,10 @@ int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; /* 32bit size */ + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_fstat64i32))(int, struct _stat64i32 *) = _fstat64i32; diff --git a/mingw-w64-crt/stdio/_stat64i32.c b/mingw-w64-crt/stdio/_stat64i32.c index 19adf5b0ee19..90e5ee6a644f 100644 --- a/mingw-w64-crt/stdio/_stat64i32.c +++ b/mingw-w64-crt/stdio/_stat64i32.c @@ -1,77 +1,18 @@ -#define __CRT__NO_INLINE -#include <sys/stat.h> -#include <stdlib.h> - /** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. + * 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 char* -_mingw_no_trailing_slash (const char* _path) -{ - int len; - char *p; - - p = (char*)_path; - - if (_path && *_path) { - len = strlen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':')) - return p; - - /* Check UNC \\abc\<name>\ */ - if ((_path[0] == '\\' || _path[0] == '/') - && (_path[1] == '\\' || _path[1] == '/')) - { - const char *r = &_path[2]; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == '/' || _path[len - 1] == '\\') - { - p = (char*)malloc (len); - memcpy (p, _path, len - 1); - p[len - 1] = '\0'; - } - } - - return p; -} +#define __CRT__NO_INLINE +#include <sys/stat.h> int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat) { struct _stat64 st; - char *_path = _mingw_no_trailing_slash(_Name); - - int ret=_stat64(_path,&st); - - if (_path != _Name) - free(_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + 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; @@ -79,10 +20,10 @@ int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_stat64i32))(const char *, struct _stat64i32 *) = _stat64i32; diff --git a/mingw-w64-crt/stdio/_wstat64i32.c b/mingw-w64-crt/stdio/_wstat64i32.c index d6ee07a3d52e..846ed576bdc9 100644 --- a/mingw-w64-crt/stdio/_wstat64i32.c +++ b/mingw-w64-crt/stdio/_wstat64i32.c @@ -1,77 +1,18 @@ -#define __CRT__NO_INLINE -#include <sys/stat.h> -#include <stdlib.h> - /** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. + * 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 wchar_t* -_mingw_no_trailing_slash (const wchar_t* _path) -{ - int len; - wchar_t *p; - - p = (wchar_t*)_path; - - if (_path && *_path) { - len = wcslen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == L':')) - return p; - - /* Check UNC \\abc\<name>\ */ - if ((_path[0] == L'\\' || _path[0] == L'/') - && (_path[1] == L'\\' || _path[1] == L'/')) - { - const wchar_t *r = &_path[2]; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == L'/' || _path[len - 1] == L'\\') - { - p = (wchar_t*)malloc (len * sizeof(wchar_t)); - memcpy (p, _path, (len - 1) * sizeof(wchar_t)); - p[len - 1] = L'\0'; - } - } - - return p; -} +#define __CRT__NO_INLINE +#include <sys/stat.h> int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat) { struct _stat64 st; - wchar_t *_path = _mingw_no_trailing_slash(_Name); - - int ret=_wstat64(_path,&st); - - if (_path != _Name) - free(_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + 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; @@ -79,10 +20,10 @@ int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_wstat64i32))(const wchar_t *, struct _stat64i32 *) = _wstat64i32; -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public