summaryrefslogtreecommitdiff
path: root/lib/readlinkat.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-06-06 18:37:45 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2015-06-06 18:38:30 -0700
commit325bf192ae281046834884b12705d6c522871b24 (patch)
tree4faf44a87bd0fde9ea9134e7cb928b629d8558e1 /lib/readlinkat.c
parent6fec047e9470731d588e52f516c1c704a7a55411 (diff)
downloademacs-325bf192ae281046834884b12705d6c522871b24.tar.gz
Merge from gnulib
This incorporates: 2015-06-06 acl-permissions: pacify -Wsuggest-attribute=const 2015-06-05 stdio: Don't redefine gets when using C++ 2015-06-05 acl-permissions: port to AIX, C89 HP-UX 2015-06-02 file-has-acl: fix build on Mac OS X 10 2015-06-01 gnulib-tool: concatenate lib_SOURCES to a single line 2015-06-01 pthread_sigmask: discount system version if a simple macro 2015-05-31 readlinkat: avoid OS X 10.10 trailing slash bug * doc/misc/texinfo.tex, lib/acl-internal.h, lib/get-permissions.c: * lib/readlinkat.c, lib/set-permissions.c, lib/stdio.in.h: * m4/acl.m4, m4/pthread_sigmask.m4, m4/readlinkat.m4: Copy from gnulib. * lib/gnulib.mk: Regenerate.
Diffstat (limited to 'lib/readlinkat.c')
-rw-r--r--lib/readlinkat.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/readlinkat.c b/lib/readlinkat.c
index f4826f92028..c91cf0e8200 100644
--- a/lib/readlinkat.c
+++ b/lib/readlinkat.c
@@ -18,7 +18,10 @@
#include <config.h>
+#include <errno.h>
#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
#if HAVE_READLINKAT
@@ -27,6 +30,21 @@
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);
}