nih_dir_walk_scan passes incorrect value to file filter
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
libnih |
Triaged
|
Undecided
|
Unassigned | ||
libnih (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
nih_watch_new() accepts a generic data pointer which is supposed to be passed to the create/
1. When nih_watch_new() is called, it creates a new NihWatch object and sets "watch->data = data".
2. nih_watch_
3. nih_watch_add calls nih_dir_walk(path, filter=
(Note that "data=watch" here).
4. nih_dir_walk() calls nih_dir_
5. BUG: nih_dir_walk_scan() calls filter(data=watch).
6. nih_dir_walk() then calls nih_dir_
7. nih_dir_
nih_
Step 5 is incorrect. nih_dir_walk_scan() *should* call:
filter(
However, it cannot since nih_dir_walk_scan knows nothing about NihWatches. The design issue comes down to the fact that the data pointer passed to nih_dir_walk() needs to be an NihWatch so it can be passed to nih_watch_
One possible solution would be to have *two* generic pointers passed to nih_dir_walk: one for the NihFileVisitor handler and the other for the NihFileFilter handler such that we would have something like:
int
nih_dir_walk (const char *path,
void *visitor_data,
void *filter_data)
{
:
filter (filter_data);
:
visitor (visitor_data);
:
}
Related branches
- Steve Langasek: Disapprove
-
Diff: 167 lines (+102/-1)3 files modifiedChangeLog (+10/-0)
nih/file.c (+32/-1)
nih/tests/test_watch.c (+60/-0)
- Steve Langasek (community): Disapprove
- Scott James Remnant: Approve
-
Diff: 167 lines (+102/-1)3 files modifiedChangeLog (+10/-0)
nih/file.c (+32/-1)
nih/tests/test_watch.c (+60/-0)
- James Hunt: Approve
-
Diff: 171 lines (+106/-1) (has conflicts)3 files modifiedChangeLog (+13/-0)
nih/tests/test_watch.c (+60/-0)
nih/watch.c (+33/-1)
- Scott James Remnant: Pending requested
-
Diff: 161 lines (+103/-1)3 files modifiedChangeLog (+10/-0)
nih/tests/test_watch.c (+60/-0)
nih/watch.c (+33/-1)
(as discussed today)
I see the problem; there are, as you say, two data pointers here; nih_dir_walk_scan() needs its data pointer passed to its visitor function, but is passing an external filter from the watch which needs an entirely different data pointer (from the watch).
The right fix without busting API would be to change step 4
nih_dir_walk() should pass filter= nih_dir_ walk_filter, a new static function that expects data=watch
that static function then simply calls
return watch->filter (watch->data, ...)
passing in the rest of the arguments.
That way data=watch is passed to both nih_dir_walk()s filter and visit, and the special filter translates it to the watch's filter passing in the watch's data