diff options
Diffstat (limited to 'openbsd-compat/getcwd.c')
-rw-r--r-- | openbsd-compat/getcwd.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/openbsd-compat/getcwd.c b/openbsd-compat/getcwd.c index 19be59172..711cb9cd5 100644 --- a/openbsd-compat/getcwd.c +++ b/openbsd-compat/getcwd.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* OPENBSD ORIGINAL: lib/libc/gen/getcwd.c */ | 1 | /* $OpenBSD: getcwd.c,v 1.14 2005/08/08 08:05:34 espie Exp $ */ |
2 | |||
3 | /* | 2 | /* |
4 | * Copyright (c) 1989, 1991, 1993 | 3 | * Copyright (c) 1989, 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -29,14 +28,12 @@ | |||
29 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
30 | */ | 29 | */ |
31 | 30 | ||
31 | /* OPENBSD ORIGINAL: lib/libc/gen/getcwd.c */ | ||
32 | |||
32 | #include "includes.h" | 33 | #include "includes.h" |
33 | 34 | ||
34 | #if !defined(HAVE_GETCWD) | 35 | #if !defined(HAVE_GETCWD) |
35 | 36 | ||
36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
37 | static char rcsid[] = "$OpenBSD: getcwd.c,v 1.9 2003/06/11 21:03:10 deraadt Exp $"; | ||
38 | #endif /* LIBC_SCCS and not lint */ | ||
39 | |||
40 | #include <sys/param.h> | 37 | #include <sys/param.h> |
41 | #include <sys/stat.h> | 38 | #include <sys/stat.h> |
42 | #include <errno.h> | 39 | #include <errno.h> |
@@ -54,12 +51,12 @@ static char rcsid[] = "$OpenBSD: getcwd.c,v 1.9 2003/06/11 21:03:10 deraadt Exp | |||
54 | char * | 51 | char * |
55 | getcwd(char *pt, size_t size) | 52 | getcwd(char *pt, size_t size) |
56 | { | 53 | { |
57 | register struct dirent *dp; | 54 | struct dirent *dp; |
58 | register DIR *dir = NULL; | 55 | DIR *dir = NULL; |
59 | register dev_t dev; | 56 | dev_t dev; |
60 | register ino_t ino; | 57 | ino_t ino; |
61 | register int first; | 58 | int first; |
62 | register char *bpt, *bup; | 59 | char *bpt, *bup; |
63 | struct stat s; | 60 | struct stat s; |
64 | dev_t root_dev; | 61 | dev_t root_dev; |
65 | ino_t root_ino; | 62 | ino_t root_ino; |
@@ -80,7 +77,7 @@ getcwd(char *pt, size_t size) | |||
80 | } | 77 | } |
81 | ept = pt + size; | 78 | ept = pt + size; |
82 | } else { | 79 | } else { |
83 | if ((pt = malloc(ptsize = 1024 - 4)) == NULL) | 80 | if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL) |
84 | return (NULL); | 81 | return (NULL); |
85 | ept = pt + ptsize; | 82 | ept = pt + ptsize; |
86 | } | 83 | } |
@@ -88,13 +85,13 @@ getcwd(char *pt, size_t size) | |||
88 | *bpt = '\0'; | 85 | *bpt = '\0'; |
89 | 86 | ||
90 | /* | 87 | /* |
91 | * Allocate bytes (1024 - malloc space) for the string of "../"'s. | 88 | * Allocate bytes for the string of "../"'s. |
92 | * Should always be enough (it's 340 levels). If it's not, allocate | 89 | * Should always be enough (it's 340 levels). If it's not, allocate |
93 | * as necessary. Special * case the first stat, it's ".", not "..". | 90 | * as necessary. Special * case the first stat, it's ".", not "..". |
94 | */ | 91 | */ |
95 | if ((up = malloc(upsize = 1024 - 4)) == NULL) | 92 | if ((up = malloc(upsize = MAXPATHLEN)) == NULL) |
96 | goto err; | 93 | goto err; |
97 | eup = up + MAXPATHLEN; | 94 | eup = up + upsize; |
98 | bup = up; | 95 | bup = up; |
99 | up[0] = '.'; | 96 | up[0] = '.'; |
100 | up[1] = '\0'; | 97 | up[1] = '\0'; |
@@ -139,18 +136,16 @@ getcwd(char *pt, size_t size) | |||
139 | 136 | ||
140 | if ((nup = realloc(up, upsize *= 2)) == NULL) | 137 | if ((nup = realloc(up, upsize *= 2)) == NULL) |
141 | goto err; | 138 | goto err; |
139 | bup = nup + (bup - up); | ||
142 | up = nup; | 140 | up = nup; |
143 | bup = up; | ||
144 | eup = up + upsize; | 141 | eup = up + upsize; |
145 | } | 142 | } |
146 | *bup++ = '.'; | 143 | *bup++ = '.'; |
147 | *bup++ = '.'; | 144 | *bup++ = '.'; |
148 | *bup = '\0'; | 145 | *bup = '\0'; |
149 | 146 | ||
150 | /* Open and stat parent directory. | 147 | /* Open and stat parent directory. */ |
151 | * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s) | 148 | if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) |
152 | */ | ||
153 | if (!(dir = opendir(up)) || lstat(up,&s)) | ||
154 | goto err; | 149 | goto err; |
155 | 150 | ||
156 | /* Add trailing slash for next directory. */ | 151 | /* Add trailing slash for next directory. */ |
@@ -175,7 +170,7 @@ getcwd(char *pt, size_t size) | |||
175 | goto notfound; | 170 | goto notfound; |
176 | if (ISDOT(dp)) | 171 | if (ISDOT(dp)) |
177 | continue; | 172 | continue; |
178 | memmove(bup, dp->d_name, dp->d_namlen + 1); | 173 | memcpy(bup, dp->d_name, dp->d_namlen + 1); |
179 | 174 | ||
180 | /* Save the first error for later. */ | 175 | /* Save the first error for later. */ |
181 | if (lstat(up, &s)) { | 176 | if (lstat(up, &s)) { |
@@ -193,19 +188,18 @@ getcwd(char *pt, size_t size) | |||
193 | * leading slash. | 188 | * leading slash. |
194 | */ | 189 | */ |
195 | if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { | 190 | if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { |
196 | size_t len, off; | 191 | size_t len; |
197 | char *npt; | 192 | char *npt; |
198 | 193 | ||
199 | if (!ptsize) { | 194 | if (!ptsize) { |
200 | errno = ERANGE; | 195 | errno = ERANGE; |
201 | goto err; | 196 | goto err; |
202 | } | 197 | } |
203 | off = bpt - pt; | ||
204 | len = ept - bpt; | 198 | len = ept - bpt; |
205 | if ((npt = realloc(pt, ptsize *= 2)) == NULL) | 199 | if ((npt = realloc(pt, ptsize *= 2)) == NULL) |
206 | goto err; | 200 | goto err; |
201 | bpt = npt + (bpt - pt); | ||
207 | pt = npt; | 202 | pt = npt; |
208 | bpt = pt + off; | ||
209 | ept = pt + ptsize; | 203 | ept = pt + ptsize; |
210 | memmove(ept - len, bpt, len); | 204 | memmove(ept - len, bpt, len); |
211 | bpt = ept - len; | 205 | bpt = ept - len; |
@@ -213,7 +207,7 @@ getcwd(char *pt, size_t size) | |||
213 | if (!first) | 207 | if (!first) |
214 | *--bpt = '/'; | 208 | *--bpt = '/'; |
215 | bpt -= dp->d_namlen; | 209 | bpt -= dp->d_namlen; |
216 | memmove(bpt, dp->d_name, dp->d_namlen); | 210 | memcpy(bpt, dp->d_name, dp->d_namlen); |
217 | (void)closedir(dir); | 211 | (void)closedir(dir); |
218 | 212 | ||
219 | /* Truncate any file name. */ | 213 | /* Truncate any file name. */ |
@@ -230,12 +224,16 @@ notfound: | |||
230 | errno = save_errno ? save_errno : ENOENT; | 224 | errno = save_errno ? save_errno : ENOENT; |
231 | /* FALLTHROUGH */ | 225 | /* FALLTHROUGH */ |
232 | err: | 226 | err: |
227 | save_errno = errno; | ||
228 | |||
233 | if (ptsize) | 229 | if (ptsize) |
234 | free(pt); | 230 | free(pt); |
235 | if (up) | 231 | free(up); |
236 | free(up); | ||
237 | if (dir) | 232 | if (dir) |
238 | (void)closedir(dir); | 233 | (void)closedir(dir); |
234 | |||
235 | errno = save_errno; | ||
236 | |||
239 | return (NULL); | 237 | return (NULL); |
240 | } | 238 | } |
241 | 239 | ||