Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include <dirent.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <stddef.h>
  6.  
  7. #define SIZE_MAX 256
  8.  
  9. int scandir(const char *path, struct dirent ***res,
  10.         int (*sel)(const struct dirent *),
  11.         int (*cmp)(const struct dirent **, const struct dirent **))
  12. {
  13.         DIR *d = opendir(path);
  14.         struct dirent *de, **names=0, **tmp;
  15.         size_t cnt=0, len=0;
  16.         int old_errno = errno;
  17.  
  18.         if (!d) return -1;
  19.  
  20.         while ((errno=0), (de = readdir(d))) {
  21.                 if (sel && !sel(de)) continue;
  22.                 if (cnt >= len) {
  23.                         len = 2*len+1;
  24.                         if (len > SIZE_MAX/sizeof *names) break;
  25.                         tmp = realloc(names, len * sizeof *names);
  26.                         if (!tmp) break;
  27.                         names = tmp;
  28.                 }
  29.                 names[cnt] = malloc(sizeof(struct dirent));
  30.                 if (!names[cnt]) break;
  31.                 memcpy(names[cnt++], de, sizeof(struct dirent));
  32.         }
  33.  
  34.         closedir(d);
  35.  
  36.         if (errno) {
  37.                 if (names) while (cnt-->0) free(names[cnt]);
  38.                 free(names);
  39.                 return -1;
  40.         }
  41.         errno = old_errno;
  42.  
  43.         if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
  44.         *res = names;
  45.         return cnt;
  46. }
  47.