diff options
Diffstat (limited to 'src/lib/libc/stdlib/realpath.c')
| -rw-r--r-- | src/lib/libc/stdlib/realpath.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c index 27f1a29061..c691252ccf 100644 --- a/src/lib/libc/stdlib/realpath.c +++ b/src/lib/libc/stdlib/realpath.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */ | 1 | /* $OpenBSD: realpath.c,v 1.21 2016/08/28 04:08:59 guenther Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> | 3 | * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> |
| 4 | * | 4 | * |
| @@ -27,8 +27,6 @@ | |||
| 27 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #include <sys/stat.h> | ||
| 31 | |||
| 32 | #include <errno.h> | 30 | #include <errno.h> |
| 33 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 34 | #include <string.h> | 32 | #include <string.h> |
| @@ -47,7 +45,6 @@ | |||
| 47 | char * | 45 | char * |
| 48 | realpath(const char *path, char *resolved) | 46 | realpath(const char *path, char *resolved) |
| 49 | { | 47 | { |
| 50 | struct stat sb; | ||
| 51 | char *p, *q, *s; | 48 | char *p, *q, *s; |
| 52 | size_t left_len, resolved_len; | 49 | size_t left_len, resolved_len; |
| 53 | unsigned symlinks; | 50 | unsigned symlinks; |
| @@ -148,21 +145,27 @@ realpath(const char *path, char *resolved) | |||
| 148 | errno = ENAMETOOLONG; | 145 | errno = ENAMETOOLONG; |
| 149 | goto err; | 146 | goto err; |
| 150 | } | 147 | } |
| 151 | if (lstat(resolved, &sb) != 0) { | 148 | slen = readlink(resolved, symlink, sizeof(symlink) - 1); |
| 152 | if (errno == ENOENT && p == NULL) { | 149 | if (slen < 0) { |
| 153 | errno = serrno; | 150 | switch (errno) { |
| 154 | return (resolved); | 151 | case EINVAL: |
| 152 | /* not a symlink, continue to next component */ | ||
| 153 | continue; | ||
| 154 | case ENOENT: | ||
| 155 | if (p == NULL) { | ||
| 156 | errno = serrno; | ||
| 157 | return (resolved); | ||
| 158 | } | ||
| 159 | /* FALLTHROUGH */ | ||
| 160 | default: | ||
| 161 | goto err; | ||
| 155 | } | 162 | } |
| 156 | goto err; | 163 | } else { |
| 157 | } | ||
| 158 | if (S_ISLNK(sb.st_mode)) { | ||
| 159 | if (symlinks++ > SYMLOOP_MAX) { | 164 | if (symlinks++ > SYMLOOP_MAX) { |
| 160 | errno = ELOOP; | 165 | errno = ELOOP; |
| 161 | goto err; | 166 | goto err; |
| 162 | } | 167 | } |
| 163 | slen = readlink(resolved, symlink, sizeof(symlink) - 1); | 168 | |
| 164 | if (slen < 0) | ||
| 165 | goto err; | ||
| 166 | symlink[slen] = '\0'; | 169 | symlink[slen] = '\0'; |
| 167 | if (symlink[0] == '/') { | 170 | if (symlink[0] == '/') { |
| 168 | resolved[1] = 0; | 171 | resolved[1] = 0; |
