--- dbus-1.2.16/bus/dir-watch-inotify.c 2009-07-14 13:06:31.000000000 -0400 +++ hacked/bus/dir-watch-inotify.c 2009-12-18 00:46:05.524818800 -0500 @@ -34,6 +34,7 @@ #include #include +#include #include #include "dir-watch.h" @@ -43,6 +44,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; @@ -90,12 +92,10 @@ 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 @@ -112,22 +112,38 @@ 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; + } } + ret = 1; + +out: + return ret; +} + +void +bus_watch_directory (const char *dir, BusContext *context) +{ + int wd; + + _dbus_assert (dir != NULL); + + if (!_init_inotify (context)) + goto out; + if (num_wds >= MAX_DIRS_TO_WATCH ) { _dbus_warn ("Cannot watch config directory '%s'. Already watching %d directories\n", dir, MAX_DIRS_TO_WATCH); @@ -141,6 +157,7 @@ goto out; } + dirs[num_wds] = strdup (dir); wds[num_wds++] = wd; _dbus_verbose ("Added watch on config directory '%s'\n", dir); @@ -148,7 +165,84 @@ ; } -void +void +bus_set_watched_dirs (BusContext *context, DBusList **directories) +{ + static int new_wds[MAX_DIRS_TO_WATCH]; + static 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++) + { + new_wds[i] = -1; + new_dirs[i] = NULL; + } + + i = 0; + link = _dbus_list_get_first_link (directories); + while (link != NULL) + { + new_dirs[i++] = (char *)link->data; + link = _dbus_list_get_next_link (directories, link); + } + + 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; + } + } + } + + 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; + } + } + + for (i = 0; new_dirs[i]; i++) + { + if (new_wds[i] == -1) + { + 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] = strdup (new_dirs[i]); + } + } + + num_wds = i; + + for (i = 0; i < MAX_DIRS_TO_WATCH; i++) + { + wds[i] = new_wds[i]; + dirs[i] = new_dirs[i]; + } + + out:; +} + +void bus_drop_all_directory_watches (void) { int ret; --- dbus-1.2.16/bus/dir-watch.h 2009-07-14 13:06:31.000000000 -0400 +++ hacked/bus/dir-watch.h 2009-12-18 00:45:47.437818936 -0500 @@ -32,4 +32,6 @@ /* drop all the watches previously set up by bus_config_watch_directory (OS dependent, may be a NOP) */ void bus_drop_all_directory_watches (void); +void bus_set_watched_dirs (BusContext *context, DBusList **dirs); + #endif /* DIR_WATCH_H */ --- dbus-1.2.16/bus/bus.c 2009-07-14 13:06:31.000000000 -0400 +++ hacked/bus/bus.c 2009-12-18 00:51:30.348481884 -0500 @@ -516,11 +516,6 @@ context->activation = new_activation; - /* Drop existing conf-dir watches (if applicable) */ - - if (is_reload) - bus_drop_all_directory_watches (); - _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = TRUE; @@ -551,9 +546,7 @@ _dbus_hash_table_unref (service_context_table); /* Watch all conf directories */ - _dbus_list_foreach (bus_config_parser_get_conf_dirs (parser), - (DBusForeachFunction) bus_watch_directory, - context); + bus_set_watched_dirs (context, bus_config_parser_get_conf_dirs (parser)); return TRUE; }