File libnih-lstat-fallback.patch of Package libnih
Description: Fallback to lstat if dirent.d_-ype is not available (fixes non-ext filesystems)
Author: Dmitrijs Ledkovs <xnox@debian.org>
Forwarded: https://code.launchpad.net/~xnox/libnih/fix-672643
Last-Update: 2012-12-17
---
--- a/nih/file.c
+++ b/nih/file.c
@@ -619,6 +619,8 @@ nih_dir_walk_scan (const char *path,
struct dirent *ent;
char **paths;
size_t npaths;
+ int isdir;
+ struct stat statbuf;
nih_assert (path != NULL);
@@ -640,7 +642,15 @@ nih_dir_walk_scan (const char *path,
subpath = NIH_MUST (nih_sprintf (NULL, "%s/%s",
path, ent->d_name));
- if (filter && filter (data, subpath, ent->d_type == DT_DIR))
+ if (ent->d_type == DT_UNKNOWN) {
+ if ( lstat (subpath, &statbuf))
+ isdir = 0;
+ else
+ isdir = S_ISDIR(statbuf.st_mode);
+ } else
+ isdir = ent->d_type == DT_DIR;
+
+ if (filter && filter (data, subpath, isdir))
continue;
NIH_MUST (nih_str_array_addp (&paths, NULL, &npaths, subpath));
--- a/nih/tests/test_file.c
+++ b/nih/tests/test_file.c
@@ -724,6 +724,25 @@ my_filter (void *data,
return FALSE;
}
+/* find only frodo files */
+static int
+my_filter_frodo_file (void *data,
+ const char *path,
+ int is_dir)
+{
+ char *slash;
+
+ if (is_dir)
+ return FALSE;
+
+ slash = strrchr (path, '/');
+ if (strcmp (slash, "/frodo"))
+ return TRUE;
+
+ return FALSE;
+}
+
+
static int logger_called = 0;
static int
@@ -905,6 +924,48 @@ test_dir_walk (void)
TEST_EQ_STR (v->path, filename);
nih_free (visited);
+
+ /* Try also inverse filter */
+ TEST_ALLOC_SAFE {
+ visitor_called = 0;
+ visited = nih_list_new (NULL);
+ }
+
+ ret = nih_dir_walk (dirname, my_filter_frodo_file,
+ my_visitor, NULL, &ret);
+
+ TEST_EQ (ret, 0);
+ TEST_EQ (visitor_called, 4);
+
+ v = (Visited *)visited->next;
+ TEST_EQ (v->data, &ret);
+ TEST_EQ_STR (v->dirname, dirname);
+ strcpy (filename, dirname);
+ strcat (filename, "/bar");
+ TEST_EQ_STR (v->path, filename);
+
+ v = (Visited *)v->entry.next;
+ TEST_EQ (v->data, &ret);
+ TEST_EQ_STR (v->dirname, dirname);
+ strcpy (filename, dirname);
+ strcat (filename, "/bar/frodo");
+ TEST_EQ_STR (v->path, filename);
+
+ v = (Visited *)v->entry.next;
+ TEST_EQ (v->data, &ret);
+ TEST_EQ_STR (v->dirname, dirname);
+ strcpy (filename, dirname);
+ strcat (filename, "/baz");
+ TEST_EQ_STR (v->path, filename);
+
+ v = (Visited *)v->entry.next;
+ TEST_EQ (v->data, &ret);
+ TEST_EQ_STR (v->dirname, dirname);
+ strcpy (filename, dirname);
+ strcat (filename, "/frodo");
+ TEST_EQ_STR (v->path, filename);
+
+ nih_free (visited);
}