Annotation of embedaddon/libiconv/srclib/readlink.c, revision 1.1.1.2
1.1 misho 1: /* Stub for readlink().
1.1.1.2 ! misho 2: Copyright (C) 2003-2007, 2009-2011 Free Software Foundation, Inc.
1.1 misho 3:
4: This program is free software: you can redistribute it and/or modify
5: it under the terms of the GNU General Public License as published by
6: the Free Software Foundation; either version 3 of the License, or
7: (at your option) any later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
14: You should have received a copy of the GNU General Public License
15: along with this program. If not, see <http://www.gnu.org/licenses/>. */
16:
17: #include <config.h>
18:
19: /* Specification. */
20: #include <unistd.h>
21:
22: #include <errno.h>
1.1.1.2 ! misho 23: #include <string.h>
1.1 misho 24: #include <sys/stat.h>
25:
26: #if !HAVE_READLINK
27:
28: /* readlink() substitute for systems that don't have a readlink() function,
29: such as DJGPP 2.03 and mingw32. */
30:
1.1.1.2 ! misho 31: ssize_t
! 32: readlink (const char *name, char *buf _GL_UNUSED,
! 33: size_t bufsize _GL_UNUSED)
1.1 misho 34: {
35: struct stat statbuf;
36:
37: /* In general we should use lstat() here, not stat(). But on platforms
1.1.1.2 ! misho 38: without symbolic links, lstat() - if it exists - would be equivalent to
1.1 misho 39: stat(), therefore we can use stat(). This saves us a configure check. */
1.1.1.2 ! misho 40: if (stat (name, &statbuf) >= 0)
1.1 misho 41: errno = EINVAL;
42: return -1;
43: }
44:
1.1.1.2 ! misho 45: #else /* HAVE_READLINK */
! 46:
! 47: # undef readlink
! 48:
! 49: /* readlink() wrapper that uses correct types, for systems like cygwin
! 50: 1.5.x where readlink returns int, and which rejects trailing slash,
! 51: for Solaris 9. */
! 52:
! 53: ssize_t
! 54: rpl_readlink (const char *name, char *buf, size_t bufsize)
! 55: {
! 56: # if READLINK_TRAILING_SLASH_BUG
! 57: size_t len = strlen (name);
! 58: if (len && name[len - 1] == '/')
! 59: {
! 60: /* Even if name without the slash is a symlink to a directory,
! 61: both lstat() and stat() must resolve the trailing slash to
! 62: the directory rather than the symlink. We can therefore
! 63: safely use stat() to distinguish between EINVAL and
! 64: ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat(). */
! 65: struct stat st;
! 66: if (stat (name, &st) == 0)
! 67: errno = EINVAL;
! 68: return -1;
! 69: }
! 70: # endif /* READLINK_TRAILING_SLASH_BUG */
! 71: return readlink (name, buf, bufsize);
! 72: }
! 73:
! 74: #endif /* HAVE_READLINK */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>