X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnu%2Freadlinkat.c;h=c91cf0e8200fafb62c2fde9828cd1a63ae4ff339;hb=d30babc23b4f25be970ada2e63a50220a3672281;hp=83355ba17785a39aa6ff9afd78c3f6964a4fe36f;hpb=4aa85f09e755fc827cd5ab6225f20c83cd42245d;p=debian%2Ftar diff --git a/gnu/readlinkat.c b/gnu/readlinkat.c index 83355ba1..c91cf0e8 100644 --- a/gnu/readlinkat.c +++ b/gnu/readlinkat.c @@ -1,7 +1,5 @@ -/* -*- buffer-read-only: t -*- vi: set ro: */ -/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ /* Read a symlink relative to an open directory. - Copyright (C) 2009-2014 Free Software Foundation, Inc. + Copyright (C) 2009-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,7 +18,37 @@ #include +#include #include +#include +#include + +#if HAVE_READLINKAT + +# undef 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); +} + +#else /* Gnulib provides a readlink stub for mingw; use it for distinction between EINVAL and ENOENT, rather than always failing with ENOSYS. */ @@ -36,14 +64,16 @@ then readlink/restore_cwd. If either the save_cwd or the restore_cwd fails, then give a diagnostic and exit nonzero. */ -#define AT_FUNC_NAME readlinkat -#define AT_FUNC_F1 readlink -#define AT_FUNC_POST_FILE_PARAM_DECLS , char *buf, size_t len -#define AT_FUNC_POST_FILE_ARGS , buf, len -#define AT_FUNC_RESULT ssize_t -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS -#undef AT_FUNC_RESULT +# define AT_FUNC_NAME readlinkat +# define AT_FUNC_F1 readlink +# define AT_FUNC_POST_FILE_PARAM_DECLS , char *buf, size_t len +# define AT_FUNC_POST_FILE_ARGS , buf, len +# define AT_FUNC_RESULT ssize_t +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS +# undef AT_FUNC_RESULT + +#endif