diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2015-06-06 18:37:45 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2015-06-06 18:38:30 -0700 |
commit | 325bf192ae281046834884b12705d6c522871b24 (patch) | |
tree | 4faf44a87bd0fde9ea9134e7cb928b629d8558e1 /lib/readlinkat.c | |
parent | 6fec047e9470731d588e52f516c1c704a7a55411 (diff) | |
download | emacs-325bf192ae281046834884b12705d6c522871b24.tar.gz emacs-325bf192ae281046834884b12705d6c522871b24.tar.bz2 emacs-325bf192ae281046834884b12705d6c522871b24.zip |
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.c | 18 |
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); } |