2004-04-15 Jon Trowbridge <trow@ximian.com>
authorJon Trowbridge <trow@ximian.com>
Fri, 16 Apr 2004 15:01:25 +0000 (15:01 +0000)
committerJon Trowbridge <trow@ximian.com>
Fri, 16 Apr 2004 15:01:25 +0000 (15:01 +0000)
    * bus/main.c (signal_handler): Reload the configuration files
    on SIGHUP.
    (main): Set up our SIGHUP handler.

    * bus/bus.c (struct BusContext): Store the config file, user and
    fork flag in the BusContext.
    (process_config_first_time_only): Added.  Contains the code
    (previously in bus_context_new) for setting up the BusContext from
    the BusConfigParser that should only be run the first time the
    config files are read.
    (process_config_every_time): Added.  Contains the code (previously
    in bus_context_new) for setting up the BusContext from the
    BusConfigParser that should be run every time the config files are
    read.
    (load_config): Added.  Builds a BusConfigParser from the config
    files and passes the resulting structure off to
    process_config_first_time_only (assuming this is the first time)
    and process_config_every_time.
    (bus_context_new): All of the config-related code has been moved
    to process_config_first_time_only and process_config_every_time.
    Now this function just does the non-config-related initializations
    and calls load_config.
    (bus_context_reload_config): Added.

ChangeLog
bus/bus.c
bus/bus.h
bus/main.c

index 0aacd5c..35540df 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2004-04-15  Jon Trowbridge  <trow@ximian.com>
+
+       * bus/main.c (signal_handler): Reload the configuration files
+       on SIGHUP.
+       (main): Set up our SIGHUP handler.
+
+       * bus/bus.c (struct BusContext): Store the config file, user and
+       fork flag in the BusContext.
+       (process_config_first_time_only): Added.  Contains the code
+       (previously in bus_context_new) for setting up the BusContext from
+       the BusConfigParser that should only be run the first time the
+       config files are read.
+       (process_config_every_time): Added.  Contains the code (previously
+       in bus_context_new) for setting up the BusContext from the
+       BusConfigParser that should be run every time the config files are
+       read.
+       (load_config): Added.  Builds a BusConfigParser from the config
+       files and passes the resulting structure off to
+       process_config_first_time_only (assuming this is the first time)
+       and process_config_every_time.
+       (bus_context_new): All of the config-related code has been moved
+       to process_config_first_time_only and process_config_every_time.
+       Now this function just does the non-config-related initializations
+       and calls load_config.
+       (bus_context_reload_config): Added.
+
 2004-04-15  Olivier Andrieu  <oliv__a@users.sourceforge.net>
 
        * bus/driver.c (bus_driver_handle_get_service_owner):
index 0b3c934..32a5760 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
 struct BusContext
 {
   int refcount;
+  char *config_file;
   char *type;
   char *address;
   char *pidfile;
+  char *user;
   DBusLoop *loop;
   DBusList *servers;
   BusConnections *connections;
@@ -48,6 +50,7 @@ struct BusContext
   BusMatchmaker *matchmaker;
   DBusUserDatabase *user_database;
   BusLimits limits;
+  unsigned int fork : 1;
 };
 
 static dbus_int32_t server_data_slot = -1;
@@ -247,45 +250,26 @@ setup_server (BusContext *context,
   return TRUE;
 }
 
