aboutsummaryrefslogtreecommitdiff
path: root/include/dirent.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/dirent.h')
-rw-r--r--include/dirent.h78
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
}