summaryrefslogtreecommitdiff
path: root/libc/stdlib/realpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdlib/realpath.c')
-rw-r--r--libc/stdlib/realpath.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/libc/stdlib/realpath.c b/libc/stdlib/realpath.c
index 99afbde0c..e23c23c82 100644
--- a/libc/stdlib/realpath.c
+++ b/libc/stdlib/realpath.c
@@ -133,29 +133,33 @@ char got_path[];
path_len = strlen(path);
/* See if last (so far) pathname component is a symlink. */
*new_path = '\0';
- link_len = readlink(got_path, copy_path, PATH_MAX - 1);
- if (link_len < 0) {
- /* EINVAL means the file exists but isn't a symlink. */
- if (errno != EINVAL) {
- return NULL;
- }
- } else {
- /* Safe sex check. */
- if (path_len + link_len >= PATH_MAX - 2) {
- __set_errno(ENAMETOOLONG);
- return NULL;
+ {
+ int sv_errno = errno;
+ link_len = readlink(got_path, copy_path, PATH_MAX - 1);
+ if (link_len < 0) {
+ /* EINVAL means the file exists but isn't a symlink. */
+ if (errno != EINVAL) {
+ return NULL;
+ }
+ } else {
+ /* Safe sex check. */
+ if (path_len + link_len >= PATH_MAX - 2) {
+ __set_errno(ENAMETOOLONG);
+ return NULL;
+ }
+ /* Note: readlink doesn't add the null byte. */
+ /* copy_path[link_len] = '\0'; - we don't need it too */
+ if (*copy_path == '/')
+ /* Start over for an absolute symlink. */
+ new_path = got_path;
+ else
+ /* Otherwise back up over this component. */
+ while (*(--new_path) != '/');
+ /* Prepend symlink contents to path. */
+ memmove(copy_path + (PATH_MAX-1) - link_len - path_len, copy_path, link_len);
+ path = copy_path + (PATH_MAX-1) - link_len - path_len;
}
- /* Note: readlink doesn't add the null byte. */
- /* copy_path[link_len] = '\0'; - we don't need it too */
- if (*copy_path == '/')
- /* Start over for an absolute symlink. */
- new_path = got_path;
- else
- /* Otherwise back up over this component. */
- while (*(--new_path) != '/');
- /* Prepend symlink contents to path. */
- memmove(copy_path + (PATH_MAX-1) - link_len - path_len, copy_path, link_len);
- path = copy_path + (PATH_MAX-1) - link_len - path_len;
+ __set_errno(sv_errno);
}
#endif /* S_IFLNK */
*new_path++ = '/';