Fix readdir(3) not preserving errno in case of end-of-directory condition.
This commit is contained in:
parent
1e671aa8cd
commit
71f9f882d1
|
@ -30,42 +30,30 @@
|
||||||
|
|
||||||
extern "C" struct dirent* readdir(DIR* dir)
|
extern "C" struct dirent* readdir(DIR* dir)
|
||||||
{
|
{
|
||||||
|
int old_errno = errno;
|
||||||
|
|
||||||
if ( !dir->read_func )
|
if ( !dir->read_func )
|
||||||
{
|
return dir->flags |= _DIR_ERROR, errno = EBADF, (struct dirent*) NULL;
|
||||||
dir->flags |= _DIR_ERROR;
|
|
||||||
errno = EBADF;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = dir->entrysize;
|
size_t size = dir->entrysize;
|
||||||
int status = dir->read_func(dir->user, dir->entry, &size);
|
int status;
|
||||||
if ( status < 0 )
|
while ( 0 < (status = dir->read_func(dir->user, dir->entry, &size)) )
|
||||||
{
|
|
||||||
dir->flags |= _DIR_ERROR;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 < status )
|
|
||||||
{
|
{
|
||||||
struct dirent* biggerdir = (struct dirent*) malloc(size);
|
struct dirent* biggerdir = (struct dirent*) malloc(size);
|
||||||
if ( !biggerdir )
|
if ( !biggerdir )
|
||||||
{
|
return dir->flags |= _DIR_ERROR, (struct dirent*) NULL;
|
||||||
dir->flags |= _DIR_ERROR;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
free(dir->entry);
|
free(dir->entry);
|
||||||
dir->entry = biggerdir;
|
dir->entry = biggerdir;
|
||||||
dir->entrysize = size;
|
dir->entrysize = size;
|
||||||
return readdir(dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( status < 0 )
|
||||||
|
return dir->flags |= _DIR_ERROR, (struct dirent*) NULL;
|
||||||
|
|
||||||
dir->flags &= ~_DIR_ERROR;
|
dir->flags &= ~_DIR_ERROR;
|
||||||
|
|
||||||
if ( !dir->entry->d_name[0] )
|
if ( !dir->entry->d_name[0] )
|
||||||
{
|
return dir->flags |= _DIR_EOF, errno = old_errno, (struct dirent*) NULL;
|
||||||
dir->flags |= _DIR_EOF;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir->entry;
|
return dir->entry;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue