From 2debee31183d819dab80fb68ead29ea34143e873 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 25 Dec 2020 18:39:47 +0100 Subject: [PATCH] Make it possible to turn off the mkdir override on Windows. * lib/sys_stat.in.h (mkdir): Conditionalize through GNULIB_MKDIR and GNULIB_MDA_MKDIR. Also support GNULIB_POSIXCHECK. * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize GNULIB_MKDIR, GNULIB_MDA_MKDIR. * modules/sys_stat (Makefile.am): Substitute GNULIB_MKDIR, GNULIB_MDA_MKDIR. * modules/mkdir (configure.ac): Invoke gl_SYS_STAT_MODULE_INDICATOR. * doc/posix-functions/mkdir.texi: Mention also the 'sys_stat' module. --- ChangeLog | 10 +++++++++ doc/posix-functions/mkdir.texi | 20 ++++++++++------- lib/sys_stat.in.h | 49 ++++++++++++++++++++++++++++++++---------- m4/sys_stat_h.m4 | 4 +++- modules/mkdir | 1 + modules/sys_stat | 2 ++ 6 files changed, 66 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0322e09981..1b19c121e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2020-12-25 Bruno Haible + Make it possible to turn off the mkdir override on Windows. + * lib/sys_stat.in.h (mkdir): Conditionalize through GNULIB_MKDIR and + GNULIB_MDA_MKDIR. Also support GNULIB_POSIXCHECK. + * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize GNULIB_MKDIR, + GNULIB_MDA_MKDIR. + * modules/sys_stat (Makefile.am): Substitute GNULIB_MKDIR, + GNULIB_MDA_MKDIR. + * modules/mkdir (configure.ac): Invoke gl_SYS_STAT_MODULE_INDICATOR. + * doc/posix-functions/mkdir.texi: Mention also the 'sys_stat' module. + Make it possible to turn off each of the Windows oldnames workarounds. * lib/fcntl.in.h (creat, open): Conditionalize each of the Windows oldnames workarounds through a GNULIB_MDA_ symbol. diff --git a/doc/posix-functions/mkdir.texi b/doc/posix-functions/mkdir.texi index 141d35d289..1162947fac 100644 --- a/doc/posix-functions/mkdir.texi +++ b/doc/posix-functions/mkdir.texi @@ -4,21 +4,15 @@ POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html} -Gnulib module: mkdir +Gnulib module: sys_stat or mkdir -Portability problems fixed by Gnulib: +Portability problems fixed by either Gnulib module @code{sys_stat} or @code{mkdir}: @itemize @item This function is declared in different header files (namely, @code{} or @code{}) on some platforms: mingw, MSVC 14. @item -When the argument ends in a slash, the function call fails on some platforms. -@item -This function mistakenly succeeds on @samp{mkdir("d/./",mode)} on -some platforms: -Cygwin 1.5.x, mingw, MSVC 14. -@item On Windows platforms (excluding Cygwin), this function is called @code{_mkdir} and takes only one argument. The fix (without Gnulib) is to define a macro like this: @@ -31,6 +25,16 @@ or @end smallexample @end itemize +Portability problems fixed by Gnulib module @code{mkdir}: +@itemize +@item +When the argument ends in a slash, the function call fails on some platforms. +@item +This function mistakenly succeeds on @samp{mkdir("d/./",mode)} on +some platforms: +Cygwin 1.5.x, mingw, MSVC 14. +@end itemize + Portability problems not fixed by Gnulib: @itemize @end itemize diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index 4b4ec65a63..faca52272a 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -608,21 +608,20 @@ _GL_WARN_ON_USE (lstat, "lstat is unportable - " #endif -#if @REPLACE_MKDIR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mkdir -# define mkdir rpl_mkdir -# endif +#if @GNULIB_MKDIR@ +# if @REPLACE_MKDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif _GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode) - _GL_ARG_NONNULL ((1))); + _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); -#else +# elif defined _WIN32 && !defined __CYGWIN__ /* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. Additionally, it declares _mkdir (and depending on compile flags, an alias mkdir), only in the nonstandard includes and , which are included above. */ -# if defined _WIN32 && ! defined __CYGWIN__ - # if !GNULIB_defined_rpl_mkdir static int rpl_mkdir (char const *name, mode_t mode) @@ -631,16 +630,44 @@ rpl_mkdir (char const *name, mode_t mode) } # define GNULIB_defined_rpl_mkdir 1 # endif - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir # define mkdir rpl_mkdir # endif _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); # else _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); # endif -#endif _GL_CXXALIASWARN (mkdir); +#elif defined GNULIB_POSIXCHECK +# undef mkdir +# if HAVE_RAW_DECL_MKDIR +_GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - " + "use gnulib module mkdir for portability"); +# endif +#elif @GNULIB_MDA_MKDIR@ +/* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::mkdir always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !GNULIB_defined_rpl_mkdir +static int +rpl_mkdir (char const *name, mode_t mode) +{ + return _mkdir (name); +} +# define GNULIB_defined_rpl_mkdir 1 +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif +_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); +# else +_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkdir); +#endif #if @GNULIB_MKDIRAT@ diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index a1cb988707..14b72db3f8 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 35 -*- Autoconf -*- +# sys_stat_h.m4 serial 36 -*- Autoconf -*- dnl Copyright (C) 2006-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -71,6 +71,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK]) GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD]) GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT]) + GNULIB_MKDIR=0; AC_SUBST([GNULIB_MKDIR]) GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT]) GNULIB_MKFIFO=0; AC_SUBST([GNULIB_MKFIFO]) GNULIB_MKFIFOAT=0; AC_SUBST([GNULIB_MKFIFOAT]) @@ -81,6 +82,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT]) dnl Support Microsoft deprecated alias function names by default. GNULIB_MDA_CHMOD=1; AC_SUBST([GNULIB_MDA_CHMOD]) + GNULIB_MDA_MKDIR=1; AC_SUBST([GNULIB_MDA_MKDIR]) GNULIB_MDA_UMASK=1; AC_SUBST([GNULIB_MDA_UMASK]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT]) diff --git a/modules/mkdir b/modules/mkdir index 2f1850c61b..fb24458a9a 100644 --- a/modules/mkdir +++ b/modules/mkdir @@ -15,6 +15,7 @@ gl_FUNC_MKDIR if test $REPLACE_MKDIR = 1; then AC_LIBOBJ([mkdir]) fi +gl_SYS_STAT_MODULE_INDICATOR([mkdir]) Makefile.am: diff --git a/modules/sys_stat b/modules/sys_stat index 6bf6b2998d..8a9adb5813 100644 --- a/modules/sys_stat +++ b/modules/sys_stat @@ -42,6 +42,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \ -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIR''@/$(GNULIB_MKDIR)/g' \ -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ @@ -51,6 +52,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \ -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \ -e 's/@''GNULIB_MDA_CHMOD''@/$(GNULIB_MDA_CHMOD)/g' \ + -e 's/@''GNULIB_MDA_MKDIR''@/$(GNULIB_MDA_MKDIR)/g' \ -e 's/@''GNULIB_MDA_UMASK''@/$(GNULIB_MDA_UMASK)/g' \ -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ -- 2.11.4.GIT