]> Savannah Git Hosting - gnulib.git/commitdiff
symlinkat: port to AIX 7.1
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 19 Oct 2014 06:22:36 +0000 (23:22 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 19 Oct 2014 06:23:48 +0000 (23:23 -0700)
* doc/posix-functions/symlinkat.texi (symlinkat):
Mention AIX porting problem.
* lib/symlinkat.c: Always include errno.h.
(rpl_symlinkat) [HAVE_SYMLINKAT]: New function.
* lib/unistd.in.h (symlinkat): Add replacement machinery.
* m4/symlinkat.m4 (gl_FUNC_SYMLINKAT): Check symlinkat behavior.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add REPLACE_SYMLINKAT.
* modules/symlinkat (Depends-on): Add fstatat if REPLACE_SYMLINKAT.
(configure.ac): Also compile replacement if REPLACE_SYMLINKAT.
* modules/unistd (unistd.h): Substitute REPLACE_SYMLINKAT.

ChangeLog
doc/posix-functions/symlinkat.texi
lib/symlinkat.c
lib/unistd.in.h
m4/symlinkat.m4
m4/unistd_h.m4
modules/symlinkat
modules/unistd

index e012f3a0b743cfe366cf5c840cf2bb946486ae27..23234b7bbf8a096fd26fefd567dda6900c8789fa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2014-10-18  Paul Eggert  <eggert@cs.ucla.edu>
 
+       symlinkat: port to AIX 7.1
+       * doc/posix-functions/symlinkat.texi (symlinkat):
+       Mention AIX porting problem.
+       * lib/symlinkat.c: Always include errno.h.
+       (rpl_symlinkat) [HAVE_SYMLINKAT]: New function.
+       * lib/unistd.in.h (symlinkat): Add replacement machinery.
+       * m4/symlinkat.m4 (gl_FUNC_SYMLINKAT): Check symlinkat behavior.
+       * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add REPLACE_SYMLINKAT.
+       * modules/symlinkat (Depends-on): Add fstatat if REPLACE_SYMLINKAT.
+       (configure.ac): Also compile replacement if REPLACE_SYMLINKAT.
+       * modules/unistd (unistd.h): Substitute REPLACE_SYMLINKAT.
+
        readlinkat: port to AIX 7.1
        * doc/posix-functions/readlink.texi (readlink):
        * doc/posix-functions/readlinkat.texi (readlinkat):
index 27ab3aebcf0bde6aa979456302b2719c9753e86d..7c3e39a8b077e4e710f15d5a6f0eb4c9a3abec33 100644 (file)
@@ -9,6 +9,10 @@ Gnulib module: symlinkat
 Portability problems fixed by Gnulib:
 @itemize
 @item
+On some systems, @code{symlinkat(value, fd, "name/")} mistakenly creates a
+symlink:
+AIX 7.1.
+@item
 This function is missing on some platforms:
 glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8,
 AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, MSVC 9, Interix 3.5, BeOS.
index 26a88f9d15bfedd07a21b0585350e6898dbafc51..9797f46e7ba376ca7aa23f67c4a818ba0b1402da 100644 (file)
 #include <config.h>
 
 #include <unistd.h>
+#include <errno.h>
 
-#if !HAVE_SYMLINK
+#if HAVE_SYMLINKAT
+# undef symlinkat
+
+/* Create a symlink, but reject trailing slash.  */
+int
+rpl_symlinkat (char const *contents, int fd, char const *name)
+{
+  size_t len = strlen (name);
+  if (len && name[len - 1] == '/')
+    {
+      struct stat st;
+      if (fstatat (fd, name, &st, 0) == 0)
+        errno = EEXIST;
+      return -1;
+    }
+  return symlinkat (contents, fd, name);
+}
+
+#elif !HAVE_SYMLINK
 /* Mingw lacks symlink, and it is more efficient to provide a trivial
    wrapper than to go through at-func.c to call rpl_symlink.  */
 
-# include <errno.h>
-
 int
 symlinkat (char const *path1 _GL_UNUSED, int fd _GL_UNUSED,
            char const *path2 _GL_UNUSED)
index cae779d26220fcbdad19832dee37f6483605895c..bfa9578f1e265747ea8264fcd0333fe1402cbb00 100644 (file)
@@ -1418,13 +1418,25 @@ _GL_WARN_ON_USE (symlink, "symlink is not portable - "
 
 
 #if @GNULIB_SYMLINKAT@
-# if !@HAVE_SYMLINKAT@
+# if @REPLACE_SYMLINKAT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef symlinkat
+#   define symlinkat rpl_symlinkat
+#  endif
+_GL_FUNCDECL_RPL (symlinkat, int,
+                  (char const *contents, int fd, char const *file)
+                  _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (symlinkat, int,
+                  (char const *contents, int fd, char const *file));
+# else
+#  if !@HAVE_SYMLINKAT@
 _GL_FUNCDECL_SYS (symlinkat, int,
                   (char const *contents, int fd, char const *file)
                   _GL_ARG_NONNULL ((1, 3)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (symlinkat, int,
                   (char const *contents, int fd, char const *file));
+# endif
 _GL_CXXALIASWARN (symlinkat);
 #elif defined GNULIB_POSIXCHECK
 # undef symlinkat
index db7ad487dd8b3db8c601cf169f2d946dbe312e4f..21648bfb16ac426d56e14f2bc263498928b51242 100644 (file)
@@ -1,4 +1,4 @@
-# serial 5
+# serial 6
 # See if we need to provide symlinkat replacement.
 
 dnl Copyright (C) 2009-2014 Free Software Foundation, Inc.
@@ -16,5 +16,38 @@ AC_DEFUN([gl_FUNC_SYMLINKAT],
   AC_CHECK_FUNCS_ONCE([symlinkat])
   if test $ac_cv_func_symlinkat = no; then
     HAVE_SYMLINKAT=0
+  else
+    AC_CACHE_CHECK([whether symlinkat handles trailing slash correctly],
+      [gl_cv_func_symlinkat_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <fcntl.h>
+             #include <unistd.h>
+           ]],
+           [[int result = 0;
+             if (!symlinkat ("a", AT_FDCWD, "conftest.link/"))
+               result |= 1;
+             if (symlinkat ("conftest.f", AT_FDCWD, "conftest.lnk2"))
+               result |= 2;
+             else if (!symlinkat ("a", AT_FDCWD, "conftest.lnk2/"))
+               result |= 4;
+             return result;
+           ]])],
+         [gl_cv_func_symlinkat_works=yes],
+         [gl_cv_func_symlinkat_works=no],
+         [case "$host_os" in
+                    # Guess yes on glibc systems.
+            *-gnu*) gl_cv_func_symlinkat_works="guessing yes" ;;
+                    # If we don't know, assume the worst.
+            *)      gl_cv_func_symlinkat_works="guessing no" ;;
+          esac
+         ])
+      rm -f conftest.f conftest.link conftest.lnk2])
+    case "$gl_cv_func_symlinkat_works" in
+      *yes) ;;
+      *)
+        REPLACE_SYMLINKAT=1
+        ;;
+    esac
   fi
 ])
