crt: Fix ABI of POSIX ftw() and nftw() functions
There are 4 POSIX stat functions (stat32, stat32i64, stat64, stat64i32)
which differs in the stat structure point size. And there is additional
stat symbol which alias to one of those based on the _FILE_OFFSET_BITS and
_USE_32BIT_TIME_T settings.
As POSIX ftw() and nftw() functions takes also struct stat in its function
callback argument, it is required to properly provide for each settings of
_FILE_OFFSET_BITS and _USE_32BIT_TIME_T configuration, the appropriate
struct stat ABI compatible ftw and nftw symbol.
This change provides 4 new ftw function symbols: ftw32, ftw32i64, ftw64 and
ftw64i32. And same for nftw symbols: nftw32, nftw32i64, nftw64, nftw64i32.
So with this change, the call to the ftw() or nftw() function will respect
the _FILE_OFFSET_BITS and _USE_32BIT_TIME_T settings and provide correct
size of stat structure.
Function symbols for ftw and nftw are aliases to one of the fixed-size
symbol based on the _FILE_OFFSET_BITS and _USE_32BIT_TIME_T settings.
Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index a049274..195251a 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -1063,7 +1063,8 @@
misc/wcstold.c \
misc/wdirent.c misc/winbs_uint64.c misc/winbs_ulong.c misc/winbs_ushort.c \
misc/wmemchr.c misc/wmemcmp.c misc/wmemcpy.c misc/wmemmove.c misc/wmempcpy.c \
- misc/wmemset.c misc/ftw.c misc/ftw64.c misc/mingw-access.c \
+ misc/wmemset.c misc/mingw-access.c \
+ misc/ftw32.c misc/ftw32i64.c misc/ftw64.c misc/ftw64i32.c \
\
ssp/chk_fail.c ssp/gets_chk.c ssp/memcpy_chk.c ssp/memmove_chk.c \
ssp/mempcpy_chk.c \
@@ -4314,6 +4315,7 @@
crt/CRT_noglob.c \
crt/txtmode.c \
crt/ucrtexe.c \
+ misc/ftw.c \
profile/gcrt0.c \
profile/COPYING \
profile/CYGWIN_LICENSE \
diff --git a/mingw-w64-crt/misc/ftw.c b/mingw-w64-crt/misc/ftw.c
index 74d05aa..e87ab5e 100644
--- a/mingw-w64-crt/misc/ftw.c
+++ b/mingw-w64-crt/misc/ftw.c
@@ -15,11 +15,11 @@
#include <dirent.h>
#include <ftw.h>
-#ifdef IMPL_FTW64
-#define stat stat64
-#define nftw nftw64
-#define ftw ftw64
-#endif
+#undef stat64
+int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat);
+int __cdecl stat32i64(const char *_Filename, struct _stat32i64 *_Stat);
+int __cdecl stat64(const char *_Filename, struct _stat64 *_Stat);
+int __cdecl stat64i32(const char *_Filename, struct _stat64i32 *_Stat);
typedef struct dir_data_t {
DIR *h;
@@ -36,14 +36,14 @@
dir_data_t **dirs;
char *buf;
struct FTW ftw;
- int (*fcb) (const char *, const struct stat *, int , struct FTW *);
+ int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *);
size_t cur_dir, msz_dir, buf_sz;
int flags;
dev_t dev;
} ctx_t;
static int add_object (ctx_t *);
-static int do_dir (ctx_t *, struct stat *, dir_data_t *);
+static int do_dir (ctx_t *, STRUCT_STAT *, dir_data_t *);
static int do_entity (ctx_t *, dir_data_t *, const char *, size_t);
static int do_it (const char *, int, void *, int, int);
@@ -225,7 +225,7 @@
static int
do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen)
{
- struct stat st;
+ STRUCT_STAT st;
char *h;
size_t cnt_sz;
int ret = 0, flag = 0;
@@ -249,7 +249,7 @@
name = ctx->buf;
- if (stat (name, &st) < 0)
+ if (FUNC_STAT (name, &st) < 0)
{
if (errno != EACCES && errno != ENOENT)
ret = -1;
@@ -257,7 +257,7 @@
flag = FTW_NS;
if (!(ctx->flags & FTW_PHYS))
- stat (name, &st);
+ FUNC_STAT (name, &st);
}
else
flag = (S_ISDIR (st.st_mode) ? FTW_D : FTW_F);
@@ -281,7 +281,7 @@
static int
-do_dir (ctx_t *ctx, struct stat *st, __UNUSED_PARAM(dir_data_t *old_dir))
+do_dir (ctx_t *ctx, STRUCT_STAT *st, __UNUSED_PARAM(dir_data_t *old_dir))
{
dir_data_t dir;
struct dirent *d;
@@ -378,7 +378,7 @@
do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void *fcb, int descriptors, int flags)
{
struct ctx_t ctx;
- struct stat st;
+ STRUCT_STAT st;
int ret = 0;
int sv_e;
char *cp;
@@ -417,12 +417,12 @@
ctx.ftw.level = 0;
ctx.ftw.base = cp - ctx.buf;
ctx.flags = flags;
- ctx.fcb = (int (*) (const char *, const struct stat *, int , struct FTW *)) fcb;
+ ctx.fcb = (int (*) (const char *, const STRUCT_STAT *, int , struct FTW *)) fcb;
ctx.objs = NULL;
if (!ret)
{
- if (stat (ctx.buf, &st) < 0)
+ if (FUNC_STAT (ctx.buf, &st) < 0)
ret = -1;
else if (S_ISDIR (st.st_mode))
{
@@ -451,13 +451,17 @@
}
int
-ftw (const char *path, int (*fcb) (const char *, const struct stat *, int), int descriptors)
+FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors);
+int
+FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors)
{
return do_it (path, 0, fcb, descriptors, 0);
}
int
-nftw (const char *path, int (*fcb) (const char *, const struct stat *, int , struct FTW *), int descriptors, int flags)
+FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags);
+int
+FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags)
{
return do_it (path, 1, fcb, descriptors, flags);
}
diff --git a/mingw-w64-crt/misc/ftw32.c b/mingw-w64-crt/misc/ftw32.c
new file mode 100644
index 0000000..5eb9e37
--- /dev/null
+++ b/mingw-w64-crt/misc/ftw32.c
@@ -0,0 +1,19 @@
+/**
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#define FUNC_FTW ftw32
+#define FUNC_NFTW nftw32
+#define FUNC_STAT stat32
+#define STRUCT_STAT struct _stat32
+#include "ftw.c"
+
+/* On 32-bit systems is stat ABI compatible with stat32 */
+#ifndef _WIN64
+#undef nftw
+#undef ftw
+struct stat;
+int __attribute__ ((alias ("nftw32"))) __cdecl nftw(const char *, int (*) (const char *, const struct stat *, int, struct FTW *), int, int);
+int __attribute__ ((alias ("ftw32"))) __cdecl ftw(const char *, int (*) (const char *, const struct stat *, int), int);
+#endif
diff --git a/mingw-w64-crt/misc/ftw32i64.c b/mingw-w64-crt/misc/ftw32i64.c
new file mode 100644
index 0000000..20985fb
--- /dev/null
+++ b/mingw-w64-crt/misc/ftw32i64.c
@@ -0,0 +1,10 @@
+/**
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#define FUNC_FTW ftw32i64
+#define FUNC_NFTW nftw32i64
+#define FUNC_STAT stat32i64
+#define STRUCT_STAT struct _stat32i64
+#include "ftw.c"
diff --git a/mingw-w64-crt/misc/ftw64.c b/mingw-w64-crt/misc/ftw64.c
index 3e45847..5595e76 100644
--- a/mingw-w64-crt/misc/ftw64.c
+++ b/mingw-w64-crt/misc/ftw64.c
@@ -3,6 +3,8 @@
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
-#define IMPL_FTW64 1
-
+#define FUNC_FTW ftw64
+#define FUNC_NFTW nftw64
+#define FUNC_STAT stat64
+#define STRUCT_STAT struct _stat64
#include "ftw.c"
diff --git a/mingw-w64-crt/misc/ftw64i32.c b/mingw-w64-crt/misc/ftw64i32.c
new file mode 100644
index 0000000..2ded6ec
--- /dev/null
+++ b/mingw-w64-crt/misc/ftw64i32.c
@@ -0,0 +1,19 @@
+/**
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#define FUNC_FTW ftw64i32
+#define FUNC_NFTW nftw64i32
+#define FUNC_STAT stat64i32
+#define STRUCT_STAT struct _stat64i32
+#include "ftw.c"
+
+/* On 64-bit systems is stat ABI compatible with stat64i32 */
+#ifdef _WIN64
+#undef nftw
+#undef ftw
+struct stat;
+int __attribute__ ((alias ("nftw64i32"))) __cdecl nftw(const char *, int (*) (const char *, const struct stat *, int, struct FTW *), int, int);
+int __attribute__ ((alias ("ftw64i32"))) __cdecl ftw(const char *, int (*) (const char *, const struct stat *, int), int);
+#endif