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.
---
 mingw-w64-crt/Makefile.am                  |  4 ++-
 mingw-w64-crt/misc/ftw.c                   | 36 ++++++++++++----------
 mingw-w64-crt/misc/{ftw64.c => ftw32.c}    | 15 +++++++--
 mingw-w64-crt/misc/{ftw64.c => ftw32i64.c} |  6 ++--
 mingw-w64-crt/misc/ftw64.c                 |  6 ++--
 mingw-w64-crt/misc/{ftw64.c => ftw64i32.c} | 15 +++++++--
 6 files changed, 57 insertions(+), 25 deletions(-)
 copy mingw-w64-crt/misc/{ftw64.c => ftw32.c} (24%)
 copy mingw-w64-crt/misc/{ftw64.c => ftw32i64.c} (56%)
 copy mingw-w64-crt/misc/{ftw64.c => ftw64i32.c} (23%)

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index e231aab20c21..0a5626d031bd 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -1049,7 +1049,8 @@ src_libmingwex=\
   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 \
@@ -4293,6 +4294,7 @@ EXTRA_DIST += revstamp.h \
   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 74d05aa715eb..e87ab5e2cd91 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 @@ typedef struct ctx_t {
   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 @@ open_directory (ctx_t *ctx, dir_data_t *dirp)
 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 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, 
size_t namlen)
 
   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 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, 
size_t namlen)
        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 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, 
size_t namlen)
 
 
 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 @@ static int
 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 @@ do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void 
*fcb, int descriptors,
   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 @@ do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void 
*fcb, int descriptors,
 }
 
 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/ftw64.c b/mingw-w64-crt/misc/ftw32.c
similarity index 24%
copy from mingw-w64-crt/misc/ftw64.c
copy to mingw-w64-crt/misc/ftw32.c
index 3e45847efe53..5eb9e374ee7a 100644
--- a/mingw-w64-crt/misc/ftw64.c
+++ b/mingw-w64-crt/misc/ftw32.c
@@ -3,6 +3,17 @@
  * No warranty is given; refer to the file DISCLAIMER within this package.
  */
 
-#define IMPL_FTW64 1
-
+#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/ftw64.c b/mingw-w64-crt/misc/ftw32i64.c
similarity index 56%
copy from mingw-w64-crt/misc/ftw64.c
copy to mingw-w64-crt/misc/ftw32i64.c
index 3e45847efe53..20985fb70581 100644
--- a/mingw-w64-crt/misc/ftw64.c
+++ b/mingw-w64-crt/misc/ftw32i64.c
@@ -3,6 +3,8 @@
  * No warranty is given; refer to the file DISCLAIMER within this package.
  */
 
-#define IMPL_FTW64 1
-
+#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 3e45847efe53..5595e76c656b 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/ftw64.c b/mingw-w64-crt/misc/ftw64i32.c
similarity index 23%
copy from mingw-w64-crt/misc/ftw64.c
copy to mingw-w64-crt/misc/ftw64i32.c
index 3e45847efe53..2ded6ec4ae39 100644
--- a/mingw-w64-crt/misc/ftw64.c
+++ b/mingw-w64-crt/misc/ftw64i32.c
@@ -3,6 +3,17 @@
  * No warranty is given; refer to the file DISCLAIMER within this package.
  */
 
-#define IMPL_FTW64 1
-
+#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
-- 
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