diff options
| author | David Zeuthen <davidz@redhat.com> | 2005-06-15 02:31:38 +0000 | 
|---|---|---|
| committer | David Zeuthen <davidz@redhat.com> | 2005-06-15 02:31:38 +0000 | 
| commit | 1d19fc62e9034cc5700c0903f68787a84f485315 (patch) | |
| tree | 6d0da2b8c889fefa111cc695b42d4b83e97ff237 | |
| parent | 50f85baa3d92657a6c77c450a8f6dc34206e0610 (diff) | |
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
| -rw-r--r-- | ChangeLog | 22 | ||||
| -rw-r--r-- | bus/Makefile.am | 2 | ||||
| -rw-r--r-- | bus/bus.c | 11 | ||||
| -rw-r--r-- | bus/config-parser.c | 34 | ||||
| -rw-r--r-- | bus/config-parser.h | 2 | ||||
| -rw-r--r-- | bus/dir-watch.c | 110 | ||||
| -rw-r--r-- | bus/dir-watch.h | 33 | ||||
| -rw-r--r-- | bus/main.c | 9 | ||||
| -rw-r--r-- | configure.in | 18 | 
9 files changed, 238 insertions, 3 deletions
| @@ -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: diff --git a/bus/Makefile.am b/bus/Makefile.am index 56770656..259b9199 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -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				\ @@ -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); diff --git a/bus/config-parser.c b/bus/config-parser.c index 9b9ad7f3..ff2927a7 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -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)  { diff --git a/bus/config-parser.h b/bus/config-parser.h index 388704db..657b0aef 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -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 index 00000000..ed123b36 --- /dev/null +++ b/bus/dir-watch.c @@ -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 index 00000000..3b754261 --- /dev/null +++ b/bus/dir-watch.h @@ -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 */ @@ -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)); diff --git a/configure.in b/configure.in index 6da1d953..dca985cf 100644 --- a/configure.in +++ b/configure.in @@ -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= | 
