1 |
/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004 Free Software Foundation, |
/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005 Free Software |
2 |
Inc. |
Foundation, Inc. |
3 |
This file is part of the GNU C Library. |
This file is part of the GNU C Library. |
4 |
|
|
5 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
14 |
|
|
15 |
You should have received a copy of the GNU General Public License along |
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, |
with this program; if not, write to the Free Software Foundation, |
17 |
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
18 |
|
|
19 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
20 |
# include "config.h" |
# include "config.h" |
114 |
# define __readdir readdir |
# define __readdir readdir |
115 |
#endif |
#endif |
116 |
|
|
117 |
/* Get the pathname of the current working directory, and put it in SIZE |
/* 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 |
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 |
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, |
NULL, an array is allocated with `malloc'; the array is SIZE bytes long, |
147 |
DIR *dirstream = NULL; |
DIR *dirstream = NULL; |
148 |
dev_t rootdev, thisdev; |
dev_t rootdev, thisdev; |
149 |
ino_t rootino, thisino; |
ino_t rootino, thisino; |
150 |
char *path; |
char *dir; |
151 |
register char *pathp; |
register char *dirp; |
152 |
struct stat st; |
struct stat st; |
153 |
size_t allocated = size; |
size_t allocated = size; |
154 |
size_t used; |
size_t used; |
161 |
So trust the system getcwd's results unless they look |
So trust the system getcwd's results unless they look |
162 |
suspicious. */ |
suspicious. */ |
163 |
# undef getcwd |
# undef getcwd |
164 |
path = getcwd (buf, size); |
dir = getcwd (buf, size); |
165 |
if (path || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT)) |
if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT)) |
166 |
return path; |
return dir; |
167 |
#endif |
#endif |
168 |
|
|
169 |
if (size == 0) |
if (size == 0) |
179 |
|
|
180 |
if (buf == NULL) |
if (buf == NULL) |
181 |
{ |
{ |
182 |
path = malloc (allocated); |
dir = malloc (allocated); |
183 |
if (path == NULL) |
if (dir == NULL) |
184 |
return NULL; |
return NULL; |
185 |
} |
} |
186 |
else |
else |
187 |
path = buf; |
dir = buf; |
188 |
|
|
189 |
pathp = path + allocated; |
dirp = dir + allocated; |
190 |
*--pathp = '\0'; |
*--dirp = '\0'; |
191 |
|
|
192 |
if (__lstat (".", &st) < 0) |
if (__lstat (".", &st) < 0) |
193 |
goto lose; |
goto lose; |
318 |
} |
} |
319 |
else |
else |
320 |
{ |
{ |
321 |
size_t pathroom = pathp - path; |
size_t dirroom = dirp - dir; |
322 |
size_t namlen = _D_EXACT_NAMLEN (d); |
size_t namlen = _D_EXACT_NAMLEN (d); |
323 |
|
|
324 |
if (pathroom <= namlen) |
if (dirroom <= namlen) |
325 |
{ |
{ |
326 |
if (size != 0) |
if (size != 0) |
327 |
{ |
{ |
335 |
|
|
336 |
allocated += MAX (allocated, namlen); |
allocated += MAX (allocated, namlen); |
337 |
if (allocated < oldsize |
if (allocated < oldsize |
338 |
|| ! (tmp = realloc (path, allocated))) |
|| ! (tmp = realloc (dir, allocated))) |
339 |
goto memory_exhausted; |
goto memory_exhausted; |
340 |
|
|
341 |
/* Move current contents up to the end of the buffer. |
/* Move current contents up to the end of the buffer. |
342 |
This is guaranteed to be non-overlapping. */ |
This is guaranteed to be non-overlapping. */ |
343 |
pathp = memcpy (tmp + allocated - (oldsize - pathroom), |
dirp = memcpy (tmp + allocated - (oldsize - dirroom), |
344 |
tmp + pathroom, |
tmp + dirroom, |
345 |
oldsize - pathroom); |
oldsize - dirroom); |
346 |
path = tmp; |
dir = tmp; |
347 |
} |
} |
348 |
} |
} |
349 |
pathp -= namlen; |
dirp -= namlen; |
350 |
memcpy (pathp, d->d_name, namlen); |
memcpy (dirp, d->d_name, namlen); |
351 |
*--pathp = '/'; |
*--dirp = '/'; |
352 |
} |
} |
353 |
|
|
354 |
thisdev = dotdev; |
thisdev = dotdev; |
361 |
goto lose; |
goto lose; |
362 |
} |
} |
363 |
|
|
364 |
if (pathp == &path[allocated - 1]) |
if (dirp == &dir[allocated - 1]) |
365 |
*--pathp = '/'; |
*--dirp = '/'; |
366 |
|
|
367 |
#ifndef AT_FDCWD |
#ifndef AT_FDCWD |
368 |
if (dotlist != dots) |
if (dotlist != dots) |
369 |
free (dotlist); |
free (dotlist); |
370 |
#endif |
#endif |
371 |
|
|
372 |
used = path + allocated - pathp; |
used = dir + allocated - dirp; |
373 |
memmove (path, pathp, used); |
memmove (dir, dirp, used); |
374 |
|
|
375 |
if (buf == NULL && size == 0) |
if (buf == NULL && size == 0) |
376 |
/* Ensure that the buffer is only as large as necessary. */ |
/* Ensure that the buffer is only as large as necessary. */ |
377 |
buf = realloc (path, used); |
buf = realloc (dir, used); |
378 |
|
|
379 |
if (buf == NULL) |
if (buf == NULL) |
380 |
/* Either buf was NULL all along, or `realloc' failed but |
/* Either buf was NULL all along, or `realloc' failed but |
381 |
we still have the original string. */ |
we still have the original string. */ |
382 |
buf = path; |
buf = dir; |
383 |
|
|
384 |
return buf; |
return buf; |
385 |
|
|
398 |
free (dotlist); |
free (dotlist); |
399 |
#endif |
#endif |
400 |
if (buf == NULL) |
if (buf == NULL) |
401 |
free (path); |
free (dir); |
402 |
__set_errno (save); |
__set_errno (save); |
403 |
} |
} |
404 |
return NULL; |
return NULL; |