]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
2005-06-14 David Zeuthen <davidz@redhat.com>
authorDavid Zeuthen <davidz@redhat.com>
Wed, 15 Jun 2005 02:31:38 +0000 (02:31 +0000)
committerDavid Zeuthen <davidz@redhat.com>
Wed, 15 Jun 2005 02:31:38 +0000 (02:31 +0000)
        * bus/bus.c (process_config_every_time): Drop existing conf-dir
        watches (if applicable) and add new watches

        * bus/main.c (signal_handler): Handle SIGIO if using D_NOTIFY
        (main): Setup SIGIO signal handler if using D_NOTIFY

        * bus/config-parser.h: Add prototype bus_config_parser_get_conf_dirs

        * bus/config-parser.c (struct BusConfigParser): Add conf_dirs list
        (merge_included): Also merge conf_dirs list
        (bus_config_parser_unref): Clear conf_dirs list
        (include_dir): Add directory to conf_dirs list
        (bus_config_parser_get_conf_dirs): New function

        * bus/dir-watch.[ch]: New files

        * bus/Makefile.am (BUS_SOURCES): Add dir-watch.[ch]

        * configure.in: Add checks for D_NOTIFY on Linux

ChangeLog
bus/Makefile.am
bus/bus.c
bus/config-parser.c
bus/config-parser.h
bus/dir-watch.c [new file with mode: 0644]
bus/dir-watch.h [new file with mode: 0644]
bus/main.c
configure.in

index cc555ac8a9eb2fcc971a4b35c72ca62659d18cfa..7ca9efc08b27cf73d4c53aee93238da449a5bdb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2005-06-14  David Zeuthen  <davidz@redhat.com>
+
+       * bus/bus.c (process_config_every_time): Drop existing conf-dir
+       watches (if applicable) and add new watches
+
+       * bus/main.c (signal_handler): Handle SIGIO if using D_NOTIFY
+       (main): Setup SIGIO signal handler if using D_NOTIFY
+
+       * bus/config-parser.h: Add prototype bus_config_parser_get_conf_dirs
+
+       * bus/config-parser.c (struct BusConfigParser): Add conf_dirs list
+       (merge_included): Also merge conf_dirs list
+       (bus_config_parser_unref): Clear conf_dirs list
+       (include_dir): Add directory to conf_dirs list
+       (bus_config_parser_get_conf_dirs): New function
+
+       * bus/dir-watch.[ch]: New files
+
+       * bus/Makefile.am (BUS_SOURCES): Add dir-watch.[ch]
+
+       * configure.in: Add checks for D_NOTIFY on Linux
+
 2005-06-14  Colin Walters  <walters@verbum.org>
 
        * glib/dbus-binding-tool-glib.c:
index 567706563c64bedb27fc1e01524d891075778386..259b91995607165871fad54acd328a2bf33da327 100644 (file)
@@ -36,6 +36,8 @@ BUS_SOURCES=                                  \
        connection.h                            \
        desktop-file.c                          \
        desktop-file.h                          \
+       dir-watch.c                             \
+       dir-watch.h                             \
        dispatch.c                              \
        dispatch.h                              \
        driver.c                                \
index 445ab52cff26d3f2f55751a7516fd195be34eec2..6da13e480f5ea4ce2b09fa73f359d03500f42852 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -30,6 +30,7 @@
 #include "config-parser.h"
 #include "signals.h"
 #include "selinux.h"
+#include "dir-watch.h"
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-hash.h>
 #include <dbus/dbus-internals.h>
@@ -478,6 +479,15 @@ process_config_every_time (BusContext      *context,
       goto failed;
     }
 
+  /* Drop existing conf-dir watches (if applicable) and watch all conf directories */
+
+  if (is_reload)
+    bus_drop_all_directory_watches ();
+
+  _dbus_list_foreach (bus_config_parser_get_conf_dirs (parser),
+                     (DBusForeachFunction) bus_watch_directory,
+                     NULL);
+
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   retval = TRUE;
 
@@ -720,6 +730,7 @@ bus_context_new (const DBusString *config_file,
       _DBUS_ASSERT_ERROR_IS_SET (error);
       goto failed;
     }
+
   if (parser != NULL)
     bus_config_parser_unref (parser);
   
