diff options
author | Colin Walters <walters@verbum.org> | 2010-02-01 17:27:26 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-02-01 17:27:26 -0500 |
commit | 6db588b8544e117241a3be2c595dfc8fdcdc8f59 (patch) | |
tree | 7fc15cf9939edecf76d9cfd4163560bc9bc22363 /bus/dir-watch-inotify.c | |
parent | 2016b83dece7f220269033e7957fb02140334294 (diff) | |
parent | e59db9df47bcf99aa292e6d13ca2044105a94b90 (diff) | |
download | dbus-6db588b8544e117241a3be2c595dfc8fdcdc8f59.tar.gz |
Merge branch 'my-dbus-1.2'
Diffstat (limited to 'bus/dir-watch-inotify.c')
-rw-r--r-- | bus/dir-watch-inotify.c | 150 |
1 files changed, 104 insertions, 46 deletions
diff --git a/bus/dir-watch-inotify.c b/bus/dir-watch-inotify.c index ee580d74..d00549a5 100644 --- a/bus/dir-watch-inotify.c +++ b/bus/dir-watch-inotify.c @@ -33,6 +33,7 @@ #include <errno.h> #include <dbus/dbus-internals.h> +#include <dbus/dbus-list.h> #include <dbus/dbus-watch.h> #include "dir-watch.h" @@ -42,6 +43,7 @@ /* use a static array to avoid handling OOM */ static int wds[MAX_DIRS_TO_WATCH]; +static char *dirs[MAX_DIRS_TO_WATCH]; static int num_wds = 0; static int inotify_fd = -1; static DBusWatch *watch = NULL; @@ -89,12 +91,10 @@ _handle_inotify_watch (DBusWatch *passed_watch, unsigned int flags, void *data) return TRUE; } -void -bus_watch_directory (const char *dir, BusContext *context) +static int +_init_inotify (BusContext *context) { - int wd; - - _dbus_assert (dir != NULL); + int ret = 0; if (inotify_fd == -1) { #ifdef HAVE_INOTIFY_INIT1 @@ -111,59 +111,117 @@ bus_watch_directory (const char *dir, BusContext *context) watch = _dbus_watch_new (inotify_fd, DBUS_WATCH_READABLE, TRUE, _handle_inotify_watch, NULL, NULL); - if (watch == NULL) - { - _dbus_warn ("Unable to create inotify watch\n"); - goto out; - } - - if (!_dbus_loop_add_watch (loop, watch, _inotify_watch_callback, - NULL, NULL)) - { - _dbus_warn ("Unable to add reload watch to main loop"); - _dbus_watch_unref (watch); - watch = NULL; - goto out; - } + if (watch == NULL) + { + _dbus_warn ("Unable to create inotify watch\n"); + goto out; + } + + if (!_dbus_loop_add_watch (loop, watch, _inotify_watch_callback, + NULL, NULL)) + { + _dbus_warn ("Unable to add reload watch to main loop"); + _dbus_watch_unref (watch); + watch = NULL; + goto out; + } } - if (num_wds >= MAX_DIRS_TO_WATCH ) + ret = 1; + +out: + return ret; +} + +void +bus_set_watched_dirs (BusContext *context, DBusList **directories) +{ + int new_wds[MAX_DIRS_TO_WATCH]; + char *new_dirs[MAX_DIRS_TO_WATCH]; + DBusList *link; + int i, j, wd; + + if (!_init_inotify (context)) + goto out; + + for (i = 0; i < MAX_DIRS_TO_WATCH; i++) { - _dbus_warn ("Cannot watch config directory '%s'. Already watching %d directories\n", dir, MAX_DIRS_TO_WATCH); - goto out; + new_wds[i] = -1; + new_dirs[i] = NULL; } - wd = inotify_add_watch (inotify_fd, dir, IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM); - if (wd < 0) + i = 0; + link = _dbus_list_get_first_link (directories); + while (link != NULL) { - _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", dir, _dbus_strerror (errno)); - goto out; + new_dirs[i++] = (char *)link->data; + link = _dbus_list_get_next_link (directories, link); } - wds[num_wds++] = wd; - _dbus_verbose ("Added watch on config directory '%s'\n", dir); - - out: - ; -} + /* Look for directories in both the old and new sets, if + * we find one, move its data into the new set. + */ + for (i = 0; new_dirs[i]; i++) + { + for (j = 0; j < num_wds; j++) + { + if (dirs[j] && strcmp (new_dirs[i], dirs[j]) == 0) + { + new_wds[i] = wds[j]; + new_dirs[i] = dirs[j]; + wds[j] = -1; + dirs[j] = NULL; + break; + } + } + } -void -bus_drop_all_directory_watches (void) -{ - int ret; + /* Any directories we find in "wds" with a nonzero fd must + * not be in the new set, so perform cleanup now. + */ + for (j = 0; j < num_wds; j++) + { + if (wds[j] != -1) + { + inotify_rm_watch (inotify_fd, wds[j]); + dbus_free (dirs[j]); + wds[j] = -1; + dirs[j] = NULL; + } + } - if (watch != NULL) + for (i = 0; new_dirs[i]; i++) { - _dbus_loop_remove_watch (loop, watch, _inotify_watch_callback, NULL); - _dbus_watch_unref (watch); - watch = NULL; + if (new_wds[i] == -1) + { + /* FIXME - less lame error handling for failing to add a watch; we may need to sleep. */ + wd = inotify_add_watch (inotify_fd, new_dirs[i], IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM); + if (wd < 0) + { + _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno)); + goto out; + } + new_wds[i] = wd; + new_dirs[i] = _dbus_strdup (new_dirs[i]); + if (!new_dirs[i]) + { + /* FIXME have less lame handling for OOM, we just silently fail to + * watch. (In reality though, the whole OOM handling in dbus is stupid + * but we won't go into that in this comment =) ) + */ + inotify_rm_watch (inotify_fd, wd); + new_wds[i] = -1; + } + } } - _dbus_verbose ("Dropping all watches on config directories\n"); - ret = close (inotify_fd); - if (ret) - _dbus_verbose ("Error dropping watches: '%s'\n", _dbus_strerror(errno)); + num_wds = i; + + for (i = 0; i < MAX_DIRS_TO_WATCH; i++) + { + wds[i] = new_wds[i]; + dirs[i] = new_dirs[i]; + } - num_wds = 0; - inotify_fd = -1; + out:; } |