]> Savannah Git Hosting - gnulib.git/commitdiff
mkfifoat: Work around trailing slash bug in mkfifoat() on AIX 7.2.
authorBruno Haible <bruno@clisp.org>
Tue, 5 Jan 2021 03:23:48 +0000 (04:23 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 5 Jan 2021 03:34:31 +0000 (04:34 +0100)
* 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
doc/posix-functions/mkfifoat.texi
lib/mkfifoat.c
lib/sys_stat.in.h
m4/mkfifoat.m4
m4/sys_stat_h.m4
modules/mkfifoat
modules/sys_stat

index 7ccc4e8b8c16145d97125b1a4691ed2cac99ca57..d8c44de1f1c841768e6b278e7e1d03e5cf36194a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2021-01-04  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        libc-config: Avoid overriding the headers from an installed newer glibc.
index 897233e4bc17bb381e503e846f35c4b2894a69cb..d4fcc46938e606054e69fc0d1cee8c83e95defb1 100644 (file)
@@ -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:
index 65c43b6424c0a30cd60b6896a1327f40cdeaf39f..785a1a7617660c322cc47bb2c6dec1b23ba952d6 100644 (file)
 
 #include <stdlib.h>
 
-#if !HAVE_MKFIFO
+#if HAVE_MKFIFOAT
 
 # include <errno.h>
+# include <fcntl.h>
+# include <string.h>
+
+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 <errno.h>
 
 /* 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 */
index 8ad0c23a31f49c4b000fac543feb1416b3ca8648..936f2e458c7c6d14f1ca2a129279b62b9e9b3694 100644 (file)
@@ -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
index f6d5a327f60f247cd5e7e539afa8c8741d76b343..c4491adf75dedf6f41e489ee80a9802ddb98ee95 100644 (file)
@@ -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 <sys/stat.h> 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 <fcntl.h>
+              #include <sys/stat.h>
+            ]],
+            [[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
index e8eac71b466d7fe70c19bd90399ce4d75244be26..7852075838fb73dde72a44bd61a70ced075f9a28 100644 (file)
@@ -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])
index 6c859f342859813f2db9b52e1c98f3550c228abb..f91d64c339826587bb5cf03780a7b55ef115a786 100644 (file)
@@ -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
index 8a9adb5813f81e1330cd9106dd7700547d6bd654..3da1272c5e4bdd688621d16ad3db7fb5374cad77 100644 (file)
@@ -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' \