index 6d217d66b43a3c74cf657da53f8a239aa38b1f3d..d7346a0b05b308faeb3811827218f19aec9285ff 100644 (file)
@@ -177,6 +177,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   REPLACE_RMDIR=0;        AC_SUBST([REPLACE_RMDIR])
   REPLACE_SLEEP=0;        AC_SUBST([REPLACE_SLEEP])
   REPLACE_SYMLINK=0;      AC_SUBST([REPLACE_SYMLINK])
+  REPLACE_SYMLINKAT=0;    AC_SUBST([REPLACE_SYMLINKAT])
   REPLACE_TTYNAME_R=0;    AC_SUBST([REPLACE_TTYNAME_R])
   REPLACE_UNLINK=0;       AC_SUBST([REPLACE_UNLINK])
   REPLACE_UNLINKAT=0;     AC_SUBST([REPLACE_UNLINKAT])
index f5d712d9f6ad317ea9bfb57b59543055cc97be3a..3d1f2ac269aa117d30e533ef2cddf6b6c6cdf3d3 100644 (file)
@@ -18,10 +18,11 @@ openat-die      [test $HAVE_SYMLINKAT = 0]
 openat-h        [test $HAVE_SYMLINKAT = 0]
 save-cwd        [test $HAVE_SYMLINKAT = 0]
 symlink         [test $HAVE_SYMLINKAT = 0]
+fstatat         [test $REPLACE_SYMLINKAT = 1]
 
 configure.ac:
 gl_FUNC_SYMLINKAT
-if test $HAVE_SYMLINKAT = 0; then
+if test $HAVE_SYMLINKAT = 0 || test $REPLACE_SYMLINKAT = 1; then
   AC_LIBOBJ([symlinkat])
 fi
 gl_UNISTD_MODULE_INDICATOR([symlinkat])
index 0bbeb847a5cfe1df5408054f1269c7bae179e150..1619509694db3e327ab64e089f609e3f12a9c467 100644 (file)
@@ -154,6 +154,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
              -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
              -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
              -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
+             -e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \
              -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
              -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
              -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \