inotify-map.c: return a copy of a path list in lookup functions.
Becouse it is possible to change the a list stored by the API while traversing it, a bug can couse a infinite loop. lets be strict about this and only return a copy of the list, so it can't be changed by calls to the API.
This commit is contained in:
parent
33ceeca315
commit
440e5ed7d2
4 changed files with 22 additions and 17 deletions
|
|
@ -148,13 +148,13 @@ int inotify_map_get_wd(const char *path) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct str_list* inotify_map_lookup(int wd) {
|
||||
|
||||
char** inotify_map_lookup(int wd) {
|
||||
|
||||
struct map_wd *m = rbtree_search(&tree_wd_paths, &wd);
|
||||
return m ? &m->paths : NULL;
|
||||
return m ? str_list_export(&m->paths) : NULL;
|
||||
}
|
||||
|
||||
const struct str_list* inotify_map_lookup_by_path(const char *path) {
|
||||
char** inotify_map_lookup_by_path(const char *path) {
|
||||
|
||||
struct map_path *p = rbtree_search(&tree_path_wd, &path);
|
||||
return p ? inotify_map_lookup(p->wd) : NULL;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ void inotify_unmap_all();
|
|||
|
||||
int inotify_map_get_wd(const char *path);
|
||||
|
||||
const struct str_list* inotify_map_lookup(int wd);
|
||||
char** inotify_map_lookup(int wd);
|
||||
|
||||
const struct str_list* inotify_map_lookup_by_path(const char *path);
|
||||
char** inotify_map_lookup_by_path(const char *path);
|
||||
|
||||
int inotify_map_isempty();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ static int addwatch(const char *path, const char *name, unsigned recursive) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
inotify_map(wd, npath);
|
||||
|
||||
logmsg(LOG_DEBUG, "added wd = %i on %s", wd, npath);
|
||||
|
||||
if (recursive) {
|
||||
|
|
@ -89,6 +87,7 @@ static int addwatch(const char *path, const char *name, unsigned recursive) {
|
|||
}
|
||||
fsc_close(f);
|
||||
}
|
||||
inotify_map(wd, npath);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -123,8 +122,7 @@ static int rmwatch(const char *path, const char *name) {
|
|||
|
||||
static void proc_event(inoev *iev) {
|
||||
|
||||
const struct str_list *paths;
|
||||
char **path;
|
||||
char **paths, **path;
|
||||
int isdir;
|
||||
|
||||
logmsg(LOG_DEBUG, "RAW EVENT: %i, %x, %s", iev->wd, iev->mask, iev->name);
|
||||
|
|
@ -146,7 +144,7 @@ static void proc_event(inoev *iev) {
|
|||
isdir = (iev->mask & IN_ISDIR) != 0;
|
||||
iev->mask &= ~IN_ISDIR;
|
||||
|
||||
str_list_foreach(path, paths) {
|
||||
for(path = paths; *path; path++) {
|
||||
|
||||
uint8_t type = NOTIFY_UNKNOWN;
|
||||
notify_event *event = notify_event_new();
|
||||
|
|
@ -163,7 +161,7 @@ static void proc_event(inoev *iev) {
|
|||
case IN_CREATE :
|
||||
if (event->dir) {
|
||||
logmsg(LOG_DEBUG, "IN_CREATE on directory, adding");
|
||||
addwatch(event->path, event->filename, 0);
|
||||
addwatch(event->path, event->filename, 1);
|
||||
}
|
||||
type = NOTIFY_CREATE;
|
||||
break;
|
||||
|
|
@ -184,6 +182,8 @@ static void proc_event(inoev *iev) {
|
|||
|
||||
event->type = type;
|
||||
}
|
||||
|
||||
free(paths);
|
||||
}
|
||||
|
||||
int notify_init() {
|
||||
|
|
|
|||
|
|
@ -22,18 +22,23 @@ static void teardown() {
|
|||
inotify_unmap_all();
|
||||
}
|
||||
|
||||
static void validate_list(int refindex, const struct str_list *l) {
|
||||
static void validate_list(int index, char **list) {
|
||||
|
||||
int i;
|
||||
|
||||
assert(l);
|
||||
assert(list);
|
||||
|
||||
for(i=0; i < 4; i++) {
|
||||
|
||||
if (i != wdref[refindex])
|
||||
char **path, found = 0;
|
||||
|
||||
if (i != wdref[index])
|
||||
continue;
|
||||
|
||||
assert(str_list_has(l, pathref[refindex]));
|
||||
for(path=list; !found && *path; path++) {
|
||||
if (!strcmp(*path, pathref[index]))
|
||||
found = 1;
|
||||
}
|
||||
assert(found);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue