]> Savannah Git Hosting - gnulib.git/commitdiff
mkfifoat: Work around trailing slash bug in mknodat() on AIX 7.2.
authorBruno Haible <bruno@clisp.org>
Tue, 5 Jan 2021 03:48:20 +0000 (04:48 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 5 Jan 2021 03:48:20 +0000 (04:48 +0100)
* m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Set also REPLACE_MKNODAT.
* lib/sys_stat.in.h (mknodat): Consider REPLACE_MKNODAT.
* lib/mknodat.c: Add an overriding implementation of mknodat().
* m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize REPLACE_MKNODAT.
* modules/sys_stat (Makefile.am): Substitute REPLACE_MKNODAT.
* modules/mkfifoat (Depends-on, configure.ac): Consider REPLACE_MKNODAT.
* doc/posix-functions/mknodat.texi: Mention the AIX bug.

ChangeLog
doc/posix-functions/mknodat.texi
lib/mknodat.c
lib/sys_stat.in.h
m4/mkfifoat.m4
m4/sys_stat_h.m4
modules/mkfifoat
modules/sys_stat

index d8c44de1f1c841768e6b278e7e1d03e5cf36194a..a579efc9b95a2b52d82a3f10caa5f363ab128556 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2021-01-04  Bruno Haible  <bruno@clisp.org>
 
+       mkfifoat: Work around trailing slash bug in mknodat() on AIX 7.2.
+       * m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Set also REPLACE_MKNODAT.
+       * lib/sys_stat.in.h (mknodat): Consider REPLACE_MKNODAT.
+       * lib/mknodat.c: Add an overriding implementation of mknodat().
+       * m4/sys_stat_h.m4 (gl_SYS_STAT_H_DEFAULTS): Initialize REPLACE_MKNODAT.
+       * modules/sys_stat (Makefile.am): Substitute REPLACE_MKNODAT.
+       * modules/mkfifoat (Depends-on, configure.ac): Consider REPLACE_MKNODAT.
+       * doc/posix-functions/mknodat.texi: Mention the AIX bug.
+
        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.
index c98c64829cfcb870a78e9530e3d97143d65d2f69..0658ed3aa75153dd07bffe48fe4ae47312ed66f9 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 4.4.
 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 68ece601b8b8840833153de187e6198282ead0c2..6d0f6773a604435e38dc27bf9615a2450c849e34 100644 (file)
 
 #include <stdlib.h>
 
-#if !HAVE_MKNOD
+#if HAVE_MKNODAT
 
 # include <errno.h>
+# include <fcntl.h>
+# include <string.h>
+
+int
+rpl_mknodat (int fd, char const *file, mode_t mode, dev_t dev)
+#undef mknodat
+{
+  /* Use the original mknodat(), 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 mknodat (fd, file, mode, dev);
+}
+
+#else
+
+# if !HAVE_MKNOD
+
+#  include <errno.h>
 
 /* Mingw lacks mknod, so this wrapper is trivial.  */
 
@@ -37,7 +73,7 @@ mknodat (int fd _GL_UNUSED, char const *path _GL_UNUSED,
   return -1;
 }
 
-#else
+# else
 
 /* Create a file system node FILE relative to directory FD, with
    access permissions and file type in MODE, and device type in DEV.
@@ -47,14 +83,16 @@ mknodat (int fd _GL_UNUSED, char const *path _GL_UNUSED,
    then mknod/restore_cwd.  If either the save_cwd or the restore_cwd
    fails, then give a diagnostic and exit nonzero.  */
 
-# define AT_FUNC_NAME mknodat
-# define AT_FUNC_F1 mknod
-# define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, dev_t dev
-# define AT_FUNC_POST_FILE_ARGS        , mode, dev
-# 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
+#  define AT_FUNC_NAME mknodat
+#  define AT_FUNC_F1 mknod
+#  define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, dev_t dev
+#  define AT_FUNC_POST_FILE_ARGS        , mode, dev
+#  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
 
 #endif
index 936f2e458c7c6d14f1ca2a129279b62b9e9b3694..283ed5514874bc8d377d9c4cad3a66671688fce9 100644 (file)
@@ -766,13 +766,25 @@ _GL_WARN_ON_USE (mknod, "mknod is not portable - "
 
 
 #if @GNULIB_MKNODAT@
-# if !@HAVE_MKNODAT@
+# if @REPLACE_MKNODAT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mknodat
+#   define mknodat rpl_mknodat
+#  endif
+_GL_FUNCDECL_RPL (mknodat, int,
+                  (int fd, char const *file, mode_t mode, dev_t dev)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (mknodat, int,
+                  (int fd, char const *file, mode_t mode, dev_t dev));
+# else
+#  if !@HAVE_MKNODAT@
 _GL_FUNCDECL_SYS (mknodat, int,
                   (int fd, char const *file, mode_t mode, dev_t dev)
                   _GL_ARG_NONNULL ((2)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (mknodat, int,
                   (int fd, char const *file, mode_t mode, dev_t dev));
+# endif
 _GL_CXXALIASWARN (mknodat);
 #elif defined GNULIB_POSIXCHECK
 # undef mknodat
index c4491adf75dedf6f41e489ee80a9802ddb98ee95..4daf4d8146fd95340366c5b5a352e695b3aad387 100644 (file)
@@ -1,4 +1,4 @@
-# serial 4
+# serial 5
 # See if we need to provide mkfifoat/mknodat replacement.
 
 dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
@@ -52,7 +52,11 @@ AC_DEFUN([gl_FUNC_MKFIFOAT],
       ])
     case "$gl_cv_func_mkfifoat_works" in
       *yes) ;;
-      *) REPLACE_MKFIFOAT=1 ;;
+      *)
+        REPLACE_MKFIFOAT=1
+        dnl mknodat() has the same bug as mkfifoat().
+        REPLACE_MKNODAT=1
+        ;;
     esac
   else
     # No known system has mkfifoat but not mknodat
index 7852075838fb73dde72a44bd61a70ced075f9a28..23cbdd28eb2f740fe514f477e670c66d0cb5e354 100644 (file)
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 37   -*- Autoconf -*-
+# sys_stat_h.m4 serial 38   -*- 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,
@@ -106,6 +106,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
   REPLACE_MKFIFO=0;     AC_SUBST([REPLACE_MKFIFO])
   REPLACE_MKFIFOAT=0;   AC_SUBST([REPLACE_MKFIFOAT])
   REPLACE_MKNOD=0;      AC_SUBST([REPLACE_MKNOD])
+  REPLACE_MKNODAT=0;    AC_SUBST([REPLACE_MKNODAT])
   REPLACE_STAT=0;       AC_SUBST([REPLACE_STAT])
   REPLACE_UTIMENSAT=0;  AC_SUBST([REPLACE_UTIMENSAT])
 ])
index f91d64c339826587bb5cf03780a7b55ef115a786..b78efd3d107c3537b27fe0c9a2770534d4091029 100644 (file)
@@ -11,7 +11,7 @@ m4/mkfifoat.m4
 Depends-on:
 sys_stat
 extensions
-fstatat         [test $REPLACE_MKFIFOAT = 1]
+fstatat         [test $REPLACE_MKFIFOAT = 1 || test $REPLACE_MKNODAT = 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]
@@ -28,7 +28,7 @@ gl_FUNC_MKFIFOAT
 if test $HAVE_MKFIFOAT = 0 || test $REPLACE_MKFIFOAT = 1; then
   AC_LIBOBJ([mkfifoat])
 fi
-if test $HAVE_MKNODAT = 0; then
+if test $HAVE_MKNODAT = 0 || test $REPLACE_MKNODAT = 1; then
   AC_LIBOBJ([mknodat])
 fi
 gl_SYS_STAT_MODULE_INDICATOR([mkfifoat])
index 3da1272c5e4bdd688621d16ad3db7fb5374cad77..26971975e4e0fbdd97a24ee23fa8b134ac706241 100644 (file)
@@ -75,6 +75,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
              -e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \
              -e 's|@''REPLACE_MKFIFOAT''@|$(REPLACE_MKFIFOAT)|g' \
              -e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \
+             -e 's|@''REPLACE_MKNODAT''@|$(REPLACE_MKNODAT)|g' \
              -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \
              -e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \