2008-11-24 Joel Sherrill <joel.sherrill@oarcorp.com>
* libc/posix/scandir.c: Fix memory leaks.
This commit is contained in:
parent
b45d16228b
commit
df913771a7
|
@ -1,3 +1,7 @@
|
||||||
|
2008-11-24 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||||
|
|
||||||
|
* libc/posix/scandir.c: Fix memory leaks.
|
||||||
|
|
||||||
2008-11-24 Joel Sherrill <joel.sherrill@oarcorp.com>
|
2008-11-24 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||||
|
|
||||||
* libc/posix/Makefile.am: Compile readdir_r.c
|
* libc/posix/Makefile.am: Compile readdir_r.c
|
||||||
|
|
|
@ -78,18 +78,25 @@ _DEFUN(scandir, (dirname, namelist, select, dcomp),
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
long arraysz;
|
long arraysz;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
|
int successful = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
dirp = NULL;
|
||||||
|
names = NULL;
|
||||||
|
|
||||||
if ((dirp = opendir(dirname)) == NULL)
|
if ((dirp = opendir(dirname)) == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
#ifdef HAVE_DD_LOCK
|
#ifdef HAVE_DD_LOCK
|
||||||
__lock_acquire_recursive(dirp->dd_lock);
|
__lock_acquire_recursive(dirp->dd_lock);
|
||||||
#endif
|
#endif
|
||||||
if (fstat(dirp->dd_fd, &stb) < 0) {
|
if (fstat(dirp->dd_fd, &stb) < 0)
|
||||||
#ifdef HAVE_DD_LOCK
|
goto cleanup;
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
|
||||||
#endif
|
/*
|
||||||
return(-1);
|
* If there were no directory entries, then bail.
|
||||||
}
|
*/
|
||||||
|
if (stb.st_size == 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* estimate the array size by taking the size of the directory file
|
* estimate the array size by taking the size of the directory file
|
||||||
|
@ -97,12 +104,8 @@ _DEFUN(scandir, (dirname, namelist, select, dcomp),
|
||||||
*/
|
*/
|
||||||
arraysz = (stb.st_size / 24);
|
arraysz = (stb.st_size / 24);
|
||||||
names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
|
names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
|
||||||
if (names == NULL) {
|
if (names == NULL)
|
||||||
#ifdef HAVE_DD_LOCK
|
goto cleanup;
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
|
||||||
#endif
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nitems = 0;
|
nitems = 0;
|
||||||
while ((d = readdir(dirp)) != NULL) {
|
while ((d = readdir(dirp)) != NULL) {
|
||||||
|
@ -112,12 +115,8 @@ _DEFUN(scandir, (dirname, namelist, select, dcomp),
|
||||||
* Make a minimum size copy of the data
|
* Make a minimum size copy of the data
|
||||||
*/
|
*/
|
||||||
p = (struct dirent *)malloc(DIRSIZ(d));
|
p = (struct dirent *)malloc(DIRSIZ(d));
|
||||||
if (p == NULL) {
|
if (p == NULL)
|
||||||
#ifdef HAVE_DD_LOCK
|
goto cleanup;
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
|
||||||
#endif
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
p->d_ino = d->d_ino;
|
p->d_ino = d->d_ino;
|
||||||
p->d_reclen = d->d_reclen;
|
p->d_reclen = d->d_reclen;
|
||||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||||
|
@ -131,32 +130,38 @@ _DEFUN(scandir, (dirname, namelist, select, dcomp),
|
||||||
* realloc the maximum size.
|
* realloc the maximum size.
|
||||||
*/
|
*/
|
||||||
if (++nitems >= arraysz) {
|
if (++nitems >= arraysz) {
|
||||||
if (fstat(dirp->dd_fd, &stb) < 0) {
|
if (fstat(dirp->dd_fd, &stb) < 0)
|
||||||
#ifdef HAVE_DD_LOCK
|
goto cleanup;
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
|
||||||
#endif
|
|
||||||
return(-1); /* just might have grown */
|
|
||||||
}
|
|
||||||
arraysz = stb.st_size / 12;
|
arraysz = stb.st_size / 12;
|
||||||
names = (struct dirent **)realloc((char *)names,
|
names = (struct dirent **)reallocf((char *)names,
|
||||||
arraysz * sizeof(struct dirent *));
|
arraysz * sizeof(struct dirent *));
|
||||||
if (names == NULL) {
|
if (names == NULL)
|
||||||
#ifdef HAVE_DD_LOCK
|
goto cleanup;
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
|
||||||
#endif
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
names[nitems-1] = p;
|
names[nitems-1] = p;
|
||||||
}
|
}
|
||||||
|
successful = 1;
|
||||||
|
cleanup:
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
if (nitems && dcomp != NULL)
|
if (successful) {
|
||||||
qsort(names, nitems, sizeof(struct dirent *), (void *)dcomp);
|
if (nitems && dcomp != NULL)
|
||||||
*namelist = names;
|
qsort(names, nitems, sizeof(struct dirent *), (void *)dcomp);
|
||||||
|
*namelist = names;
|
||||||
|
rc = nitems;
|
||||||
|
} else { /* We were unsuccessful, clean up storage and return -1. */
|
||||||
|
if ( names ) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i < nitems; i++ )
|
||||||
|
free( names[i] );
|
||||||
|
free( names );
|
||||||
|
}
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DD_LOCK
|
#ifdef HAVE_DD_LOCK
|
||||||
__lock_release_recursive(dirp->dd_lock);
|
__lock_release_recursive(dirp->dd_lock);
|
||||||
#endif
|
#endif
|
||||||
return(nitems);
|
return(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue