summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorguenther <>2016-08-28 04:08:59 +0000
committerguenther <>2016-08-28 04:08:59 +0000
commit1250d78eeed22bd3e5b5389e26f447d9d5f5969b (patch)
tree97bebb52af146194335c40817dca433f00de8f64 /src
parent9304d31ee77186647e4a011b65ec5bc5f7aaa6b2 (diff)
downloadopenbsd-1250d78eeed22bd3e5b5389e26f447d9d5f5969b.tar.gz
openbsd-1250d78eeed22bd3e5b5389e26f447d9d5f5969b.tar.bz2
openbsd-1250d78eeed22bd3e5b5389e26f447d9d5f5969b.zip
Don't call lstat() before readlink() just to see if it's a symlink,
as readlink() will tell you that more cheaply. ok millert@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/realpath.c31
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 @@
47char * 45char *
48realpath(const char *path, char *resolved) 46realpath(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;