1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005 Free Software
3 This file is part of the GNU C Library.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
28 #include <sys/types.h>
33 #include <fcntl.h> /* For AT_FDCWD on Solaris 9. */
35 __RCSID("$MirOS: src/gnu/usr.bin/cvs/lib/getcwd.c,v 1.3 2010/09/19 19:42:57 tg Exp $");
38 # define __set_errno(val) (errno = (val))
41 #if HAVE_DIRENT_H || _LIBC
43 # ifndef _D_EXACT_NAMLEN
44 # define _D_EXACT_NAMLEN(d) strlen ((d)->d_name)
47 # define dirent direct
49 # include <sys/ndir.h>
58 #ifndef _D_EXACT_NAMLEN
59 # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
61 #ifndef _D_ALLOC_NAMLEN
62 # define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
65 #if HAVE_UNISTD_H || _LIBC
74 # define mempcpy __mempcpy
83 # define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
85 # define is_ENAMETOOLONG(x) 0
89 # define MAX(a, b) ((a) < (b) ? (b) : (a))
92 # define MIN(a, b) ((a) < (b) ? (a) : (b))
97 # define PATH_MAX MAXPATHLEN
99 # define PATH_MAX 1024
104 # define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino))
106 # define MATCHING_INO(dp, ino) true
110 # define __getcwd getcwd
111 # define __lstat lstat
112 # define __closedir closedir
113 # define __opendir opendir
114 # define __readdir readdir
117 /* Get the name of the current working directory, and put it in SIZE
118 bytes of BUF. Returns NULL if the directory couldn't be determined or
119 SIZE was too small. If successful, returns BUF. In GNU, if BUF is
120 NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
121 unless SIZE == 0, in which case it is as big as necessary. */
124 __getcwd (char *buf, size_t size)
126 /* Lengths of big file name components and entire file names, and a
127 deep level of file name nesting. These numbers are not upper
128 bounds; they are merely large values suitable for initial
129 allocations, designed to be large enough for most real-world
133 BIG_FILE_NAME_COMPONENT_LENGTH = 255,
134 BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1),
140 bool fd_needs_closing = false;
142 char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1];
143 char *dotlist = dots;
144 size_t dotsize = sizeof dots;
147 DIR *dirstream = NULL;
148 dev_t rootdev, thisdev;
149 ino_t rootino, thisino;
153 size_t allocated = size;
156 #if HAVE_PARTLY_WORKING_GETCWD
157 /* The system getcwd works, except it sometimes fails when it
158 shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If
159 AT_FDCWD is not defined, the algorithm below is O(N**2) and this
160 is much slower than the system getcwd (at least on GNU/Linux).
161 So trust the system getcwd's results unless they look
164 dir = getcwd (buf, size);
165 if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT))
173 __set_errno (EINVAL);
177 allocated = BIG_FILE_NAME_LENGTH + 1;
182 dir = malloc (allocated);
189 dirp = dir + allocated;
192 if (__lstat (".", &st) < 0)
197 if (__lstat ("/", &st) < 0)
202 while (!(thisdev == rootdev && thisino == rootino))
211 bool use_d_ino = true;
213 /* Look at the parent directory. */
215 fd = openat (fd, "..", O_RDONLY);
218 fd_needs_closing = true;
219 parent_status = fstat (fd, &st);
221 dotlist[dotlen++] = '.';
222 dotlist[dotlen++] = '.';
223 dotlist[dotlen] = '\0';
224 parent_status = __lstat (dotlist, &st);
226 if (parent_status != 0)
229 if (dirstream && __closedir (dirstream) != 0)
235 /* Figure out if this directory is a mount point. */
238 mount_point = dotdev != thisdev;
240 /* Search for the last directory. */
242 dirstream = fdopendir (fd);
243 if (dirstream == NULL)
245 fd_needs_closing = false;
247 dirstream = __opendir (dotlist);
248 if (dirstream == NULL)
250 dotlist[dotlen++] = '/';
254 /* Clear errno to distinguish EOF from error if readdir returns
257 d = __readdir (dirstream);
259 /* When we've iterated through all directory entries without finding
260 one with a matching d_ino, rewind the stream and consider each
261 name again, but this time, using lstat. This is necessary in a
262 chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
263 .., ../.., ../../.., etc. all had the same device number, yet the
264 d_ino values for entries in / did not match those obtained
266 if (d == NULL && errno == 0 && use_d_ino)
269 rewinddir (dirstream);
270 d = __readdir (dirstream);
276 /* EOF on dirstream, which can mean e.g., that the current
277 directory has been removed. */
278 __set_errno (ENOENT);
281 if (d->d_name[0] == '.' &&
282 (d->d_name[1] == '\0' ||
283 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
288 bool match = (MATCHING_INO (d, thisino) || mount_point);
296 entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
298 /* Compute size needed for this file name, or for the file
299 name ".." in the same directory, whichever is larger.
300 Room for ".." might be needed the next time through
302 size_t name_alloc = _D_ALLOC_NAMLEN (d);
303 size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
305 if (filesize < dotlen)
306 goto memory_exhausted;
308 if (dotsize < filesize)
310 /* My, what a deep directory tree you have, Grandma. */
311 size_t newsize = MAX (filesize, dotsize * 2);
313 if (newsize < dotsize)
314 goto memory_exhausted;
317 dotlist = malloc (newsize);
332 memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
333 entry_status = __lstat (dotlist, &st);
335 /* We don't fail here if we cannot stat() a directory entry.
336 This can happen when (network) file systems fail. If this
337 entry is in fact the one we are looking for we will find
338 out soon as we reach the end of the directory without
339 having found anything. */
340 if (entry_status == 0 && S_ISDIR (st.st_mode)
341 && st.st_dev == thisdev && st.st_ino == thisino)
346 dirroom = dirp - dir;
347 namlen = _D_EXACT_NAMLEN (d);
349 if (dirroom <= namlen)
353 __set_errno (ERANGE);
359 size_t oldsize = allocated;
361 allocated += MAX (allocated, namlen);
362 if (allocated < oldsize
363 || ! (tmp = realloc (dir, allocated)))
364 goto memory_exhausted;
366 /* Move current contents up to the end of the buffer.
367 This is guaranteed to be non-overlapping. */
368 dirp = memcpy (tmp + allocated - (oldsize - dirroom),
375 memcpy (dirp, d->d_name, namlen);
382 if (dirstream && __closedir (dirstream) != 0)
388 if (dirp == &dir[allocated - 1])
396 used = dir + allocated - dirp;
397 memmove (dir, dirp, used);
399 if (buf == NULL && size == 0)
400 /* Ensure that the buffer is only as large as necessary. */
401 buf = realloc (dir, used);
404 /* Either buf was NULL all along, or `realloc' failed but
405 we still have the original string. */
411 __set_errno (ENOMEM);
416 __closedir (dirstream);
418 if (fd_needs_closing)
432 weak_alias (__getcwd, getcwd)