Mercurial > hg > octave-nkf > gnulib-hg
changeset 6439:3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
leave errno alone.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sun, 30 Oct 2005 01:32:04 +0000 |
parents | f9d5ad5c44c0 |
children | d811a65bfa7a |
files | lib/ChangeLog lib/getcwd.c |
diffstat | 2 files changed, 47 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -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
--- a/lib/getcwd.c +++ b/lib/getcwd.c @@ -201,6 +201,8 @@ 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 @@ 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 @@ break; } } - if (d == NULL) + + dirroom = dirp - dir; + namlen = _D_EXACT_NAMLEN (d); + + if (dirroom <= namlen) { - 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) + if (size != 0) + { + __set_errno (ERANGE); + goto lose; + } + else { - if (size != 0) - { - __set_errno (ERANGE); - goto lose; - } - else - { - char *tmp; - size_t oldsize = allocated; + char *tmp; + size_t oldsize = allocated; + + allocated += MAX (allocated, namlen); + if (allocated < oldsize + || ! (tmp = realloc (dir, allocated))) + goto memory_exhausted; - 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; - } + /* 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;