1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005,2006 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. */
25 #include <sys/types.h>
30 #include <fcntl.h> /* For AT_FDCWD on Solaris 9. */
33 # define __set_errno(val) (errno = (val))
37 #ifndef _D_EXACT_NAMLEN
38 # define _D_EXACT_NAMLEN(d) strlen ((d)->d_name)
40 #ifndef _D_ALLOC_NAMLEN
41 # define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
50 # define mempcpy __mempcpy
58 /* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its
59 value exceeds INT_MAX, so its use as an int doesn't conform to the
60 C standard, and GCC and Sun C complain in some cases. */
61 #if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
63 # define AT_FDCWD (-3041965)
67 # define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
69 # define is_ENAMETOOLONG(x) 0
73 # define MAX(a, b) ((a) < (b) ? (b) : (a))
76 # define MIN(a, b) ((a) < (b) ? (a) : (b))
81 # define PATH_MAX MAXPATHLEN
83 # define PATH_MAX 1024
88 # define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino))
90 # define MATCHING_INO(dp, ino) true
94 # define __getcwd getcwd
95 # define __lstat lstat
96 # define __closedir closedir
97 # define __opendir opendir
98 # define __readdir readdir
101 /* The results of opendir() in this file are not used with dirfd and fchdir,
102 therefore save some unnecessary recursion in fchdir.c. */
106 /* Get the name of the current working directory, and put it in SIZE
107 bytes of BUF. Returns NULL if the directory couldn't be determined or
108 SIZE was too small. If successful, returns BUF. In GNU, if BUF is
109 NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
110 unless SIZE == 0, in which case it is as big as necessary. */
113 __getcwd (char *buf, size_t size)
115 /* Lengths of big file name components and entire file names, and a
116 deep level of file name nesting. These numbers are not upper
117 bounds; they are merely large values suitable for initial
118 allocations, designed to be large enough for most real-world
122 BIG_FILE_NAME_COMPONENT_LENGTH = 255,
123 BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1),
129 bool fd_needs_closing = false;
131 char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1];
132 char *dotlist = dots;
133 size_t dotsize = sizeof dots;
136 DIR *dirstream = NULL;
137 dev_t rootdev, thisdev;
138 ino_t rootino, thisino;
142 size_t allocated = size;
145 #if HAVE_PARTLY_WORKING_GETCWD && !defined AT_FDCWD
146 /* The system getcwd works, except it sometimes fails when it
147 shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If
148 AT_FDCWD is not defined, the algorithm below is O(N**2) and this
149 is much slower than the system getcwd (at least on GNU/Linux).
150 So trust the system getcwd's results unless they look
153 dir = getcwd (buf, size);
154 if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT))
162 __set_errno (EINVAL);
166 allocated = BIG_FILE_NAME_LENGTH + 1;
171 dir = malloc (allocated);
178 dirp = dir + allocated;
181 if (__lstat (".", &st) < 0)
186 if (__lstat ("/", &st) < 0)
191 while (!(thisdev == rootdev && thisino == rootino))
200 bool use_d_ino = true;
202 /* Look at the parent directory. */
204 fd = openat (fd, "..", O_RDONLY);
207 fd_needs_closing = true;
208 parent_status = fstat (fd, &st);
210 dotlist[dotlen++] = '.';
211 dotlist[dotlen++] = '.';
212 dotlist[dotlen] = '\0';
213 parent_status = __lstat (dotlist, &st);
215 if (parent_status != 0)
218 if (dirstream && __closedir (dirstream) != 0)
224 /* Figure out if this directory is a mount point. */
227 mount_point = dotdev != thisdev;
229 /* Search for the last directory. */
231 dirstream = fdopendir (fd);
232 if (dirstream == NULL)
234 fd_needs_closing = false;
236 dirstream = __opendir (dotlist);
237 if (dirstream == NULL)
239 dotlist[dotlen++] = '/';
243 /* Clear errno to distinguish EOF from error if readdir returns
246 d = __readdir (dirstream);
248 /* When we've iterated through all directory entries without finding
249 one with a matching d_ino, rewind the stream and consider each
250 name again, but this time, using lstat. This is necessary in a
251 chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
252 .., ../.., ../../.., etc. all had the same device number, yet the
253 d_ino values for entries in / did not match those obtained
255 if (d == NULL && errno == 0 && use_d_ino)
258 rewinddir (dirstream);
259 d = __readdir (dirstream);
265 /* EOF on dirstream, which can mean e.g., that the current
266 directory has been removed. */
267 __set_errno (ENOENT);
270 if (d->d_name[0] == '.' &&
271 (d->d_name[1] == '\0' ||
272 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
277 bool match = (MATCHING_INO (d, thisino) || mount_point);
285 entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
287 /* Compute size needed for this file name, or for the file
288 name ".." in the same directory, whichever is larger.
289 Room for ".." might be needed the next time through
291 size_t name_alloc = _D_ALLOC_NAMLEN (d);
292 size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
294 if (filesize < dotlen)
295 goto memory_exhausted;
297 if (dotsize < filesize)
299 /* My, what a deep directory tree you have, Grandma. */
300 size_t newsize = MAX (filesize, dotsize * 2);
302 if (newsize < dotsize)
303 goto memory_exhausted;
306 dotlist = malloc (newsize);
321 memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
322 entry_status = __lstat (dotlist, &st);
324 /* We don't fail here if we cannot stat() a directory entry.
325 This can happen when (network) file systems fail. If this
326 entry is in fact the one we are looking for we will find
327 out soon as we reach the end of the directory without
328 having found anything. */
329 if (entry_status == 0 && S_ISDIR (st.st_mode)
330 && st.st_dev == thisdev && st.st_ino == thisino)
335 dirroom = dirp - dir;
336 namlen = _D_EXACT_NAMLEN (d);
338 if (dirroom <= namlen)
342 __set_errno (ERANGE);
348 size_t oldsize = allocated;
350 allocated += MAX (allocated, namlen);
351 if (allocated < oldsize
352 || ! (tmp = realloc (dir, allocated)))
353 goto memory_exhausted;
355 /* Move current contents up to the end of the buffer.
356 This is guaranteed to be non-overlapping. */
357 dirp = memcpy (tmp + allocated - (oldsize - dirroom),
364 memcpy (dirp, d->d_name, namlen);
371 if (dirstream && __closedir (dirstream) != 0)
377 if (dirp == &dir[allocated - 1])
385 used = dir + allocated - dirp;
386 memmove (dir, dirp, used);
388 if (buf == NULL && size == 0)
389 /* Ensure that the buffer is only as large as necessary. */
390 buf = realloc (dir, used);
393 /* Either buf was NULL all along, or `realloc' failed but
394 we still have the original string. */
400 __set_errno (ENOMEM);
405 __closedir (dirstream);
407 if (fd_needs_closing)
421 weak_alias (__getcwd, getcwd)