mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-07-25 10:16:53 +02:00
(__getcwd): Don't assume that system calls after readdir
leave errno alone. Problem reported by Dmitry V. Levin.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2005-10-29 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* getcwd.c (__getcwd): Don't assume that system calls after readdir
|
||||
leave errno alone. Problem reported by Dmitry V. Levin.
|
||||
|
||||
2005-10-28 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* savedir.c (savedir): Don't assume that xrealloc etc. leave
|
||||
|
||||
+43
-42
@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size)
|
||||
ino_t dotino;
|
||||
bool mount_point;
|
||||
int parent_status;
|
||||
size_t dirroom;
|
||||
size_t namlen;
|
||||
|
||||
/* Look at the parent directory. */
|
||||
#ifdef AT_FDCWD
|
||||
@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size)
|
||||
goto lose;
|
||||
dotlist[dotlen++] = '/';
|
||||
#endif
|
||||
/* Clear errno to distinguish EOF from error if readdir returns
|
||||
NULL. */
|
||||
__set_errno (0);
|
||||
while ((d = __readdir (dirstream)) != NULL)
|
||||
for (;;)
|
||||
{
|
||||
/* Clear errno to distinguish EOF from error if readdir returns
|
||||
NULL. */
|
||||
__set_errno (0);
|
||||
d = __readdir (dirstream);
|
||||
if (d == NULL)
|
||||
{
|
||||
if (errno == 0)
|
||||
/* EOF on dirstream, which means that the current directory
|
||||
has been removed. */
|
||||
__set_errno (ENOENT);
|
||||
goto lose;
|
||||
}
|
||||
if (d->d_name[0] == '.' &&
|
||||
(d->d_name[1] == '\0' ||
|
||||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
||||
@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == NULL)
|
||||
{
|
||||
if (errno == 0)
|
||||
/* EOF on dirstream, which means that the current directory
|
||||
has been removed. */
|
||||
__set_errno (ENOENT);
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t dirroom = dirp - dir;
|
||||
size_t namlen = _D_EXACT_NAMLEN (d);
|
||||
|
||||
if (dirroom <= namlen)
|
||||
dirroom = dirp - dir;
|
||||
namlen = _D_EXACT_NAMLEN (d);
|
||||
|
||||
if (dirroom <= namlen)
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
size_t oldsize = allocated;
|
||||
|
||||
allocated += MAX (allocated, namlen);
|
||||
if (allocated < oldsize
|
||||
|| ! (tmp = realloc (dir, allocated)))
|
||||
goto memory_exhausted;
|
||||
|
||||
/* Move current contents up to the end of the buffer.
|
||||
This is guaranteed to be non-overlapping. */
|
||||
dirp = memcpy (tmp + allocated - (oldsize - dirroom),
|
||||
tmp + dirroom,
|
||||
oldsize - dirroom);
|
||||
dir = tmp;
|
||||
}
|
||||
__set_errno (ERANGE);
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
size_t oldsize = allocated;
|
||||
|
||||
allocated += MAX (allocated, namlen);
|
||||
if (allocated < oldsize
|
||||
|| ! (tmp = realloc (dir, allocated)))
|
||||
goto memory_exhausted;
|
||||
|
||||
/* Move current contents up to the end of the buffer.
|
||||
This is guaranteed to be non-overlapping. */
|
||||
dirp = memcpy (tmp + allocated - (oldsize - dirroom),
|
||||
tmp + dirroom,
|
||||
oldsize - dirroom);
|
||||
dir = tmp;
|
||||
}
|
||||
dirp -= namlen;
|
||||
memcpy (dirp, d->d_name, namlen);
|
||||
*--dirp = '/';
|
||||
}
|
||||
dirp -= namlen;
|
||||
memcpy (dirp, d->d_name, namlen);
|
||||
*--dirp = '/';
|
||||
|
||||
thisdev = dotdev;
|
||||
thisino = dotino;
|
||||
|
||||
Reference in New Issue
Block a user