Discussion:
windows-stat-override: new module
(too old to reply)
Bruno Haible
2017-05-13 01:15:16 UTC
Permalink
Raw Message
This patch adds an override of 'struct stat' on native Windows platforms.

It's a separate module so that other modules can depend on it.
(Maybe a module is overkill and a .m4 file would be sufficient, but I
think it's easier to use this way.)


2017-05-13 Bruno Haible <***@clisp.org>

windows-stat-override: New module.
* lib/sys_stat.in.h (stat) [GNULIB_OVERRIDES_STRUCT_STAT]: Provide own
definition. Define GNULIB_defined_struct_stat.
(fstat, fstatat, lstat, stat) [GNULIB_OVERRIDES_STRUCT_STAT]: Provoke
link error if this symbol is used and the corresponding module is not
in use.
(_stat64, _stat32i64, _stati64, _stat32, _stat64i32): Don't redefine if
GNULIB_OVERRIDES_STRUCT_STAT.
* m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize
GNULIB_OVERRIDES_STRUCT_STAT.
* modules/sys_stat (Makefile.am): Substitute
GNULIB_OVERRIDES_STRUCT_STAT.
* modules/windows-stat-override: New file.

diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 189598d..ef689b9 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -1,4 +1,4 @@
-/* Provide a more complete sys/stat header file.
+/* Provide a more complete sys/stat.h header file.
Copyright (C) 2005-2017 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
@@ -72,6 +72,73 @@
# define stat _stati64
#endif

+/* Optionally, override 'struct stat' on native Windows. */
+#if @GNULIB_OVERRIDES_STRUCT_STAT@
+
+# undef stat
+# if @GNULIB_STAT@
+# define stat rpl_stat
+# else
+ /* Provoke a clear link error if stat() is used as a function and
+ module 'stat' is not in use. */
+# define stat stat_used_without_requesting_gnulib_module_stat
+# endif
+
+# if !GNULIB_defined_struct_stat
+struct stat
+{
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+# if 0
+ uid_t st_uid;
+# else /* uid_t is not defined by default on native Windows. */
+ short st_uid;
+# endif
+# if 0
+ gid_t st_gid;
+# else /* gid_t is not defined by default on native Windows. */
+ short st_gid;
+# endif
+ dev_t st_rdev;
+ off_t st_size;
+# if 0
+ blksize_t st_blksize;
+ blkcnt_t st_blocks;
+# endif
+
+# if 0
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+# else
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+# endif
+};
+# if 0
+# define st_atime st_atim.tv_sec
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# endif
+# define GNULIB_defined_struct_stat 1
+# endif
+
+/* Other possible values of st_mode. */
+# if 0
+# define _S_IFBLK 0x6000
+# endif
+# if 0
+# define _S_IFLNK 0xA000
+# endif
+# if 0
+# define _S_IFSOCK 0xC000
+# endif
+
+#endif
+
#ifndef S_IFIFO
# ifdef _S_IFIFO
# define S_IFIFO _S_IFIFO
@@ -345,6 +412,9 @@ _GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf));
_GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf));
# endif
_GL_CXXALIASWARN (fstat);
+#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+# undef fstat
+# define fstat fstat_used_without_requesting_gnulib_module_fstat
#elif @WINDOWS_64_BIT_ST_SIZE@
/* Above, we define stat to _stati64. */
# define fstat _fstati64
@@ -378,6 +448,9 @@ _GL_CXXALIAS_SYS (fstatat, int,
(int fd, char const *name, struct stat *st, int flags));
# endif
_GL_CXXALIASWARN (fstatat);
+#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+# undef fstatat
+# define fstatat fstatat_used_without_requesting_gnulib_module_fstatat
#elif defined GNULIB_POSIXCHECK
# undef fstatat
# if HAVE_RAW_DECL_FSTATAT
@@ -476,6 +549,9 @@ _GL_CXXALIAS_SYS (lstat, int, (const char *name, struct stat *buf));
# if @HAVE_LSTAT@
_GL_CXXALIASWARN (lstat);
# endif
+#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+# undef lstat
+# define lstat lstat_used_without_requesting_gnulib_module_lstat
#elif defined GNULIB_POSIXCHECK
# undef lstat
# if HAVE_RAW_DECL_LSTAT
@@ -625,63 +701,69 @@ _GL_WARN_ON_USE (mknodat, "mknodat is not portable - "

#if @GNULIB_STAT@
# if @REPLACE_STAT@
-/* We can't use the object-like #define stat rpl_stat, because of
- struct stat. This means that rpl_stat will not be used if the user
- does (stat)(a,b). Oh well. */
-# if defined _AIX && defined stat && defined _LARGE_FILES
- /* With _LARGE_FILES defined, AIX (only) defines stat to stat64,
- so we have to replace stat64() instead of stat(). */
-# undef stat64
-# define stat64(name, st) rpl_stat (name, st)
-# elif @WINDOWS_64_BIT_ST_SIZE@
- /* Above, we define stat to _stati64. */
-# if defined __MINGW32__ && defined _stati64
-# ifndef _USE_32BIT_TIME_T
- /* The system headers define _stati64 to _stat64. */
-# undef _stat64
-# define _stat64(name, st) rpl_stat (name, st)
+# if !@GNULIB_OVERRIDES_STRUCT_STAT@
+ /* We can't use the object-like #define stat rpl_stat, because of
+ struct stat. This means that rpl_stat will not be used if the user
+ does (stat)(a,b). Oh well. */
+# if defined _AIX && defined stat && defined _LARGE_FILES
+ /* With _LARGE_FILES defined, AIX (only) defines stat to stat64,
+ so we have to replace stat64() instead of stat(). */
+# undef stat64
+# define stat64(name, st) rpl_stat (name, st)
+# elif @WINDOWS_64_BIT_ST_SIZE@
+ /* Above, we define stat to _stati64. */
+# if defined __MINGW32__ && defined _stati64
+# ifndef _USE_32BIT_TIME_T
+ /* The system headers define _stati64 to _stat64. */
+# undef _stat64
+# define _stat64(name, st) rpl_stat (name, st)
+# endif
+# elif defined _MSC_VER && defined _stati64
+# ifdef _USE_32BIT_TIME_T
+ /* The system headers define _stati64 to _stat32i64. */
+# undef _stat32i64
+# define _stat32i64(name, st) rpl_stat (name, st)
+# else
+ /* The system headers define _stati64 to _stat64. */
+# undef _stat64
+# define _stat64(name, st) rpl_stat (name, st)
+# endif
+# else
+# undef _stati64
+# define _stati64(name, st) rpl_stat (name, st)
# endif
-# elif defined _MSC_VER && defined _stati64
+# elif defined __MINGW32__ && defined stat
# ifdef _USE_32BIT_TIME_T
- /* The system headers define _stati64 to _stat32i64. */
+ /* The system headers define stat to _stat32i64. */
# undef _stat32i64
# define _stat32i64(name, st) rpl_stat (name, st)
# else
- /* The system headers define _stati64 to _stat64. */
+ /* The system headers define stat to _stat64. */
# undef _stat64
# define _stat64(name, st) rpl_stat (name, st)
# endif
-# else
-# undef _stati64
-# define _stati64(name, st) rpl_stat (name, st)
-# endif
-# elif defined __MINGW32__ && defined stat
-# ifdef _USE_32BIT_TIME_T
- /* The system headers define stat to _stat32i64. */
-# undef _stat32i64
-# define _stat32i64(name, st) rpl_stat (name, st)
-# else
- /* The system headers define stat to _stat64. */
-# undef _stat64
-# define _stat64(name, st) rpl_stat (name, st)
-# endif
-# elif defined _MSC_VER && defined stat
-# ifdef _USE_32BIT_TIME_T
- /* The system headers define stat to _stat32. */
-# undef _stat32
-# define _stat32(name, st) rpl_stat (name, st)
-# else
- /* The system headers define stat to _stat64i32. */
-# undef _stat64i32
-# define _stat64i32(name, st) rpl_stat (name, st)
-# endif
-# else /* !(_AIX ||__MINGW32__ || _MSC_VER) */
-# undef stat
-# define stat(name, st) rpl_stat (name, st)
-# endif /* !_LARGE_FILES */
+# elif defined _MSC_VER && defined stat
+# ifdef _USE_32BIT_TIME_T
+ /* The system headers define stat to _stat32. */
+# undef _stat32
+# define _stat32(name, st) rpl_stat (name, st)
+# else
+ /* The system headers define stat to _stat64i32. */
+# undef _stat64i32
+# define _stat64i32(name, st) rpl_stat (name, st)
+# endif
+# else /* !(_AIX || __MINGW32__ || _MSC_VER) */
+# undef stat
+# define stat(name, st) rpl_stat (name, st)
+# endif /* !_LARGE_FILES */
+# endif /* !@GNULIB_OVERRIDES_STRUCT_STAT@ */
_GL_EXTERN_C int stat (const char *name, struct stat *buf)
_GL_ARG_NONNULL ((1, 2));
# endif
+#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+/* see above:
+ #define stat stat_used_without_requesting_gnulib_module_stat
+ */
#elif defined GNULIB_POSIXCHECK
# undef stat
# if HAVE_RAW_DECL_STAT
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index 1e34ac4..f0f443e 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 28 -*- Autoconf -*-
+# sys_stat_h.m4 serial 29 -*- Autoconf -*-
dnl Copyright (C) 2006-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -72,6 +72,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
GNULIB_MKNODAT=0; AC_SUBST([GNULIB_MKNODAT])
GNULIB_STAT=0; AC_SUBST([GNULIB_STAT])
GNULIB_UTIMENSAT=0; AC_SUBST([GNULIB_UTIMENSAT])
+ GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT])
HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT])
diff --git a/modules/sys_stat b/modules/sys_stat
index f8d8633..2e0aa75 100644
--- a/modules/sys_stat
+++ b/modules/sys_stat
@@ -46,6 +46,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
-e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \
-e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \
-e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \
+ -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \
-e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \
-e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \
-e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \
diff --git a/modules/windows-stat-override b/modules/windows-stat-override
new file mode 100644
index 0000000..027fa92
--- /dev/null
+++ b/modules/windows-stat-override
@@ -0,0 +1,30 @@
+Description:
+On native Windows platforms, override 'struct stat'.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the main modules in lib/.
+
+Files:
+
+Depends-on:
+sys_stat
+
+configure.ac:
+AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+AC_REQUIRE([AC_CANONICAL_HOST])
+case "$host_os" in
+ mingw*) GNULIB_OVERRIDES_STRUCT_STAT=1 ;;
+esac
+
+Makefile.am:
+
+Include:
+<sys/stat.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible

Loading...