Merge lp:~xnox/ubuntu/raring/libnih/fix-xfs into lp:ubuntu/raring/libnih

Proposed by Dimitri John Ledkov
Status: Merged
Merged at revision: 1068
Proposed branch: lp:~xnox/ubuntu/raring/libnih/fix-xfs
Merge into: lp:ubuntu/raring/libnih
Diff against target: 122 lines (+80/-1)
3 files modified
debian/changelog (+8/-0)
nih/file.c (+11/-1)
nih/tests/test_file.c (+61/-0)
To merge this branch: bzr merge lp:~xnox/ubuntu/raring/libnih/fix-xfs
Reviewer Review Type Date Requested Status
Upstart Developers Pending
Upstart Developers Pending
Review via email: mp+139065@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

I have tested this on ubuntu & debian and it fixes the referenced bugs.
But I still would like a second review before pushing to lp:ubuntu/libnih.

Revision history for this message
Steve Langasek (vorlon) wrote :

The main concern I have here is that we're not checking the return value of lstat, which means statbuf may be uninitialized and yield random behavior. If lstat() fails, we should assume it's not a directory.

The other consideration is that having to do an lstat for each entry just to check if it's a directory makes this walk a bit more expensive. According to readdir(3), if d_type isn't supported, its value should be set to DT_UNKNOWN. What about calling lstat *iff* d_type == DT_UNKNOWN? This would keep this speedy in the common case, but address the problem of portability to other filesystems.

1069. By Dimitri John Ledkov

use lstat, if d_type is not present

1070. By Dimitri John Ledkov

Check lstat return code

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

I like your suggestion. d_type indeed is set to DT_UNKNOWN on xfs. Implemented your suggestions and tested on ext4 & xfs. All tests pass.

1071. By Dimitri John Ledkov

Update changelog entry

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2012-10-25 10:57:30 +0000
3+++ debian/changelog 2012-12-11 11:12:26 +0000
4@@ -1,3 +1,11 @@
5+libnih (1.0.3-4ubuntu13) UNRELEASED; urgency=low
6+
7+ [ Petr Lautrbach <plautrba@redhat.com>, Dmitrijs Ledkovs ]
8+ * Fallback to lstat, if dirent.d_type is not available (not portable)
9+ (LP: #672643) (Closes: #695604)
10+
11+ -- Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> Mon, 10 Dec 2012 18:13:28 +0000
12+
13 libnih (1.0.3-4ubuntu12) raring; urgency=low
14
15 * nih/logging.c: Use our own __nih_abort_msg rather than the (e)glibc
16
17=== modified file 'nih/file.c'
18--- nih/file.c 2010-02-04 22:30:23 +0000
19+++ nih/file.c 2012-12-11 11:12:26 +0000
20@@ -619,6 +619,8 @@
21 struct dirent *ent;
22 char **paths;
23 size_t npaths;
24+ int isdir;
25+ struct stat statbuf;
26
27 nih_assert (path != NULL);
28
29@@ -640,7 +642,15 @@
30 subpath = NIH_MUST (nih_sprintf (NULL, "%s/%s",
31 path, ent->d_name));
32
33- if (filter && filter (data, subpath, ent->d_type == DT_DIR))
34+ if (ent->d_type == DT_UNKNOWN) {
35+ if ( lstat (subpath, &statbuf))
36+ isdir = 0;
37+ else
38+ isdir = S_ISDIR(statbuf.st_mode);
39+ } else
40+ isdir = ent->d_type == DT_DIR;
41+
42+ if (filter && filter (data, subpath, isdir))
43 continue;
44
45 NIH_MUST (nih_str_array_addp (&paths, NULL, &npaths, subpath));
46
47=== modified file 'nih/tests/test_file.c'
48--- nih/tests/test_file.c 2010-02-04 22:30:23 +0000
49+++ nih/tests/test_file.c 2012-12-11 11:12:26 +0000
50@@ -724,6 +724,25 @@
51 return FALSE;
52 }
53
54+/* find only frodo files */
55+static int
56+my_filter_frodo_file (void *data,
57+ const char *path,
58+ int is_dir)
59+{
60+ char *slash;
61+
62+ if (is_dir)
63+ return FALSE;
64+
65+ slash = strrchr (path, '/');
66+ if (strcmp (slash, "/frodo"))
67+ return TRUE;
68+
69+ return FALSE;
70+}
71+
72+
73 static int logger_called = 0;
74
75 static int
76@@ -905,6 +924,48 @@
77 TEST_EQ_STR (v->path, filename);
78
79 nih_free (visited);
80+
81+ /* Try also inverse filter */
82+ TEST_ALLOC_SAFE {
83+ visitor_called = 0;
84+ visited = nih_list_new (NULL);
85+ }
86+
87+ ret = nih_dir_walk (dirname, my_filter_frodo_file,
88+ my_visitor, NULL, &ret);
89+
90+ TEST_EQ (ret, 0);
91+ TEST_EQ (visitor_called, 4);
92+
93+ v = (Visited *)visited->next;
94+ TEST_EQ (v->data, &ret);
95+ TEST_EQ_STR (v->dirname, dirname);
96+ strcpy (filename, dirname);
97+ strcat (filename, "/bar");
98+ TEST_EQ_STR (v->path, filename);
99+
100+ v = (Visited *)v->entry.next;
101+ TEST_EQ (v->data, &ret);
102+ TEST_EQ_STR (v->dirname, dirname);
103+ strcpy (filename, dirname);
104+ strcat (filename, "/bar/frodo");
105+ TEST_EQ_STR (v->path, filename);
106+
107+ v = (Visited *)v->entry.next;
108+ TEST_EQ (v->data, &ret);
109+ TEST_EQ_STR (v->dirname, dirname);
110+ strcpy (filename, dirname);
111+ strcat (filename, "/baz");
112+ TEST_EQ_STR (v->path, filename);
113+
114+ v = (Visited *)v->entry.next;
115+ TEST_EQ (v->data, &ret);
116+ TEST_EQ_STR (v->dirname, dirname);
117+ strcpy (filename, dirname);
118+ strcat (filename, "/frodo");
119+ TEST_EQ_STR (v->path, filename);
120+
121+ nih_free (visited);
122 }
123
124

Subscribers

People subscribed via source and target branches