summaryrefslogtreecommitdiff
path: root/openbsd-compat/getcwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/getcwd.c')
-rw-r--r--openbsd-compat/getcwd.c54
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)
37static 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
54char * 51char *
55getcwd(char *pt, size_t size) 52getcwd(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 */
232err: 226err:
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