Package: libnih / 1.0.3-11

0001-Fallback-to-lstat-if-dirent.d_type-is-not-available-.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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);
 	}