index 9b9ad7f326fceda6f737640da48285219a0b42e7..ff2927a755013324ac2359347c55e899f6d59827 100644 (file)
@@ -115,6 +115,8 @@ struct BusConfigParser
 
   DBusList *service_dirs; /**< Directories to look for services in */
 
+  DBusList *conf_dirs;   /**< Directories to look for policy configuration in */
+
   BusPolicy *policy;     /**< Security policy */
 
   BusLimits limits;      /**< Limits */
@@ -322,6 +324,9 @@ merge_included (BusConfigParser *parser,
 
   while ((link = _dbus_list_pop_first_link (&included->service_dirs)))
     _dbus_list_append_link (&parser->service_dirs, link);
+
+  while ((link = _dbus_list_pop_first_link (&included->conf_dirs)))
+    _dbus_list_append_link (&parser->conf_dirs, link);
   
   return TRUE;
 }
@@ -468,6 +473,12 @@ bus_config_parser_unref (BusConfigParser *parser)
 
       _dbus_list_clear (&parser->service_dirs);
 
+      _dbus_list_foreach (&parser->conf_dirs,
+                          (DBusForeachFunction) dbus_free,
+                          NULL);
+
+      _dbus_list_clear (&parser->conf_dirs);
+
       _dbus_list_foreach (&parser->mechanisms,
                           (DBusForeachFunction) dbus_free,
                           NULL);
