X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnu%2Freadlinkat.c;h=c91cf0e8200fafb62c2fde9828cd1a63ae4ff339;hb=92428c426e44751165d3ee86e164c636f3404481;hp=a722ec4bb3840a8212cc60693326ad0d83abcded;hpb=b414e25de8ca49d7567a92c203d431383ec57c83;p=debian%2Ftar diff --git a/gnu/readlinkat.c b/gnu/readlinkat.c index a722ec4b..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-2010 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