-BusContext*
-bus_context_new (const DBusString *config_file,
-                 dbus_bool_t       force_fork,
-                 int               print_addr_fd,
-                 int               print_pid_fd,
-                 DBusError        *error)
+/* This code only gets executed the first time the
+   config files are parsed.  It is not executed
+   when config files are reloaded.*/
+static dbus_bool_t
+process_config_first_time_only (BusContext      *context,
+                               BusConfigParser *parser,
+                               DBusError       *error)
 {
-  BusContext *context;
   DBusList *link;
   DBusList **addresses;
-  BusConfigParser *parser;
-  DBusString full_address;
   const char *user, *pidfile;
   char **auth_mechanisms;
   DBusList **auth_mechanisms_list;
   int len;
-  
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  dbus_bool_t retval;
 
-  if (!_dbus_string_init (&full_address))
-    {
-      BUS_SET_OOM (error);
-      return NULL;
-    }
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
-  if (!dbus_server_allocate_data_slot (&server_data_slot))
-    {
-      BUS_SET_OOM (error);
-      _dbus_string_free (&full_address);
-      return NULL;
-    }
-  
-  parser = NULL;
-  context = NULL;
+  retval = FALSE;
   auth_mechanisms = NULL;
-  
-  parser = bus_config_load (config_file, TRUE, NULL, error);
-  if (parser == NULL)
-    goto failed;
 
   /* Check for an existing pid file. Of course this is a race;
    * we'd have to use fcntl() locks on the pid file to
@@ -312,38 +296,9 @@ bus_context_new (const DBusString *config_file,
        }
     }
   
-  context = dbus_new0 (BusContext, 1);
-  if (context == NULL)
-    {
-      BUS_SET_OOM (error);
-      goto failed;
-    }
-  
-  context->refcount = 1;
+  /* keep around the pid filename so we can delete it later */
+  context->pidfile = _dbus_strdup (pidfile);
 
-  /* get our limits and timeout lengths */
-  bus_config_parser_get_limits (parser, &context->limits);
-  
-  /* we need another ref of the server data slot for the context
-   * to own
-   */
-  if (!dbus_server_allocate_data_slot (&server_data_slot))
-    _dbus_assert_not_reached ("second ref of server data slot failed");
-  
-  context->user_database = _dbus_user_database_new ();
-  if (context->user_database == NULL)
-    {
-      BUS_SET_OOM (error);
-      goto failed;
-    }
-  
-  context->loop = _dbus_loop_new ();
-  if (context->loop == NULL)
-    {
-      BUS_SET_OOM (error);
-      goto failed;
-    }
-  
   /* Build an array of auth mechanisms */
   
   auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
@@ -355,7 +310,10 @@ bus_context_new (const DBusString *config_file,
 
       auth_mechanisms = dbus_new0 (char*, len + 1);
       if (auth_mechanisms == NULL)
-        goto failed;
+       {
+         BUS_SET_OOM (error);
+         goto failed;
+       }
       
       i = 0;
       link = _dbus_list_get_first_link (auth_mechanisms_list);
@@ -363,7 +321,10 @@ bus_context_new (const DBusString *config_file,
         {
           auth_mechanisms[i] = _dbus_strdup (link->data);
           if (auth_mechanisms[i] == NULL)
-            goto failed;
+           {
+             BUS_SET_OOM (error);
+             goto failed;
+           }
           link = _dbus_list_get_next_link (auth_mechanisms_list, link);
         }
     }
@@ -383,9 +344,15 @@ bus_context_new (const DBusString *config_file,
       
       server = dbus_server_listen (link->data, error);
       if (server == NULL)
-        goto failed;
+       {
+         _DBUS_ASSERT_ERROR_IS_SET (error);
+         goto failed;
+       }
       else if (!setup_server (context, server, auth_mechanisms, error))
-        goto failed;
+       {
+         _DBUS_ASSERT_ERROR_IS_SET (error);
+         goto failed;
+       }
 
       if (!_dbus_list_append (&context->servers, server))
         {
@@ -403,7 +370,58 @@ bus_context_new (const DBusString *config_file,
       BUS_SET_OOM (error);
       goto failed;
     }
+
+  user = bus_config_parser_get_user (parser);
+  if (user != NULL)
+    {
+      context->user = _dbus_strdup (user);
+      if (context->user == NULL)
+       {
+         BUS_SET_OOM (error);
+         goto failed;
+       }
+    }
+
+  context->fork = bus_config_parser_get_fork (parser);
   
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  retval = TRUE;
+
+ failed:
+  dbus_free_string_array (auth_mechanisms);
+  return retval;
+}
+
+/* This code gets executed every time the config files
+   are parsed: both during BusContext construction
+   and on reloads. */
+static dbus_bool_t
+process_config_every_time (BusContext      *context,
+                          BusConfigParser *parser,
+                          dbus_bool_t      is_reload,
+                          DBusError       *error)
+{
+  DBusString full_address;
+  DBusList *link;
+  
+  dbus_bool_t retval;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  retval = FALSE;
+
+  if (!_dbus_string_init (&full_address))
+    {
+      BUS_SET_OOM (error);
+      return FALSE;
+    }
+
+  /* get our limits and timeout lengths */
+  bus_config_parser_get_limits (parser, &context->limits);
+
+  context->policy = bus_config_parser_steal_policy (parser);
+  _dbus_assert (context->policy != NULL);
+
   /* We have to build the address backward, so that
    * <listen> later in the config file have priority
    */
@@ -439,12 +457,137 @@ bus_context_new (const DBusString *config_file,
       link = _dbus_list_get_prev_link (&context->servers, link);
     }
 
+  if (is_reload)
+    dbus_free (context->address);
+
   if (!_dbus_string_copy_data (&full_address, &context->address))
     {
       BUS_SET_OOM (error);
       goto failed;
     }
 
+  /* Create activation subsystem */
+  
+  if (is_reload)
+    bus_activation_unref (context->activation);
+  
+  context->activation = bus_activation_new (context, &full_address,
+                                            bus_config_parser_get_service_dirs (parser),
+                                            error);
+  if (context->activation == NULL)
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      goto failed;
+    }
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  retval = TRUE;
+
+ failed:
+  _dbus_string_free (&full_address);
+  return retval;
+}
+
+static dbus_bool_t
+load_config (BusContext *context,
+            dbus_bool_t is_reload,
+            DBusError  *error)
+{
+  BusConfigParser *parser;
+  DBusString config_file;
+  dbus_bool_t retval;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  retval = FALSE;
+  parser = NULL;
+
+  _dbus_string_init_const (&config_file, context->config_file);
+  parser = bus_config_load (&config_file, TRUE, NULL, error);
+  if (parser == NULL)
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      goto failed;
+    }
+  
+  if (!is_reload && !process_config_first_time_only (context, parser, error))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      goto failed;
+    }
+
+  if (!process_config_every_time (context, parser, is_reload, error))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      goto failed;
+    }
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  retval = TRUE;
+
+ failed:
+  if (parser)
+    bus_config_parser_unref (parser);
+  return retval;
+}
+
+BusContext*
+bus_context_new (const DBusString *config_file,
+                 dbus_bool_t       force_fork,
+                 int               print_addr_fd,
+                 int               print_pid_fd,
+                 DBusError        *error)
+{
+  BusContext *context;
+  
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  if (!dbus_server_allocate_data_slot (&server_data_slot))
+    {
+      BUS_SET_OOM (error);
+      return NULL;
+    }
+
+  context = dbus_new0 (BusContext, 1);
+  if (context == NULL)
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+  context->refcount = 1;
+
+  if (!_dbus_string_copy_data (config_file, &context->config_file))
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+
+  context->loop = _dbus_loop_new ();
+  if (context->loop == NULL)
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+
+  if (!load_config (context, FALSE, error))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      goto failed;
+    }
+  
+  /* we need another ref of the server data slot for the context
+   * to own
+   */
+  if (!dbus_server_allocate_data_slot (&server_data_slot))
+    _dbus_assert_not_reached ("second ref of server data slot failed");
+
+  context->user_database = _dbus_user_database_new ();
+  if (context->user_database == NULL)
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
+  
   /* Note that we don't know whether the print_addr_fd is
    * one of the sockets we're using to listen on, or some
    * other random thing. But I think the answer is "don't do
@@ -487,17 +630,6 @@ bus_context_new (const DBusString *config_file,
       _dbus_string_free (&addr);
     }
   
-  /* Create activation subsystem */
-  
-  context->activation = bus_activation_new (context, &full_address,
-                                            bus_config_parser_get_service_dirs (parser),
-                                            error);
-  if (context->activation == NULL)
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (error);
-      goto failed;
-    }
-
   context->connections = bus_connections_new (context);
   if (context->connections == NULL)
     {
@@ -519,37 +651,37 @@ bus_context_new (const DBusString *config_file,
       goto failed;
     }
   
-  context->policy = bus_config_parser_steal_policy (parser);
-  _dbus_assert (context->policy != NULL);
-  
   /* Now become a daemon if appropriate */
-  if (force_fork || bus_config_parser_get_fork (parser))
+  if (force_fork || context->fork)
     {
       DBusString u;
 
-      if (pidfile)
-        _dbus_string_init_const (&u, pidfile);
+      if (context->pidfile)
+        _dbus_string_init_const (&u, context->pidfile);
       
-      if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
-        goto failed;
+      if (!_dbus_become_daemon (context->pidfile ? &u : NULL, error))
+       {
+         _DBUS_ASSERT_ERROR_IS_SET (error);
+         goto failed;
+       }
     }
   else
     {
       /* Need to write PID file for ourselves, not for the child process */
-      if (pidfile != NULL)
+      if (context->pidfile != NULL)
         {
           DBusString u;
 
-          _dbus_string_init_const (&u, pidfile);
+          _dbus_string_init_const (&u, context->pidfile);
           
           if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
-            goto failed;
+           {
+             _DBUS_ASSERT_ERROR_IS_SET (error);
+             goto failed;
+           }
         }
     }
 
-  /* keep around the pid filename so we can delete it later */
-  context->pidfile = _dbus_strdup (pidfile);
-
   /* Write PID if requested */
   if (print_pid_fd >= 0)
     {
@@ -589,13 +721,12 @@ bus_context_new (const DBusString *config_file,
   /* Here we change our credentials if required,
    * as soon as we've set up our sockets and pidfile
    */
-  user = bus_config_parser_get_user (parser);
-  if (user != NULL)
+  if (context->user != NULL)
     {
       DBusCredentials creds;
       DBusString u;
 
-      _dbus_string_init_const (&u, user);
+      _dbus_string_init_const (&u, context->user);
 
       if (!_dbus_credentials_from_username (&u, &creds) ||
           creds.uid < 0 ||
@@ -603,36 +734,39 @@ bus_context_new (const DBusString *config_file,
         {
           dbus_set_error (error, DBUS_ERROR_FAILED,
                           "Could not get UID and GID for username \"%s\"",
-                          user);
+                          context->user);
           goto failed;
         }
       
       if (!_dbus_change_identity (creds.uid, creds.gid, error))
-        goto failed;
+       {
+         _DBUS_ASSERT_ERROR_IS_SET (error);
+         goto failed;
+       }
     }
   
-  bus_config_parser_unref (parser);
-  _dbus_string_free (&full_address);
-  dbus_free_string_array (auth_mechanisms);
   dbus_server_free_data_slot (&server_data_slot);
   
   return context;
   
  failed:  
-  if (parser != NULL)
-    bus_config_parser_unref (parser);
-
   if (context != NULL)
     bus_context_unref (context);
 
-  _dbus_string_free (&full_address);
-  dbus_free_string_array (auth_mechanisms);
-
   dbus_server_free_data_slot (&server_data_slot);
   
   return NULL;
 }
 
+dbus_bool_t
+bus_context_reload_config (BusContext *context,
+                          DBusError  *error)
+{
+  return load_config (context,
+                     TRUE, /* yes, we are re-loading */
+                     error);
+}
+
 static void
 shutdown_server (BusContext *context,
                  DBusServer *server)
@@ -738,8 +872,10 @@ bus_context_unref (BusContext *context)
           context->matchmaker = NULL;
         }
       
+      dbus_free (context->config_file);
       dbus_free (context->type);
       dbus_free (context->address);
+      dbus_free (context->user);
 
       if (context->pidfile)
        {
index 44b9433..7d05508 100644 (file)
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -65,6 +65,8 @@ BusContext*       bus_context_new                                (const DBusStri
                                                                   int               print_addr_fd,
                                                                   int               print_pid_fd,
                                                                   DBusError        *error);
+dbus_bool_t       bus_context_reload_config                      (BusContext       *context,
+                                                                 DBusError        *error);
 void              bus_context_shutdown                           (BusContext       *context);
 BusContext*       bus_context_ref                                (BusContext       *context);
 void              bus_context_unref                              (BusContext       *context);
index 33c6765..8d33fbb 100644 (file)
 #include <errno.h>
 
 static BusContext *context;
-static dbus_bool_t got_sighup = FALSE;
 
 static void
 signal_handler (int sig)
 {
+  DBusError error;
+
   switch (sig)
     {
     case SIGHUP:
-      got_sighup = TRUE;
+      /* FIXME: We shouldn't be reloading the config in the
+        signal handler.  We should use a pipe or something to
+        make the reload happen in the main loop. */
+      dbus_error_init (&error);
+      if (!bus_context_reload_config (context, &error))
+       {
+         _dbus_warn ("Unable to reload configuration: %s\n",
+                     error.message);
+         dbus_error_free (&error);
+         exit (1);
+       }
+      break;
+
     case SIGTERM:
       _dbus_loop_quit (bus_context_get_loop (context));
       break;
@@ -297,7 +310,7 @@ main (int argc, char **argv)
       exit (1);
     }
   
-  /* FIXME we have to handle this properly below _dbus_set_signal_handler (SIGHUP, signal_handler); */
+  _dbus_set_signal_handler (SIGHUP, signal_handler);
   _dbus_set_signal_handler (SIGTERM, signal_handler);
   
   _dbus_verbose ("We are on D-Bus...\n");
@@ -306,13 +319,5 @@ main (int argc, char **argv)
   bus_context_shutdown (context);
   bus_context_unref (context);
 
-  /* If we exited on TERM we just exit, if we exited on
-   * HUP we restart the daemon.
-   */
-  if (got_sighup)
-    {
-      /* FIXME execv (argv) basically */
-    }
-  
   return 0;
 }