notify/inotify.c: now using new fscrawl.
This commit is contained in:
parent
797545cd9b
commit
99066503f3
1 changed files with 68 additions and 21 deletions
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../common/path.h"
|
#include "../common/path.h"
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
#include "fscrawl.h"
|
||||||
#include "notify.h"
|
#include "notify.h"
|
||||||
|
|
||||||
typedef struct inotify_event inoev;
|
typedef struct inotify_event inoev;
|
||||||
|
|
@ -50,10 +51,10 @@ static int addwatch(const char *path, const char *name) {
|
||||||
wd = inotify_add_watch(fd, npath, WATCH_MASK);
|
wd = inotify_add_watch(fd, npath, WATCH_MASK);
|
||||||
|
|
||||||
if (wd < 0) {
|
if (wd < 0) {
|
||||||
perror("NOTIFY ADD");
|
|
||||||
dprint("%i path %s\n", errno == EBADF, npath);
|
|
||||||
free(npath);
|
free(npath);
|
||||||
return -errno;
|
wd = -errno;
|
||||||
|
errno = 0;
|
||||||
|
return wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we must update to not introduce duplicated wd's (keys) */
|
/* we must update to not introduce duplicated wd's (keys) */
|
||||||
|
|
@ -73,15 +74,16 @@ static int addwatch(const char *path, const char *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmwatch(unsigned int wd) {
|
static int rmwatch(unsigned int wd) {
|
||||||
|
|
||||||
void *data = rbtree_delete(&tree, wd);
|
void *data = rbtree_delete(&tree, wd);
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dprint("remove watch: %i %s\n", wd, (char*) data);
|
dprint("rmwatch: %i %s\n", wd, (char*) data);
|
||||||
inotify_rm_watch(fd, wd);
|
inotify_rm_watch(fd, wd);
|
||||||
free(data);
|
if (data)
|
||||||
|
free(data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,14 +112,25 @@ static void proc_event(inoev *iev) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_event_set_dir(event, (iev->mask & IN_ISDIR) != 0);
|
|
||||||
|
|
||||||
/* set path, this is stored in void* node->data */
|
/* set path, this is stored in void* node->data */
|
||||||
notify_event_set_path(event, (char*)node->data);
|
notify_event_set_path(event, node->data);
|
||||||
notify_event_set_filename(event, iev->name);
|
notify_event_set_filename(event, iev->name);
|
||||||
|
|
||||||
|
notify_event_set_dir(event, (iev->mask & IN_ISDIR) != 0);
|
||||||
|
|
||||||
iev->mask &= ~IN_ISDIR;
|
iev->mask &= ~IN_ISDIR;
|
||||||
|
|
||||||
|
/* this event is always generated and works better
|
||||||
|
for removing the node in the binary tree */
|
||||||
|
if (iev->mask == IN_IGNORED) {
|
||||||
|
rmwatch(iev->wd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* queue event before doing any fscrawl on a subdirectory
|
||||||
|
to prevent messing up the order */
|
||||||
|
queue_enqueue(event_queue, event);
|
||||||
|
|
||||||
switch (iev->mask) {
|
switch (iev->mask) {
|
||||||
|
|
||||||
case IN_CREATE :
|
case IN_CREATE :
|
||||||
|
|
@ -133,31 +146,61 @@ static void proc_event(inoev *iev) {
|
||||||
|
|
||||||
if (event->dir) {
|
if (event->dir) {
|
||||||
dprint("IN_MOVED_TO on directory, adding\n");
|
dprint("IN_MOVED_TO on directory, adding\n");
|
||||||
addwatch(event->path, event->filename);
|
/* TODO: clean this */
|
||||||
|
sprintf(buf, "%s%s/", event->path, event->filename);
|
||||||
|
notify_add_watch(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
type = NOTIFY_MOVE_TO;
|
type = NOTIFY_CREATE;
|
||||||
break;
|
break;
|
||||||
case IN_MOVED_FROM :
|
case IN_MOVED_FROM :
|
||||||
/* TODO: clean this */
|
/* TODO: and this */
|
||||||
sprintf(buf, "%s%s/", event->path, event->filename);
|
sprintf(buf, "%s%s/", event->path, event->filename);
|
||||||
notify_rm_watch(buf);
|
notify_rm_watch(buf);
|
||||||
case IN_DELETE :
|
case IN_DELETE :
|
||||||
type = NOTIFY_DELETE;
|
type = NOTIFY_DELETE;
|
||||||
break;
|
break;
|
||||||
case IN_IGNORED :
|
|
||||||
rmwatch(iev->wd);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_event_set_type(event, type);
|
notify_event_set_type(event, type);
|
||||||
|
|
||||||
queue_enqueue(event_queue, event);
|
|
||||||
return;
|
return;
|
||||||
cleanup:
|
cleanup:
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void addrecursive(const char *path) {
|
||||||
|
|
||||||
|
fscrawl_t fsc;
|
||||||
|
fs_entry *ent;
|
||||||
|
notify_event *ev;
|
||||||
|
|
||||||
|
fsc = fsc_open(path);
|
||||||
|
|
||||||
|
if (!fsc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
|
||||||
|
ent = fsc_read(fsc);
|
||||||
|
|
||||||
|
if (!ent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent->dir)
|
||||||
|
addwatch(ent->base, ent->name);
|
||||||
|
|
||||||
|
ev = notify_event_new();
|
||||||
|
|
||||||
|
notify_event_set_type(ev, NOTIFY_CREATE);
|
||||||
|
notify_event_set_path(ev, ent->base);
|
||||||
|
notify_event_set_filename(ev, ent->name);
|
||||||
|
notify_event_set_dir(ev, ent->dir);
|
||||||
|
|
||||||
|
queue_enqueue(event_queue, ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int notify_init() {
|
int notify_init() {
|
||||||
|
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
|
|
@ -186,7 +229,6 @@ void notify_exit() {
|
||||||
|
|
||||||
fd = 0;
|
fd = 0;
|
||||||
|
|
||||||
/* free rbtree */
|
|
||||||
rbtree_free(&tree, NULL);
|
rbtree_free(&tree, NULL);
|
||||||
|
|
||||||
if (event_queue) {
|
if (event_queue) {
|
||||||
|
|
@ -199,8 +241,13 @@ void notify_exit() {
|
||||||
* Add inotify watch on path
|
* Add inotify watch on path
|
||||||
*/
|
*/
|
||||||
int notify_add_watch(const char *path) {
|
int notify_add_watch(const char *path) {
|
||||||
|
|
||||||
return addwatch(path, NULL);
|
if (addwatch(path, NULL) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
addrecursive(path);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int notify_rm_watch(const char *path) {
|
int notify_rm_watch(const char *path) {
|
||||||
|
|
|
||||||
Reference in a new issue