[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] symlinkat: port to AIX 7.1
From: |
Paul Eggert |
Subject: |
[PATCH] symlinkat: port to AIX 7.1 |
Date: |
Sat, 18 Oct 2014 23:24:07 -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 | 12 ++++++++++++
doc/posix-functions/symlinkat.texi | 4 ++++
lib/symlinkat.c | 23 ++++++++++++++++++++---
lib/unistd.in.h | 16 ++++++++++++++--
m4/symlinkat.m4 | 35 ++++++++++++++++++++++++++++++++++-
m4/unistd_h.m4 | 1 +
modules/symlinkat | 3 ++-
modules/unistd | 1 +
8 files changed, 88 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e012f3a..23234b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2014-10-18 Paul Eggert <address@hidden>
+ 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):
diff --git a/doc/posix-functions/symlinkat.texi
b/doc/posix-functions/symlinkat.texi
index 27ab3ae..7c3e39a 100644
--- a/doc/posix-functions/symlinkat.texi
+++ b/doc/posix-functions/symlinkat.texi
@@ -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.
address@hidden
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.
diff --git a/lib/symlinkat.c b/lib/symlinkat.c
index 26a88f9..9797f46 100644
--- a/lib/symlinkat.c
+++ b/lib/symlinkat.c
@@ -19,13 +19,30 @@
#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)
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index cae779d..bfa9578 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1418,13 +1418,25 @@ _GL_WARN_ON_USE (symlink, "symlink is not portable - "
#if @GNULIB_SYMLINKAT@
-# if address@hidden@
+# 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 address@hidden@
_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
diff --git a/m4/symlinkat.m4 b/m4/symlinkat.m4
index db7ad48..21648bf 100644
--- a/m4/symlinkat.m4
+++ b/m4/symlinkat.m4
@@ -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
])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 6d217d6..d7346a0 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -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])
diff --git a/modules/symlinkat b/modules/symlinkat
index f5d712d..3d1f2ac 100644
--- a/modules/symlinkat
+++ b/modules/symlinkat
@@ -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])
diff --git a/modules/unistd b/modules/unistd
index 0bbeb84..1619509 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -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' \
--
1.9.3
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] symlinkat: port to AIX 7.1,
Paul Eggert <=