util/disk_cache: use stat() to check if entry is a directory
authorTimothy Arceri <tarceri@itsqueeze.com>
Wed, 8 Feb 2017 04:05:19 +0000 (15:05 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Fri, 10 Feb 2017 12:50:36 +0000 (23:50 +1100)
d_type is not supported on all systems.

Tested-by: Vinson Lee <vlee@freedesktop.org>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97967

src/util/disk_cache.c

index c4d08d1ce9ed231fec5f64610946d6ca8f479e0d..42fe432b8c4cb8931152adf91dc5b445eecaaa87 100644 (file)
@@ -375,7 +375,8 @@ make_cache_file_directory(struct disk_cache *cache, cache_key key)
  */
 static char *
 choose_random_file_matching(const char *dir_path,
-                            bool (*predicate)(struct dirent *))
+                            bool (*predicate)(struct dirent *,
+                                              const char *dir_path))
 {
    DIR *dir;
    struct dirent *entry;
@@ -392,7 +393,7 @@ choose_random_file_matching(const char *dir_path,
       entry = readdir(dir);
       if (entry == NULL)
          break;
-      if (! predicate(entry))
+      if (!predicate(entry, dir_path))
          continue;
 
       count++;
@@ -412,7 +413,7 @@ choose_random_file_matching(const char *dir_path,
       entry = readdir(dir);
       if (entry == NULL)
          break;
-      if (! predicate(entry))
+      if (!predicate(entry, dir_path))
          continue;
       if (count == victim)
          break;
@@ -437,14 +438,20 @@ choose_random_file_matching(const char *dir_path,
  * ".tmp"
  */
 static bool
-is_regular_non_tmp_file(struct dirent *entry)
+is_regular_non_tmp_file(struct dirent *entry, const char *path)
 {
-   size_t len;
+   char *filename;
+   if (asprintf(&filename, "%s/%s", path, entry->d_name) == -1)
+      return false;
+
+   struct stat sb;
+   stat(filename, &sb);
+   free(filename);
 
-   if (entry->d_type != DT_REG)
+   if (!S_ISREG(sb.st_mode))
       return false;
 
-   len = strlen (entry->d_name);
+   size_t len = strlen (entry->d_name);
    if (len >= 4 && strcmp(&entry->d_name[len-4], ".tmp") == 0)
       return false;
 
@@ -478,9 +485,17 @@ unlink_random_file_from_directory(const char *path)
  * special name of "..")
  */
 static bool
-is_two_character_sub_directory(struct dirent *entry)
+is_two_character_sub_directory(struct dirent *entry, const char *path)
 {
-   if (entry->d_type != DT_DIR)
+   char *subdir;
+   if (asprintf(&subdir, "%s/%s", path, entry->d_name) == -1)
+      return false;
+
+   struct stat sb;
+   stat(path, &sb);
+   free(subdir);
+
+   if (!S_ISDIR(sb.st_mode))
       return false;
 
    if (strlen(entry->d_name) != 2)