diff --git a/nih/file.c b/nih/file.c index eda3f7b..108aec2 100644 --- a/nih/file.c +++ b/nih/file.c @@ -619,6 +619,7 @@ nih_dir_walk_scan (const char *path, struct dirent *ent; char **paths; size_t npaths; + struct stat statbuf; nih_assert (path != NULL); @@ -640,7 +641,9 @@ 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)) + lstat (subpath, &statbuf); + + if (filter && filter (data, subpath, S_ISDIR(statbuf.st_mode))) continue; NIH_MUST (nih_str_array_addp (&paths, NULL, &npaths, subpath)); diff --git a/nih/tests/test_file.c b/nih/tests/test_file.c index a40eca3..b62dbae 100644 --- 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); }