From 3b68160892792f71bb7820d6b03dcb80ca60f6d8 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 15 Feb 2011 16:33:51 +0100 Subject: [PATCH] inotify-watch: Adding inotify watch datastructure. --- src/inotify-watch.c | 75 ++++++++++++++++++++++++++++++++++++++++++ src/inotify-watch.h | 21 ++++++++++++ test/Makefile | 1 + test/t_inotify-watch.c | 49 +++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 src/inotify-watch.c create mode 100644 src/inotify-watch.h create mode 100644 test/t_inotify-watch.c diff --git a/src/inotify-watch.c b/src/inotify-watch.c new file mode 100644 index 0000000..ba36c39 --- /dev/null +++ b/src/inotify-watch.c @@ -0,0 +1,75 @@ + +#include +#include +#include "xalloc.h" +#include "path.h" +#include "inotify-watch.h" + +struct watch* inotify_watch_new(int wd, const char *path) { + + struct watch *w = xmallocz(sizeof(struct watch)); + + w->wd = wd; + w->path = path; + + return w; +} + +static void watch_free(struct tree *tree, void *data) { + + void (*fn)(struct watch *) = data; + + if (fn) + fn((struct watch*)tree); + xfree(tree); +} + +void inotify_watch_destroy(struct watch *watch, void (*fn)(struct watch *)) { + + if (watch) { + struct tree *tree = (struct tree*) watch; + + if (!tree_is_root(tree)) + tree_detach(tree); + + tree_traverse(tree, watch_free, fn); + } +} + +struct watch* inotify_watch_add(struct watch *parent, struct watch *watch) { + + if (parent->tree.child) { + struct watch *it = (struct watch*)parent->tree.child; + + /* move nodes that are children of this watch alongside watch */ + while(it) { + if (path_isparent(it->path, watch->path)) { + struct watch *next = (struct watch*)it->tree.next; + tree_move(&watch->tree, &it->tree); + it = next; + } else { + it = (struct watch*)it->tree.next; + } + } + } + return (struct watch*)tree_link(&parent->tree, &watch->tree); +} + +void inotify_watch_rm(struct watch *watch) { + + tree_unlink(&watch->tree); +} + +struct watch* inoitfy_watch_find_child(struct watch *watch, const char *path) { + + if (watch->tree.child) { + struct watch *it = (struct watch *) watch->tree.child; + + while(it) { + if (!strcmp(watch->path, it->path)) + return it; + it = (struct watch*) it->tree.next; + } + } + return NULL; +} diff --git a/src/inotify-watch.h b/src/inotify-watch.h new file mode 100644 index 0000000..823d90b --- /dev/null +++ b/src/inotify-watch.h @@ -0,0 +1,21 @@ + +#ifndef INOTIFY_WATCH_H +#define INOTIFY_WATCH_H + +#include "tree.h" + +struct watch { + struct tree tree; + int wd; + const char *path; +}; + +struct watch* inotify_watch_new(int wd, const char *path); + +void inotify_watch_destroy(struct watch *watch, void (*fn)(struct watch *)); + +struct watch* inotify_watch_add(struct watch *parent, struct watch *watch); + +void inotify_watch_rm(struct watch *watch); + +#endif diff --git a/test/Makefile b/test/Makefile index 1a44ecd..a09e9e3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -20,6 +20,7 @@ path : unit.c $(ROOT)src/path.o $(addprefix $(ROOT),$(obj-strbuf)) fscrawl : $(ROOT)src/fscrawl.o $(addprefix $(ROOT),$(obj-fscrawl)) notify : $(addprefix $(ROOT),$(obj-notify)) inotify-map : $(addprefix $(ROOT),$(obj-inotify-map)) +inotify-watch : $(addprefix $(ROOT), $(obj-xalloc)) $(addprefix $(ROOT), $(obj-path)) $(ROOT)src/tree.o ../src/inotify-watch.o log : $(addprefix $(ROOT),$(obj-log)) tree : $(addprefix $(ROOT),$(obj-xalloc)) $(ROOT)src/tree.o str-list : unit.c $(addprefix $(ROOT),$(obj-str-list)) diff --git a/test/t_inotify-watch.c b/test/t_inotify-watch.c new file mode 100644 index 0000000..6707b9d --- /dev/null +++ b/test/t_inotify-watch.c @@ -0,0 +1,49 @@ + +#include +#include +#include "../src/inotify-watch.h" + +void print_node(struct tree *n, void *data) { + + size_t c = tree_parent_count(n); + while(c--) + printf("│ "); + + if (n->next == NULL && n->parent) + printf("└──"); + else + printf("│──"); + printf(" %s\n", ((struct watch *)n)->path); +} + +int main() { + + struct watch *root = inotify_watch_new(0, "/"); + struct watch *ch1 = inotify_watch_new(1, "/var/"); + struct watch *ch2 = inotify_watch_new(2, "/mnt/"); + + inotify_watch_add(root, ch1); + inotify_watch_add(root, ch2); + + inotify_watch_add(ch1, inotify_watch_new(11, "/var/a/")); + inotify_watch_add(ch1, inotify_watch_new(12, "/var/b/")); + inotify_watch_add(ch2, inotify_watch_new(21, "/mnt/c/")); + + inotify_watch_add((struct watch*)ch2->tree.child, inotify_watch_new(234, "/mnt/c/a/")); + + tree_traverse((struct tree*)root, print_node, NULL); + + inotify_watch_rm(ch1); + + printf("---\n"); + tree_traverse((struct tree*)root, print_node, NULL); + + inotify_watch_add(root, ch1); + + printf("---\n"); + tree_traverse((struct tree*)root, print_node, NULL); + + inotify_watch_destroy(root, NULL); + + return 0; +}