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 | 27 +++++++---
mingw-w64-crt/stdio/_stat64i32.c | 88 +++++++------------------------
mingw-w64-crt/stdio/_wstat64i32.c | 88 +++++++------------------------
4 files changed, 66 insertions(+), 147 deletions(-)
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 6987e6a93873..2b5c6e83d83d 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -548,9 +548,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
@@ -632,6 +634,8 @@ src_msvcrtarm32=\
misc/__winitenv.c \
stdio/_fstat64i32.c \
stdio/_setmaxstdio.c \
+ stdio/_stat64i32.c \
+ stdio/_wstat64i32.c \
stdio/gets.c
if !ENABLE_SOFTMATH
@@ -842,6 +846,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
@@ -1041,8 +1047,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 7e71f2e80005..cc72b3814ba9 100644
--- a/mingw-w64-crt/stdio/_fstat64i32.c
+++ b/mingw-w64-crt/stdio/_fstat64i32.c
@@ -1,14 +1,27 @@
+/**
+ * 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>
+/* When the file size does not fit into the st_size field:
+ * crtdll-msvcr90 msvcr100 msvcr110+
+ * st_size truncate 0 0
+ * errno no change no change EOVERFLOW
+ * returns 0 -1 -1
+ *
+ * This file is used only for pre-msvcr80 builds,
+ * So use the pre-msvcr80 behavior - truncate without error.
+ */
int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat)
{
struct _stat64 st;
int ret=_fstat64(_FileDes,&st);
- if (ret == -1) {
- *_Stat = (struct _stat64i32){0};
- 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 +29,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 e288470ea052..47aa080800e3 100644
--- a/mingw-w64-crt/stdio/_stat64i32.c
+++ b/mingw-w64-crt/stdio/_stat64i32.c
@@ -1,77 +1,27 @@
+/**
+ * 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 <stdlib.h>
-/**
- * Returns _path without trailing slash if any
+/* When the file size does not fit into the st_size field:
+ * crtdll-msvcr90 msvcr100 msvcr110+
+ * st_size truncate 0 0
+ * errno no change no change EOVERFLOW
+ * returns 0 -1 -1
*
- * - 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 is used only for pre-msvcr80 builds,
+ * So use the pre-msvcr80 behavior - truncate without error.
*/
-
-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;
-}
-
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) {
- *_Stat = (struct _stat64i32){0};
- 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 +29,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 b17c50574f78..a48a5101359f 100644
--- a/mingw-w64-crt/stdio/_wstat64i32.c
+++ b/mingw-w64-crt/stdio/_wstat64i32.c
@@ -1,77 +1,27 @@
+/**
+ * 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 <stdlib.h>
-/**
- * Returns _path without trailing slash if any
+/* When the file size does not fit into the st_size field:
+ * crtdll-msvcr90 msvcr100 msvcr110+
+ * st_size truncate 0 0
+ * errno no change no change EOVERFLOW
+ * returns 0 -1 -1
*
- * - 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 is used only for pre-msvcr80 builds,
+ * So use the pre-msvcr80 behavior - truncate without error.
*/
-
-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;
-}
-
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) {
- *_Stat = (struct _stat64i32){0};
- 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 +29,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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public