+2015-05-31 Pádraig Brady <P@draigBrady.com>
+
+ readlinkat: avoid OS X 10.10 trailing slash bug
+ * doc/posix-functions/readlink.texi: Mention that OS X 10.10
+ has this bug.
+ * doc/posix-functions/readlinkat.texi: Likewise. Also mention
+ that OS X 10.10 has this function.
+ * lib/readlinkat.c (rpl_readlinkat): Handle the trailing slash bug,
+ as done for readlink().
+ * m4/readlinkat.m4 (gl_FUNC_READLINKAT): Check for the readlink()
+ trailing slash bug, and assume readlinkat() has the same issue.
+ Also fix a typo where $gl_cv_decl_readlink_works was tested,
+ rather than the correct $gl_cv_decl_readlinkat_works.
+
2015-05-29 Andreas Gruenbacher <andreas.gruenbacher@gmail.com>
acl-permissions: Fix build on Mac OS X and older AIX (Bug#20681)
@itemize
@item
Some platforms mistakenly succeed on @code{readlink("link/",buf,len)}:
-FreeBSD 7.2, Solaris 9.
+FreeBSD 7.2, Solaris 9, Mac OS X 10.10.
@item
On some platforms, @code{readlink} returns @code{int} instead of
@code{ssize_t}:
@itemize
@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,
+glibc 2.3.6, Mac OS X < 10.10, 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.
But the replacement function is not safe to be used in libraries and is not multithread-safe.
@item
+Some platforms mistakenly succeed on @code{readlink("link/",buf,len)}:
+Mac OS X 10.10.
+@item
On some platforms, @code{readlinkat} returns @code{int} instead of
@code{ssize_t}:
AIX 7.1.
#include <config.h>
+#include <errno.h>
#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
#if HAVE_READLINKAT
ssize_t
rpl_readlinkat (int fd, char const *file, char *buf, size_t len)
{
+# if READLINK_TRAILING_SLASH_BUG
+ size_t file_len = strlen (file);
+ if (file_len && file[file_len - 1] == '/')
+ {
+ /* Even if FILE without the slash is a symlink to a directory,
+ both lstat() and stat() must resolve the trailing slash to
+ the directory rather than the symlink. We can therefore
+ safely use stat() to distinguish between EINVAL and
+ ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat(). */
+ struct stat st;
+ if (stat (file, &st) == 0)
+ errno = EINVAL;
+ return -1;
+ }
+# endif /* READLINK_TRAILING_SLASH_BUG */
return readlinkat (fd, file, buf, len);
}
-# serial 4
+# serial 5
# See if we need to provide readlinkat replacement.
dnl Copyright (C) 2009-2015 Free Software Foundation, Inc.
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_FUNCS_ONCE([readlinkat])
+ AC_REQUIRE([gl_FUNC_READLINK])
if test $ac_cv_func_readlinkat = no; then
HAVE_READLINKAT=0
else
ssize_t readlinkat (int, char const *, char *, size_t);]])],
[gl_cv_decl_readlinkat_works=yes],
[gl_cv_decl_readlinkat_works=no])])
- if test "$gl_cv_decl_readlink_works" != yes; then
- REPLACE_READLINKAT=1
- fi
+ # Assume readinkat has the same trailing slash bug as readlink,
+ # as is the case on Mac Os X 10.10
+ case "$gl_cv_func_readlink_works" in
+ *yes)
+ if test "$gl_cv_decl_readlinkat_works" != yes; then
+ REPLACE_READLINKAT=1
+ fi
+ ;;
+ *)
+ REPLACE_READLINKAT=1
+ ;;
+ esac
fi
])