@@ -1965,6 +1976,7 @@ include_dir (BusConfigParser   *parser,
   dbus_bool_t retval;
   DBusError tmp_error;
   DBusDirIter *dir;
+  char *s;
   
   if (!_dbus_string_init (&filename))
     {
@@ -2021,7 +2033,21 @@ include_dir (BusConfigParser   *parser,
       dbus_move_error (&tmp_error, error);
       goto failed;
     }
-  
+
+
+  if (!_dbus_string_copy_data (dirname, &s))
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+
+  if (!_dbus_list_append (&parser->conf_dirs, s))
+    {
+      dbus_free (s);
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+
   retval = TRUE;
   
  failed:
@@ -2358,6 +2384,12 @@ bus_config_parser_get_service_dirs (BusConfigParser *parser)
   return &parser->service_dirs;
 }
 
+DBusList**
+bus_config_parser_get_conf_dirs (BusConfigParser *parser)
+{
+  return &parser->conf_dirs;
+}
+
 dbus_bool_t
 bus_config_parser_get_fork (BusConfigParser   *parser)
 {
index 388704db6d54ba1500b47d2d20c1c2aae19c2f3b..657b0aefc52ae42e0a15d448dc17175f09fcc26f 100644 (file)
@@ -67,6 +67,7 @@ DBusList**  bus_config_parser_get_mechanisms   (BusConfigParser *parser);
 dbus_bool_t bus_config_parser_get_fork         (BusConfigParser *parser);
 const char* bus_config_parser_get_pidfile      (BusConfigParser *parser);
 DBusList**  bus_config_parser_get_service_dirs (BusConfigParser *parser);
+DBusList**  bus_config_parser_get_conf_dirs    (BusConfigParser *parser);
 BusPolicy*  bus_config_parser_steal_policy     (BusConfigParser *parser);
 void        bus_config_parser_get_limits       (BusConfigParser *parser,
                                                 BusLimits       *limits);
@@ -81,5 +82,4 @@ BusConfigParser* bus_config_load (const DBusString      *file,
                                   const BusConfigParser *parent,
                                   DBusError             *error);
 
-
 #endif /* BUS_CONFIG_PARSER_H */
diff --git a/bus/dir-watch.c b/bus/dir-watch.c
new file mode 100644 (file)
index 0000000..ed123b3
--- /dev/null
@@ -0,0 +1,110 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dir-watch.c  OS specific directory change notification for message bus
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */
+
+#include <dbus/dbus-internals.h>
+#include "dir-watch.h"
+
+
+/* D_NOTIFY is available on Linux 2.4 or greater - the actual SIGIO signal is handled in main.c:signal_handler() */
+#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
+
+#define MAX_DIRS_TO_WATCH 128
+
+/* use a static array to avoid handling OOM */
+static int fds[MAX_DIRS_TO_WATCH];
+static int num_fds = 0;
+
+void
+bus_watch_directory (const char *dir, void *userdata)
+{
+  int fd;
+
+  _dbus_assert (dir != NULL);
+
+  if (num_fds >= MAX_DIRS_TO_WATCH )
+    {
+      _dbus_warn ("Cannot watch config directory '%s'. Already watching %d directories\n", dir, MAX_DIRS_TO_WATCH);
+      goto out;
+    }
+
+  fd = open (dir, O_RDONLY);
+  if (fd < 0)
+    {
+      _dbus_warn ("Cannot open directory '%s'; error '%s'\n", dir, _dbus_strerror (errno));
+      goto out;
+    }
+
+  if (fcntl (fd, F_NOTIFY, DN_DELETE|DN_RENAME|DN_MODIFY) == -1)
+    {
+      _dbus_warn ("Cannot setup D_NOTIFY for '%s' error '%s'\n", dir, _dbus_strerror (errno));
+      close (fd);
+      goto out;
+    }
+  
+  fds[num_fds++] = fd;
+  _dbus_verbose ("Added watch on config directory '%s'\n", dir);
+
+ out:
+  ;
+}
+
+void 
+bus_drop_all_directory_watches (void)
+{
+  _dbus_verbose ("Dropping all watches on config directories\n");
+
+  int i;
+  
+  for (i = 0; i < num_fds; i++)
+    {
+      if (close (fds[i]) != 0)
+       {
+         _dbus_verbose ("Error closing fd %d for config directory watch\n", fds[i]);
+       }
+    }
+  
+  num_fds = 0;
+}
+
+#else /* fallback to NOP */
+
+void 
+bus_drop_all_directory_watches (void)
+{
+}
+
+void
+bus_watch_directory (const char *dir, void *userdata)
+{
+}
+
+#endif
diff --git a/bus/dir-watch.h b/bus/dir-watch.h
new file mode 100644 (file)
index 0000000..3b75426
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dir-watch.h  Watch directories
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef DIR_WATCH_H
+#define DIR_WATCH_H
+
+/* setup a watch on a directory (OS dependent, may be a NOP) */
+void bus_watch_directory (const char *directory, void *userdata);
+
+/* 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);
+
+#endif /* DIR_WATCH_H */
index f4b188a9ff839c1cc0bed9b5db42021a72c0e94e..be3fe319b007b33eef13667c52ea1aeb5325ec78 100644 (file)
@@ -44,6 +44,10 @@ signal_handler (int sig)
 
   switch (sig)
     {
+#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
+    case SIGIO: 
+      /* explicit fall-through */
+#endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX  */
     case SIGHUP:
       _dbus_string_init_const (&str, "foo");
       if (!_dbus_write (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
@@ -397,9 +401,12 @@ main (int argc, char **argv)
     }
 
   setup_reload_pipe (bus_context_get_loop (context));
+
   _dbus_set_signal_handler (SIGHUP, signal_handler);
   _dbus_set_signal_handler (SIGTERM, signal_handler);
+#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX 
+  _dbus_set_signal_handler (SIGIO, signal_handler);
+#endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */
   
   _dbus_verbose ("We are on D-Bus...\n");
   _dbus_loop_run (bus_context_get_loop (context));
index 6da1d9536884d5dce08fc1e7ebd21c6e08242d8e..dca985cf0fe7832cf9ff9a7be7c49abfa3da1e37 100644 (file)
@@ -7,6 +7,8 @@ AM_INIT_AUTOMAKE(dbus, 0.34)
 
 AM_CONFIG_HEADER(config.h)
 
+AC_CANONICAL_TARGET
+
 # Honor aclocal flags
 ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
 
@@ -822,6 +824,22 @@ else
     SELINUX_LIBS=
 fi
 
+# dnotify checks
+if test x$target_os = xlinux-gnu; then
+       AC_ARG_ENABLE(dnotify,
+       [  --disable-dnotify         Disable using dnotify on Linux],
+       [case "${enableval}" in
+         yes) dnotify=false ;;
+         no)  dnotify=true ;;
+         *) AC_MSG_ERROR(bad value ${enableval} for --disable-dnotify) ;;
+       esac],[dnotify=true])
+fi
+dnl check if dnotify backend is enabled
+if test x$dnotify = xtrue; then
+   AC_DEFINE(DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX,1,[Use dnotify on Linux])
+fi
+
+
 #### Set up final flags
 DBUS_CLIENT_CFLAGS=
 DBUS_CLIENT_LIBS=