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 /* Get the name of the current working directory, and put it in SIZE
102 bytes of BUF. Returns NULL if the directory couldn't be determined or
103 SIZE was too small. If successful, returns BUF. In GNU, if BUF is
104 NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
105 unless SIZE == 0, in which case it is as big as necessary. */
108 __getcwd (char *buf, size_t size)
110 /* Lengths of big file name components and entire file names, and a
111 deep level of file name nesting. These numbers are not upper
112 bounds; they are merely large values suitable for initial
113 allocations, designed to be large enough for most real-world
117 BIG_FILE_NAME_COMPONENT_LENGTH = 255,
118 BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1),
124 bool fd_needs_closing = false;
126 char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1];
127 char *dotlist = dots;
128 size_t dotsize = sizeof dots;
131 DIR *dirstream = NULL;
132 dev_t rootdev, thisdev;
133 ino_t rootino, thisino;
137 size_t allocated = size;
140 #if HAVE_PARTLY_WORKING_GETCWD && !defined AT_FDCWD
141 /* The system getcwd works, except it sometimes fails when it
142 shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If
143 AT_FDCWD is not defined, the algorithm below is O(N**2) and this
144 is much slower than the system getcwd (at least on GNU/Linux).
145 So trust the system getcwd's results unless they look
148 dir = getcwd (buf, size);
149 if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT))
157 __set_errno (EINVAL);
161 allocated = BIG_FILE_NAME_LENGTH + 1;
166 dir = malloc (allocated);
173 dirp = dir + allocated;
176 if (__lstat (".", &st) < 0)
181 if (__lstat ("/", &st) < 0)
186 while (!(thisdev == rootdev && thisino == rootino))
195 bool use_d_ino = true;
197 /* Look at the parent directory. */
199 fd = openat (fd, "..", O_RDONLY);
202 fd_needs_closing = true;
203 parent_status = fstat (fd, &st);
205 dotlist[dotlen++] = '.';
206 dotlist[dotlen++] = '.';
207 dotlist[dotlen] = '\0';
208 parent_status = __lstat (dotlist, &st);
210 if (parent_status != 0)
213 if (dirstream && __closedir (dirstream) != 0)
219 /* Figure out if this directory is a mount point. */
222 mount_point = dotdev != thisdev;
224 /* Search for the last directory. */
226 dirstream = fdopendir (fd);
227 if (dirstream == NULL)
229 fd_needs_closing = false;
231 dirstream = __opendir (dotlist);
232 if (dirstream == NULL)
234 dotlist[dotlen++] = '/';
238 /* Clear errno to distinguish EOF from error if readdir returns
241 d = __readdir (dirstream);
243 /* When we've iterated through all directory entries without finding
244 one with a matching d_ino, rewind the stream and consider each
245 name again, but this time, using lstat. This is necessary in a
246 chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
247 .., ../.., ../../.., etc. all had the same device number, yet the
248 d_ino values for entries in / did not match those obtained
250 if (d == NULL && errno == 0 && use_d_ino)
253 rewinddir (dirstream);
254 d = __readdir (dirstream);
260 /* EOF on dirstream, which can mean e.g., that the current
261 directory has been removed. */
262 __set_errno (ENOENT);
265 if (d->d_name[0] == '.' &&
266 (d->d_name[1] == '\0' ||
267 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
272 bool match = (MATCHING_INO (d, thisino) || mount_point);
280 entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
282 /* Compute size needed for this file name, or for the file
283 name ".." in the same directory, whichever is larger.
284 Room for ".." might be needed the next time through
286 size_t name_alloc = _D_ALLOC_NAMLEN (d);
287 size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
289 if (filesize < dotlen)
290 goto memory_exhausted;
292 if (dotsize < filesize)
294 /* My, what a deep directory tree you have, Grandma. */
295 size_t newsize = MAX (filesize, dotsize * 2);
297 if (newsize < dotsize)
298 goto memory_exhausted;
301 dotlist = malloc (newsize);
316 memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
317 entry_status = __lstat (dotlist, &st);
319 /* We don't fail here if we cannot stat() a directory entry.
320 This can happen when (network) file systems fail. If this
321 entry is in fact the one we are looking for we will find
322 out soon as we reach the end of the directory without
323 having found anything. */
324 if (entry_status == 0 && S_ISDIR (st.st_mode)
325 && st.st_dev == thisdev && st.st_ino == thisino)
330 dirroom = dirp - dir;
331 namlen = _D_EXACT_NAMLEN (d);
333 if (dirroom <= namlen)
337 __set_errno (ERANGE);
343 size_t oldsize = allocated;
345 allocated += MAX (allocated, namlen);
346 if (allocated < oldsize
347 || ! (tmp = realloc (dir, allocated)))
348 goto memory_exhausted;
350 /* Move current contents up to the end of the buffer.
351 This is guaranteed to be non-overlapping. */
352 dirp = memcpy (tmp + allocated - (oldsize - dirroom),
359 memcpy (dirp, d->d_name, namlen);
366 if (dirstream && __closedir (dirstream) != 0)
372 if (dirp == &dir[allocated - 1])
380 used = dir + allocated - dirp;
381 memmove (dir, dirp, used);
383 if (buf == NULL && size == 0)
384 /* Ensure that the buffer is only as large as necessary. */
385 buf = realloc (dir, used);
388 /* Either buf was NULL all along, or `realloc' failed but
389 we still have the original string. */
395 __set_errno (ENOMEM);
400 __closedir (dirstream);
402 if (fd_needs_closing)
416 weak_alias (__getcwd, getcwd)