summaryrefslogtreecommitdiff
path: root/lib/readlink.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2009-11-15 20:16:40 +0100
committerLudovic Courtès <ludo@gnu.org>2009-11-16 09:23:46 +0100
commit8912421cf3829a4fd65877fd1255125c191f6f89 (patch)
tree6b89fecf0738a1f80792bbe7453730f7882f1d54 /lib/readlink.c
parent3fe87cf7aff396d7bd993aa009f48eb8afd6c1cd (diff)
downloadguile-8912421cf3829a4fd65877fd1255125c191f6f89.tar.gz
Use Gnulib's `inet_ntop' and `inet_pton' modules.
* m4/gnulib-cache.m4: Add `inet_ntop' and `inet_pton'. * configure.ac: Don't check for `inet_ntop' and `inet_pton'. * libguile/socket.c (scm_inet_pton, scm_inet_ntop): Compile regardless of `HAVE_INET_PTON' and `HAVE_INET_NTOP' respectively. * libguile/filesys.c: Use <stdlib.h> instead of <canonicalize.h>.
Diffstat (limited to 'lib/readlink.c')
-rw-r--r--lib/readlink.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/lib/readlink.c b/lib/readlink.c
index c9f49f815..704e6f099 100644
--- a/lib/readlink.c
+++ b/lib/readlink.c
@@ -1,5 +1,5 @@
/* Stub for readlink().
- Copyright (C) 2003-2007 Free Software Foundation, Inc.
+ Copyright (C) 2003-2007, 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -20,30 +20,55 @@
#include <unistd.h>
#include <errno.h>
-#include <sys/types.h>
+#include <string.h>
#include <sys/stat.h>
-#include <stddef.h>
#if !HAVE_READLINK
/* readlink() substitute for systems that don't have a readlink() function,
such as DJGPP 2.03 and mingw32. */
-/* The official POSIX return type of readlink() is ssize_t, but since here
- we have no declaration in a public header file, we use 'int' as return
- type. */
-
-int
-readlink (const char *path, char *buf, size_t bufsize)
+ssize_t
+readlink (const char *name, char *buf _UNUSED_PARAMETER_,
+ size_t bufsize _UNUSED_PARAMETER_)
{
struct stat statbuf;
/* In general we should use lstat() here, not stat(). But on platforms
- without symbolic links lstat() - if it exists - would be equivalent to
+ without symbolic links, lstat() - if it exists - would be equivalent to
stat(), therefore we can use stat(). This saves us a configure check. */
- if (stat (path, &statbuf) >= 0)
+ if (stat (name, &statbuf) >= 0)
errno = EINVAL;
return -1;
}
-#endif
+#else /* HAVE_READLINK */
+
+# undef readlink
+
+/* readlink() wrapper that uses correct types, for systems like cygwin
+ 1.5.x where readlink returns int, and which rejects trailing slash,
+ for Solaris 9. */
+
+ssize_t
+rpl_readlink (const char *name, char *buf, size_t bufsize)
+{
+# if READLINK_TRAILING_SLASH_BUG
+ size_t len = strlen (name);
+ if (len && name[len - 1] == '/')
+ {
+ /* Even if name 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 (name, &st) == 0)
+ errno = EINVAL;
+ return -1;
+ }
+# endif /* READLINK_TRAILING_SLASH_BUG */
+ return readlink (name, buf, bufsize);
+}
+
+#endif /* HAVE_READLINK */