diff options
Diffstat (limited to 'include/dirent.h')
-rw-r--r-- | include/dirent.h | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/include/dirent.h b/include/dirent.h index 39ff0f38f..4c0f36b0c 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -177,7 +177,7 @@ static void rewinddir(DIR* dirp); /* Set errno variable */ #if defined(_MSC_VER) -#define DIRENT_SET_ERRNO(x) _set_errno (x) +#define DIRENT_SET_ERRNO(x) _set_errno(x) #else #define DIRENT_SET_ERRNO(x) (errno = (x)) #endif @@ -357,6 +357,82 @@ static void rewinddir(DIR* dirp) } } +static int +scandir (const char *dir, + struct dirent ***namelist, + int (*select) (const struct dirent *), + int (*compar) (const struct dirent **, const struct dirent **)) +{ + DIR *dirp; + struct dirent *ent, *etmp, **nl = NULL, **ntmp; + int count = 0; + int allocated = 0; + int prior_errno; + + if (!(dirp = opendir (dir))) + return -1; + + _get_errno(&prior_errno); + _set_errno(0); + + while ((ent = readdir (dirp))) + { + if (!select || select (ent)) + { + + /* Ignore error from readdir/select. See POSIX specs. */ + _set_errno(0); + + if (count == allocated) + { + + if (allocated == 0) + allocated = 10; + else + allocated *= 2; + + ntmp = (struct dirent **) realloc (nl, allocated * sizeof *nl); + if (!ntmp) + { + _set_errno(ENOMEM); + break; + } + nl = ntmp; + } + + if (!(etmp = (struct dirent *) malloc (sizeof *ent))) + { + _set_errno(ENOMEM); + break; + } + *etmp = *ent; + nl[count++] = etmp; + } + } + + _get_errno(&prior_errno); + if (prior_errno != 0) + { + closedir (dirp); + if (nl) + { + while (count > 0) + free (nl[--count]); + free (nl); + } + /* Ignore errors from closedir() and what not else. */ + _set_errno(prior_errno); + return -1; + } + + closedir (dirp); + _set_errno(prior_errno); + + qsort (nl, count, sizeof *nl, (int (*)(const void *, const void *)) compar); + if (namelist) + *namelist = nl; + return count; +} #ifdef __cplusplus } |