diff options
author | doug <> | 2014-10-18 20:43:52 +0000 |
---|---|---|
committer | doug <> | 2014-10-18 20:43:52 +0000 |
commit | b0ad006b01899618307bba729ced855f135cb798 (patch) | |
tree | 4bdb23db70df4e1559c5bad1868d86729b458d48 /src | |
parent | 04818d13dd76f6467f7c876faf62cbc8f22646ca (diff) | |
download | openbsd-b0ad006b01899618307bba729ced855f135cb798.tar.gz openbsd-b0ad006b01899618307bba729ced855f135cb798.tar.bz2 openbsd-b0ad006b01899618307bba729ced855f135cb798.zip |
Better POSIX compliance in realpath(3).
millert@ made changes to realpath.c based on FreeBSD's version. I merged
Todd's changes into dl_realpath.c.
ok millert@, guenther@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/realpath.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c index e0f9b123b3..8c83ec2b81 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.16 2013/04/05 12:59:54 kurt Exp $ */ | 1 | /* $OpenBSD: realpath.c,v 1.17 2014/10/18 20:43:52 doug 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 | * |
@@ -54,6 +54,10 @@ realpath(const char *path, char *resolved) | |||
54 | int serrno, slen, mem_allocated; | 54 | int serrno, slen, mem_allocated; |
55 | char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; | 55 | char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; |
56 | 56 | ||
57 | if (path == NULL) { | ||
58 | errno = EINVAL; | ||
59 | return (NULL); | ||
60 | } | ||
57 | if (path[0] == '\0') { | 61 | if (path[0] == '\0') { |
58 | errno = ENOENT; | 62 | errno = ENOENT; |
59 | return (NULL); | 63 | return (NULL); |
@@ -139,22 +143,15 @@ realpath(const char *path, char *resolved) | |||
139 | } | 143 | } |
140 | 144 | ||
141 | /* | 145 | /* |
142 | * Append the next path component and lstat() it. If | 146 | * Append the next path component and lstat() it. |
143 | * lstat() fails we still can return successfully if | ||
144 | * there are no more path components left. | ||
145 | */ | 147 | */ |
146 | resolved_len = strlcat(resolved, next_token, PATH_MAX); | 148 | resolved_len = strlcat(resolved, next_token, PATH_MAX); |
147 | if (resolved_len >= PATH_MAX) { | 149 | if (resolved_len >= PATH_MAX) { |
148 | errno = ENAMETOOLONG; | 150 | errno = ENAMETOOLONG; |
149 | goto err; | 151 | goto err; |
150 | } | 152 | } |
151 | if (lstat(resolved, &sb) != 0) { | 153 | if (lstat(resolved, &sb) != 0) |
152 | if (errno == ENOENT && p == NULL) { | ||
153 | errno = serrno; | ||
154 | return (resolved); | ||
155 | } | ||
156 | goto err; | 154 | goto err; |
157 | } | ||
158 | if (S_ISLNK(sb.st_mode)) { | 155 | if (S_ISLNK(sb.st_mode)) { |
159 | if (symlinks++ > MAXSYMLINKS) { | 156 | if (symlinks++ > MAXSYMLINKS) { |
160 | errno = ELOOP; | 157 | errno = ELOOP; |
@@ -196,6 +193,9 @@ realpath(const char *path, char *resolved) | |||
196 | } | 193 | } |
197 | } | 194 | } |
198 | left_len = strlcpy(left, symlink, sizeof(left)); | 195 | left_len = strlcpy(left, symlink, sizeof(left)); |
196 | } else if (!S_ISDIR(sb.st_mode) && p != NULL) { | ||
197 | errno = ENOTDIR; | ||
198 | goto err; | ||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||