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;
|
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);
|
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);
|
struct map_path *p = rbtree_search(&tree_path_wd, &path);
|
||||||
return p ? inotify_map_lookup(p->wd) : NULL;
|
return p ? inotify_map_lookup(p->wd) : NULL;
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ void inotify_unmap_all();
|
||||||
|
|
||||||
int inotify_map_get_wd(const char *path);
|
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();
|
int inotify_map_isempty();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,6 @@ static int addwatch(const char *path, const char *name, unsigned recursive) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inotify_map(wd, npath);
|
|
||||||
|
|
||||||
logmsg(LOG_DEBUG, "added wd = %i on %s", wd, npath);
|
logmsg(LOG_DEBUG, "added wd = %i on %s", wd, npath);
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
|
|
@ -89,6 +87,7 @@ static int addwatch(const char *path, const char *name, unsigned recursive) {
|
||||||
}
|
}
|
||||||
fsc_close(f);
|
fsc_close(f);
|
||||||
}
|
}
|
||||||
|
inotify_map(wd, npath);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -123,8 +122,7 @@ static int rmwatch(const char *path, const char *name) {
|
||||||
|
|
||||||
static void proc_event(inoev *iev) {
|
static void proc_event(inoev *iev) {
|
||||||
|
|
||||||
const struct str_list *paths;
|
char **paths, **path;
|
||||||
char **path;
|
|
||||||
int isdir;
|
int isdir;
|
||||||
|
|
||||||
logmsg(LOG_DEBUG, "RAW EVENT: %i, %x, %s", iev->wd, iev->mask, iev->name);
|
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;
|
isdir = (iev->mask & IN_ISDIR) != 0;
|
||||||
iev->mask &= ~IN_ISDIR;
|
iev->mask &= ~IN_ISDIR;
|
||||||
|
|
||||||
str_list_foreach(path, paths) {
|
for(path = paths; *path; path++) {
|
||||||
|
|
||||||
uint8_t type = NOTIFY_UNKNOWN;
|
uint8_t type = NOTIFY_UNKNOWN;
|
||||||
notify_event *event = notify_event_new();
|
notify_event *event = notify_event_new();
|
||||||
|
|
@ -163,7 +161,7 @@ static void proc_event(inoev *iev) {
|
||||||
case IN_CREATE :
|
case IN_CREATE :
|
||||||
if (event->dir) {
|
if (event->dir) {
|
||||||
logmsg(LOG_DEBUG, "IN_CREATE on directory, adding");
|
logmsg(LOG_DEBUG, "IN_CREATE on directory, adding");
|
||||||
addwatch(event->path, event->filename, 0);
|
addwatch(event->path, event->filename, 1);
|
||||||
}
|
}
|
||||||
type = NOTIFY_CREATE;
|
type = NOTIFY_CREATE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -184,6 +182,8 @@ static void proc_event(inoev *iev) {
|
||||||
|
|
||||||
event->type = type;
|
event->type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
int notify_init() {
|
int notify_init() {
|
||||||
|
|
|
||||||
|
|
@ -22,18 +22,23 @@ static void teardown() {
|
||||||
inotify_unmap_all();
|
inotify_unmap_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void validate_list(int refindex, const struct str_list *l) {
|
static void validate_list(int index, char **list) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(l);
|
assert(list);
|
||||||
|
|
||||||
for(i=0; i < 4; i++) {
|
for(i=0; i < 4; i++) {
|
||||||
|
char **path, found = 0;
|
||||||
|
|
||||||
if (i != wdref[refindex])
|
if (i != wdref[index])
|
||||||
continue;
|
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