summaryrefslogtreecommitdiffstats
path: root/bus/dir-watch-inotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'bus/dir-watch-inotify.c')
-rw-r--r--bus/dir-watch-inotify.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/bus/dir-watch-inotify.c b/bus/dir-watch-inotify.c
index 0f3c155c..1622cde2 100644
--- a/bus/dir-watch-inotify.c
+++ b/bus/dir-watch-inotify.c
@@ -38,6 +38,8 @@
#include "dir-watch.h"
#define MAX_DIRS_TO_WATCH 128
+#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
+#define INOTIFY_BUF_LEN (1024 * (INOTIFY_EVENT_SIZE + 16))
/* use a static array to avoid handling OOM */
static int wds[MAX_DIRS_TO_WATCH];
@@ -55,33 +57,43 @@ _inotify_watch_callback (DBusWatch *watch, unsigned int condition, void *data)
static dbus_bool_t
_handle_inotify_watch (DBusWatch *watch, unsigned int flags, void *data)
{
- struct inotify_event ev;
- size_t res;
+ char buffer[INOTIFY_BUF_LEN];
+ ssize_t ret = 0;
+ int i = 0;
pid_t pid;
- res = read (inotify_fd, &ev, sizeof(ev));
+ ret = read (inotify_fd, buffer, INOTIFY_BUF_LEN);
+ if (ret < 0)
+ _dbus_verbose ("Error reading inotify event: '%s'\n, _dbus_strerror(errno)");
+ else if (!ret)
+ _dbus_verbose ("Error reading inotify event: buffer too small\n");
- if (res > 0)
+ while (i < ret)
{
- pid = getpid ();
+ struct inotify_event *ev;
+ pid = _dbus_getpid ();
+
+ ev = (struct inotify_event *) &buffer[i];
+ i += INOTIFY_EVENT_SIZE + ev->len;
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+ if (ev->len)
+ _dbus_verbose ("event name: '%s'\n", ev->name);
+ _dbus_verbose ("inotify event: wd=%d mask=%u cookie=%u len=%u\n", ev->wd, ev->mask, ev->cookie, ev->len);
+#endif
_dbus_verbose ("Sending SIGHUP signal on reception of a inotify event\n");
(void) kill (pid, SIGHUP);
}
- else if (res < 0 && errno == EBADF)
+
+ if (watch != NULL)
{
- if (watch != NULL)
- {
- _dbus_loop_remove_watch (loop, watch, _inotify_watch_callback, NULL);
- _dbus_watch_unref (watch);
- watch = NULL;
- }
- pid = getpid ();
- _dbus_verbose ("Sending SIGHUP signal since inotify fd has been closed\n");
- (void) kill (pid, SIGHUP);
+ _dbus_loop_remove_watch (loop, watch, _inotify_watch_callback, NULL);
+ _dbus_watch_unref (watch);
+ watch = NULL;
}
-
+
return TRUE;
}
+
void
bus_watch_directory (const char *dir, BusContext *context)
{
@@ -116,14 +128,13 @@ bus_watch_directory (const char *dir, BusContext *context)
}
}
-
if (num_wds >= MAX_DIRS_TO_WATCH )
{
_dbus_warn ("Cannot watch config directory '%s'. Already watching %d directories\n", dir, MAX_DIRS_TO_WATCH);
goto out;
}
- wd = inotify_add_watch (inotify_fd, dir, IN_MODIFY);
+ wd = inotify_add_watch (inotify_fd, dir, IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd < 0)
{
_dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", dir, _dbus_strerror (errno));
@@ -140,17 +151,13 @@ bus_watch_directory (const char *dir, BusContext *context)
void
bus_drop_all_directory_watches (void)
{
- int i;
-
+ int ret;
+
_dbus_verbose ("Dropping all watches on config directories\n");
-
- for (i = 0; i < num_wds; i++)
- {
- if (inotify_rm_watch(inotify_fd, wds[i]) != 0)
- {
- _dbus_verbose ("Error closing fd %d for config directory watch\n", wds[i]);
- }
- }
-
+ ret = close (inotify_fd);
+ if (ret)
+ _dbus_verbose ("Error dropping watches: '%s'\n", perror(ret));
+
num_wds = 0;
+ inotify_fd = -1;
}