>From 5e6fdcd601b83417a3f29c27fa0eb4ead053e1ea Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 5 Jan 2021 04:23:48 +0100 Subject: [PATCH 1/2] mkfifoat: Work around trailing slash bug in mkfifoat() on AIX 7.2. * m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Add a test whether mkfifoat rejects trailing slashes. Set REPLACE_MKFIFOAT if not. * lib/sys_stat.in.h (mkfifoat): Consider REPLACE_MKFIFOAT. * lib/mkfifoat.c: Add an overriding implementation of mkfifoat(). * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize REPLACE_MKFIFOAT. * modules/sys_stat (Makefile.am): Substitute REPLACE_MKFIFOAT. * modules/mkfifoat (Depends-on): Add fstatat. (configure.ac): Consider REPLACE_MKFIFOAT. * doc/posix-functions/mkfifoat.texi: Mention the AIX bug. --- ChangeLog | 14 +++++++++ doc/posix-functions/mkfifoat.texi | 4 +++ lib/mkfifoat.c | 64 +++++++++++++++++++++++++++++++-------- lib/sys_stat.in.h | 14 +++++++-- m4/mkfifoat.m4 | 46 ++++++++++++++++++++++++++-- m4/sys_stat_h.m4 | 3 +- modules/mkfifoat | 3 +- modules/sys_stat | 1 + 8 files changed, 129 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ccc4e8..d8c44de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2021-01-04 Bruno Haible + mkfifoat: Work around trailing slash bug in mkfifoat() on AIX 7.2. + * m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Add a test whether mkfifoat rejects + trailing slashes. Set REPLACE_MKFIFOAT if not. + * lib/sys_stat.in.h (mkfifoat): Consider REPLACE_MKFIFOAT. + * lib/mkfifoat.c: Add an overriding implementation of mkfifoat(). + * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize + REPLACE_MKFIFOAT. + * modules/sys_stat (Makefile.am): Substitute REPLACE_MKFIFOAT. + * modules/mkfifoat (Depends-on): Add fstatat. + (configure.ac): Consider REPLACE_MKFIFOAT. + * doc/posix-functions/mkfifoat.texi: Mention the AIX bug. + +2021-01-04 Bruno Haible + libc-config: Avoid overriding the headers from an installed newer glibc. Reported by Paul E Murphy in . diff --git a/doc/posix-functions/mkfifoat.texi b/doc/posix-functions/mkfifoat.texi index 897233e..d4fcc46 100644 --- a/doc/posix-functions/mkfifoat.texi +++ b/doc/posix-functions/mkfifoat.texi @@ -12,6 +12,10 @@ Portability problems fixed by Gnulib: This function is missing on some platforms: glibc 2.3.6, Mac OS X 10.13, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, Cygwin 1.5.x, mingw, MSVC 14, Android 5.1. But the replacement function is not safe to be used in libraries and is not multithread-safe. +@item +This function does not fail when the file name argument ends in a slash +and (without the slash) names a nonexistent file, on some platforms: +AIX 7.2. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/mkfifoat.c b/lib/mkfifoat.c index 65c43b6..785a1a7 100644 --- a/lib/mkfifoat.c +++ b/lib/mkfifoat.c @@ -23,9 +23,45 @@ #include -#if !HAVE_MKFIFO +#if HAVE_MKFIFOAT # include +# include +# include + +int +rpl_mkfifoat (int fd, char const *file, mode_t mode) +#undef mkfifoat +{ + /* Use the original mkfifoat(), but correct the trailing slash handling. */ + size_t len = strlen (file); + if (len && file[len - 1] == '/') + { + struct stat st; + + if (fstatat (fd, file, &st, AT_SYMLINK_NOFOLLOW) < 0) + { + if (errno == EOVERFLOW) + /* It's surely a file, not a directory. */ + errno = ENOTDIR; + } + else + { + /* It's a directory, otherwise fstatat() would have reported an error + ENOTDIR. */ + errno = EEXIST; + } + return -1; + } + + return mkfifoat (fd, file, mode); +} + +#else + +# if !HAVE_MKFIFO + +# include /* Mingw lacks mkfifo, so this wrapper is trivial. */ @@ -37,7 +73,7 @@ mkfifoat (int fd _GL_UNUSED, char const *path _GL_UNUSED, return -1; } -#else /* HAVE_MKFIFO */ +# else /* HAVE_MKFIFO */ /* Create a named fifo FILE relative to directory FD, with access permissions in MODE. If possible, do it without changing the @@ -45,14 +81,16 @@ mkfifoat (int fd _GL_UNUSED, char const *path _GL_UNUSED, then mkfifo/restore_cwd. If either the save_cwd or the restore_cwd fails, then give a diagnostic and exit nonzero. */ -# define AT_FUNC_NAME mkfifoat -# define AT_FUNC_F1 mkfifo -# define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode -# define AT_FUNC_POST_FILE_ARGS , mode -# include "at-func.c" -# undef AT_FUNC_NAME -# undef AT_FUNC_F1 -# undef AT_FUNC_POST_FILE_PARAM_DECLS -# undef AT_FUNC_POST_FILE_ARGS - -#endif /* HAVE_MKFIFO */ +# define AT_FUNC_NAME mkfifoat +# define AT_FUNC_F1 mkfifo +# define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode +# define AT_FUNC_POST_FILE_ARGS , mode +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +# endif /* HAVE_MKFIFO */ + +#endif /* HAVE_MKFIFOAT */ diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index 8ad0c23..936f2e4 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -713,11 +713,21 @@ _GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - " #if @GNULIB_MKFIFOAT@ -# if !@HAVE_MKFIFOAT@ +# if @REPLACE_MKFIFOAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkfifoat +# define mkfifoat rpl_mkfifoat +# endif +_GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)); +# else +# if !@HAVE_MKFIFOAT@ _GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); +# endif _GL_CXXALIASWARN (mkfifoat); #elif defined GNULIB_POSIXCHECK # undef mkfifoat diff --git a/m4/mkfifoat.m4 b/m4/mkfifoat.m4 index f6d5a32..c4491ad 100644 --- a/m4/mkfifoat.m4 +++ b/m4/mkfifoat.m4 @@ -1,4 +1,4 @@ -# serial 3 +# serial 4 # See if we need to provide mkfifoat/mknodat replacement. dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -11,10 +11,50 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_MKFIFOAT], [ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) - AC_REQUIRE([gl_FUNC_OPENAT]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Persuade glibc to declare mkfifoat() and mknodat(). AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_FUNC_OPENAT]) + AC_CHECK_FUNCS_ONCE([mkfifoat mknodat]) - if test $ac_cv_func_mkfifoat = no; then + if test $ac_cv_func_mkfifoat = yes; then + dnl Check for AIX 7.2 bug with trailing slash. + AC_CACHE_CHECK([whether mkfifoat rejects trailing slashes], + [gl_cv_func_mkfifoat_works], + [rm -f conftest.tmp + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + ]], + [[int result = 0; + if (!mkfifoat (AT_FDCWD, "conftest.tmp/", 0600)) + result |= 1; + return result; + ]]) + ], + [gl_cv_func_mkfifoat_works=yes], + [gl_cv_func_mkfifoat_works=no], + [case "$host_os" in + # Guess yes on Linux systems. + linux-* | linux) gl_cv_func_mknod_works="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_mknod_works="guessing yes" ;; + # Guess no on AIX systems. + aix*) gl_cv_func_mknod_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_mknod_works="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.tmp + ]) + case "$gl_cv_func_mkfifoat_works" in + *yes) ;; + *) REPLACE_MKFIFOAT=1 ;; + esac + else # No known system has mkfifoat but not mknodat HAVE_MKFIFOAT=0 HAVE_MKNODAT=0 diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index e8eac71..7852075 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 36 -*- Autoconf -*- +# sys_stat_h.m4 serial 37 -*- Autoconf -*- dnl Copyright (C) 2006-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -104,6 +104,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], REPLACE_LSTAT=0; AC_SUBST([REPLACE_LSTAT]) REPLACE_MKDIR=0; AC_SUBST([REPLACE_MKDIR]) REPLACE_MKFIFO=0; AC_SUBST([REPLACE_MKFIFO]) + REPLACE_MKFIFOAT=0; AC_SUBST([REPLACE_MKFIFOAT]) REPLACE_MKNOD=0; AC_SUBST([REPLACE_MKNOD]) REPLACE_STAT=0; AC_SUBST([REPLACE_STAT]) REPLACE_UTIMENSAT=0; AC_SUBST([REPLACE_UTIMENSAT]) diff --git a/modules/mkfifoat b/modules/mkfifoat index 6c859f3..f91d64c 100644 --- a/modules/mkfifoat +++ b/modules/mkfifoat @@ -11,6 +11,7 @@ m4/mkfifoat.m4 Depends-on: sys_stat extensions +fstatat [test $REPLACE_MKFIFOAT = 1] at-internal [test $HAVE_MKFIFOAT = 0 || test $HAVE_MKNODAT = 0] errno [test $HAVE_MKFIFOAT = 0 || test $HAVE_MKNODAT = 0] fchdir [test $HAVE_MKFIFOAT = 0 || test $HAVE_MKNODAT = 0] @@ -24,7 +25,7 @@ mknod [test $HAVE_MKNODAT = 0] configure.ac: gl_FUNC_MKFIFOAT -if test $HAVE_MKFIFOAT = 0; then +if test $HAVE_MKFIFOAT = 0 || test $REPLACE_MKFIFOAT = 1; then AC_LIBOBJ([mkfifoat]) fi if test $HAVE_MKNODAT = 0; then diff --git a/modules/sys_stat b/modules/sys_stat index 8a9adb5..3da1272 100644 --- a/modules/sys_stat +++ b/modules/sys_stat @@ -73,6 +73,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \ -e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \ -e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \ + -e 's|@''REPLACE_MKFIFOAT''@|$(REPLACE_MKFIFOAT)|g' \ -e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \ -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \ -e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \ -- 2.7.4