Annotation of embedaddon/libiconv/srclib/readlink.c, revision 1.1.1.3
1.1 misho 1: /* Stub for readlink().
1.1.1.3 ! misho 2: Copyright (C) 2003-2007, 2009-2019 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
1.1.1.3 ! misho 15: along with this program. If not, see <https://www.gnu.org/licenses/>. */
1.1 misho 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>