/* scandir.cc Written by Corinna Vinschen This file is part of Cygwin. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" #include #include #include "cygerrno.h" extern "C" int alphasort (const struct dirent **a, const struct dirent **b) { return strcoll ((*a)->d_name, (*b)->d_name); } extern "C" int versionsort (const struct dirent **a, const struct dirent **b) { return strverscmp ((*a)->d_name, (*b)->d_name); } extern "C" 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 err = 0; if (!(dirp = opendir (dir))) return -1; if (!compar) compar = alphasort; while ((ent = readdir (dirp))) { if (!select || select (ent)) { if (count == allocated) { if (allocated == 0) allocated = 10; else allocated *= 2; ntmp = (struct dirent **) realloc (nl, allocated * sizeof *nl); if (!ntmp) { err = ENOMEM; break; } nl = ntmp; } if (!(etmp = (struct dirent *) malloc (sizeof *ent))) { err = ENOMEM; break; } *etmp = *ent; nl[count++] = etmp; } } if (err != 0) { closedir (dirp); if (nl) { while (count > 0) free (nl[--count]); free (nl); } /* Ignore errors from closedir() and what not else. */ set_errno (err); return -1; } closedir (dirp); qsort (nl, count, sizeof *nl, (int (*)(const void *, const void *)) compar); *namelist = nl; return count; }