diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-04-03 05:22:49 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-04-03 05:22:49 +0000 | 
| commit | eeb88949d8d2ca84d9cbe54c07e73b9907d3163e (patch) | |
| tree | 9520b0d32fd0c105f41619f8d247a298f93caf9c | |
| parent | 5364beac6cbfa8793fd34c7a634528a2112787f8 (diff) | |
2003-04-03  Havoc Pennington  <hp@pobox.com>
	* bus/config-parser.c (bus_config_parser_unref): free
	list of mechanisms, bug discovered by test suite enhancements
	(putting system.conf and session.conf into suite)
	* test/Makefile.am, test/test-service.c: add placeholder for a
	test service that we'll activate as part of test suite. Doesn't
	do anything yet.
	* dbus/dbus-sysdeps.c (_dbus_setenv): support unsetenv by
	setting NULL value, and use system malloc not dbus_malloc()
	when we have unavoidable memleakage.
	* dbus/dbus-bus.c (dbus_bus_get): fix bug where bus type of 0
	didn't work, and support DBUS_BUS_ACTIVATION.
	* bus/activation.c (child_setup): pass our well-known bus type to
	the child
	* bus/config-parser.c: support <type> to specify well-known type
	* doc/dbus-specification.sgml: document the env variables to
	locate well-known buses and find service activator
| -rw-r--r-- | ChangeLog | 25 | ||||
| -rw-r--r-- | bus/activation.c | 10 | ||||
| -rw-r--r-- | bus/bus.c | 14 | ||||
| -rw-r--r-- | bus/bus.h | 1 | ||||
| -rw-r--r-- | bus/config-parser.c | 87 | ||||
| -rw-r--r-- | bus/config-parser.h | 1 | ||||
| -rw-r--r-- | bus/session.conf.in | 4 | ||||
| -rw-r--r-- | bus/system.conf.in | 3 | ||||
| -rw-r--r-- | configure.in | 2 | ||||
| -rw-r--r-- | dbus/dbus-bus.c | 188 | ||||
| -rw-r--r-- | dbus/dbus-bus.h | 5 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.c | 73 | ||||
| -rw-r--r-- | doc/config-file.txt | 9 | ||||
| -rw-r--r-- | doc/dbus-specification.sgml | 48 | ||||
| -rw-r--r-- | test/Makefile.am | 8 | ||||
| -rw-r--r-- | test/test-service.c | 30 | 
16 files changed, 426 insertions, 82 deletions
| @@ -1,3 +1,28 @@ +2003-04-03  Havoc Pennington  <hp@pobox.com> + +	* bus/config-parser.c (bus_config_parser_unref): free  +	list of mechanisms, bug discovered by test suite enhancements +	(putting system.conf and session.conf into suite) + +	* test/Makefile.am, test/test-service.c: add placeholder for a +	test service that we'll activate as part of test suite. Doesn't  +	do anything yet. + +	* dbus/dbus-sysdeps.c (_dbus_setenv): support unsetenv by  +	setting NULL value, and use system malloc not dbus_malloc()  +	when we have unavoidable memleakage. + +	* dbus/dbus-bus.c (dbus_bus_get): fix bug where bus type of 0 +	didn't work, and support DBUS_BUS_ACTIVATION. +	 +	* bus/activation.c (child_setup): pass our well-known bus type to +	the child + +	* bus/config-parser.c: support <type> to specify well-known type + +	* doc/dbus-specification.sgml: document the env variables to  +	locate well-known buses and find service activator +  2003-04-02  Havoc Pennington  <hp@redhat.com>  	* test/Makefile.am (all-local): add a rule to copy tests to diff --git a/bus/activation.c b/bus/activation.c index 0dfce3f8..eb56a744 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -404,12 +404,20 @@ static void  child_setup (void *data)  {    BusActivation *activation = data; +  const char *type;    /* If no memory, we simply have the child exit, so it won't try     * to connect to the wrong thing.     */ -  if (!_dbus_setenv ("DBUS_ADDRESS", activation->server_address)) +  if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", activation->server_address))      _dbus_exit (1); + +  type = bus_context_get_type (activation->context); +  if (type != NULL) +    { +      if (!_dbus_setenv ("DBUS_BUS_TYPE", type)) +        _dbus_exit (1); +    }  }  dbus_bool_t @@ -36,6 +36,7 @@  struct BusContext  {    int refcount; +  char *type;    char *address;    DBusList *servers;    BusConnections *connections; @@ -290,6 +291,9 @@ bus_context_new (const DBusString *config_file,        if (!_dbus_change_identity (creds.uid, creds.gid, error))          goto failed;      } + +  /* note that type may be NULL */ +  context->type = _dbus_strdup (bus_config_parser_get_type (parser));    /* We have to build the address backward, so that     * <listen> later in the config file have priority @@ -496,12 +500,20 @@ bus_context_unref (BusContext *context)            _dbus_hash_table_unref (context->rules_by_gid);            context->rules_by_gid = NULL;          } -       + +      dbus_free (context->type);        dbus_free (context->address);        dbus_free (context);      }  } +/* type may be NULL */ +const char* +bus_context_get_type (BusContext *context) +{ +  return context->type; +} +  BusRegistry*  bus_context_get_registry (BusContext  *context)  { @@ -43,6 +43,7 @@ BusContext*     bus_context_new                      (const DBusString *config_f  void            bus_context_shutdown                 (BusContext       *context);  void            bus_context_ref                      (BusContext       *context);  void            bus_context_unref                    (BusContext       *context); +const char*     bus_context_get_type                 (BusContext       *context);  BusRegistry*    bus_context_get_registry             (BusContext       *context);  BusConnections* bus_context_get_connections          (BusContext       *context);  BusActivation*  bus_context_get_activation           (BusContext       *context); diff --git a/bus/config-parser.c b/bus/config-parser.c index 9e16e4fc..f9473ff9 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -41,7 +41,8 @@ typedef enum    ELEMENT_DENY,    ELEMENT_FORK,    ELEMENT_SERVICEDIR, -  ELEMENT_INCLUDEDIR +  ELEMENT_INCLUDEDIR, +  ELEMENT_TYPE  } ElementType;  typedef struct @@ -59,11 +60,6 @@ typedef struct      struct      { -      char *mechanism; -    } auth; - -    struct -    {        char *context;        char *user;        char *group; @@ -89,6 +85,8 @@ struct BusConfigParser    char *user;          /**< user to run as */ +  char *bus_type;          /**< Message bus type */ +      DBusList *listen_on; /**< List of addresses to listen to */    DBusList *mechanisms; /**< Auth mechanisms */ @@ -129,6 +127,8 @@ element_type_to_name (ElementType type)        return "servicedir";      case ELEMENT_INCLUDEDIR:        return "includedir"; +    case ELEMENT_TYPE: +      return "type";      }    _dbus_assert_not_reached ("bad element type"); @@ -213,6 +213,13 @@ merge_included (BusConfigParser *parser,        included->user = NULL;      } +  if (included->bus_type != NULL) +    { +      dbus_free (parser->bus_type); +      parser->bus_type = included->bus_type; +      included->bus_type = NULL; +    } +      if (included->fork)      parser->fork = TRUE; @@ -276,7 +283,8 @@ bus_config_parser_unref (BusConfigParser *parser)          pop_element (parser);        dbus_free (parser->user); - +      dbus_free (parser->bus_type); +              _dbus_list_foreach (&parser->listen_on,                            (DBusForeachFunction) dbus_free,                            NULL); @@ -289,6 +297,12 @@ bus_config_parser_unref (BusConfigParser *parser)        _dbus_list_clear (&parser->service_dirs); +      _dbus_list_foreach (&parser->mechanisms, +                          (DBusForeachFunction) dbus_free, +                          NULL); + +      _dbus_list_clear (&parser->mechanisms); +              _dbus_string_free (&parser->basedir);        dbus_free (parser); @@ -451,7 +465,20 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_USER) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error); +          return FALSE; +        } + +      return TRUE; +    } +  else if (strcmp (element_name, "type") == 0) +    { +      if (!check_no_attributes (parser, "type", attribute_names, attribute_values, error)) +        return FALSE; + +      if (push_element (parser, ELEMENT_TYPE) == NULL) +        { +          BUS_SET_OOM (error);            return FALSE;          } @@ -464,7 +491,7 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_FORK) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -479,7 +506,7 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_LISTEN) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -492,7 +519,7 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_AUTH) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -505,7 +532,7 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_INCLUDEDIR) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -518,7 +545,7 @@ start_busconfig_child (BusConfigParser   *parser,        if (push_element (parser, ELEMENT_SERVICEDIR) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -531,7 +558,7 @@ start_busconfig_child (BusConfigParser   *parser,        if ((e = push_element (parser, ELEMENT_INCLUDE)) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -570,7 +597,7 @@ start_busconfig_child (BusConfigParser   *parser,        if ((e = push_element (parser, ELEMENT_POLICY)) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -608,7 +635,7 @@ start_policy_child (BusConfigParser   *parser,      {        if (push_element (parser, ELEMENT_ALLOW) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -618,7 +645,7 @@ start_policy_child (BusConfigParser   *parser,      {        if (push_element (parser, ELEMENT_DENY) == NULL)          { -          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +          BUS_SET_OOM (error);            return FALSE;          } @@ -657,7 +684,7 @@ bus_config_parser_start_element (BusConfigParser   *parser,            if (push_element (parser, ELEMENT_BUSCONFIG) == NULL)              { -              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +              BUS_SET_OOM (error);                return FALSE;              } @@ -725,7 +752,8 @@ bus_config_parser_end_element (BusConfigParser   *parser,         * being paranoid about XML parsers         */        dbus_set_error (error, DBUS_ERROR_FAILED, -                      "XML element ended which was not the topmost element on the stack"); +                      "XML element <%s> ended but topmost element on the stack was <%s>", +                      element_name, n);        return FALSE;      } @@ -740,6 +768,7 @@ bus_config_parser_end_element (BusConfigParser   *parser,      case ELEMENT_INCLUDE:      case ELEMENT_USER: +    case ELEMENT_TYPE:      case ELEMENT_LISTEN:      case ELEMENT_AUTH:      case ELEMENT_SERVICEDIR: @@ -1040,6 +1069,20 @@ bus_config_parser_content (BusConfigParser   *parser,        }        break; +    case ELEMENT_TYPE: +      { +        char *s; + +        e->had_content = TRUE; + +        if (!_dbus_string_copy_data (content, &s)) +          goto nomem; +         +        dbus_free (parser->bus_type); +        parser->bus_type = s; +      } +      break; +            case ELEMENT_LISTEN:        {          char *s; @@ -1149,6 +1192,12 @@ bus_config_parser_get_user (BusConfigParser *parser)    return parser->user;  } +const char* +bus_config_parser_get_type (BusConfigParser *parser) +{ +  return parser->bus_type; +} +  DBusList**  bus_config_parser_get_addresses (BusConfigParser *parser)  { diff --git a/bus/config-parser.h b/bus/config-parser.h index 9b433f04..af5c8260 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -56,6 +56,7 @@ dbus_bool_t      bus_config_parser_finished      (BusConfigParser   *parser,  /* Functions for extracting the parse results */  const char* bus_config_parser_get_user         (BusConfigParser *parser); +const char* bus_config_parser_get_type         (BusConfigParser *parser);  DBusList**  bus_config_parser_get_addresses    (BusConfigParser *parser);  DBusList**  bus_config_parser_get_mechanisms   (BusConfigParser *parser);  dbus_bool_t bus_config_parser_get_fork         (BusConfigParser *parser); diff --git a/bus/session.conf.in b/bus/session.conf.in index fe7aa5f0..28478955 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -5,6 +5,9 @@  <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"   "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">  <busconfig> +  <!-- Our well-known bus type, don't change this --> +  <type>session</type> +    <!-- FIXME - this is fairly complicated to fix.         Propose the following:           - add "unix:tmpdir=/tmp" which means unix domain transport  @@ -18,6 +21,7 @@             reads the address from there and sets the env variable      -->    <listen>unix:path=/tmp/foobar</listen> +    <policy context="default">      <!-- Allow everything -->      <allow send="*"/> diff --git a/bus/system.conf.in b/bus/system.conf.in index 7752b576..15a4972e 100644 --- a/bus/system.conf.in +++ b/bus/system.conf.in @@ -11,6 +11,9 @@   "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">  <busconfig> +  <!-- Our well-known bus type, do not change this --> +  <type>system</type> +    <!-- Run as special user -->    <user>messagebus</user> diff --git a/configure.in b/configure.in index 46e18707..fbf60d78 100644 --- a/configure.in +++ b/configure.in @@ -139,7 +139,7 @@ AC_C_BIGENDIAN  AC_CHECK_LIB(socket,socket)  AC_CHECK_LIB(nsl,gethostbyname) -AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv socketpair getgrouplist) +AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv unsetenv socketpair getgrouplist)  AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)]) diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index d65a3f0f..dc1762eb 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -25,6 +25,7 @@  #include "dbus-bus.h"  #include "dbus-protocol.h"  #include "dbus-internals.h" +#include <string.h>  /**   * @defgroup DBusBus Message bus APIs @@ -61,11 +62,132 @@ static int bus_data_slot = -1;   */  static int bus_data_slot_refcount = 0; +/** Number of bus types */ +#define N_BUS_TYPES 3 + +static DBusConnection *bus_connections[N_BUS_TYPES]; +static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL }; + +static DBusBusType activation_bus_type = DBUS_BUS_ACTIVATION; + +static dbus_bool_t initialized = FALSE; +  /** - * Lock for bus_data_slot and bus_data_slot_refcount + * Lock for globals in this file   */  _DBUS_DEFINE_GLOBAL_LOCK (bus); +static void +addresses_shutdown_func (void *data) +{ +  int i; + +  i = 0; +  while (i < N_BUS_TYPES) +    { +      if (bus_connections[i] != NULL) +        _dbus_warn ("dbus_shutdown() called but connections were still live!"); +       +      dbus_free (bus_connection_addresses[i]); +      bus_connection_addresses[i] = NULL; +      ++i; +    } + +  activation_bus_type = DBUS_BUS_ACTIVATION; +} + +static dbus_bool_t +get_from_env (char           **connection_p, +              const char      *env_var) +{ +  const char *s; +   +  _dbus_assert (*connection_p == NULL); +   +  s = _dbus_getenv (env_var); +  if (s == NULL || *s == '\0') +    return TRUE; /* successfully didn't use the env var */ +  else +    { +      *connection_p = _dbus_strdup (s); +      return *connection_p != NULL; +    } +} + +static dbus_bool_t +init_connections_unlocked (void) +{ +  if (!initialized) +    { +      const char *s; +       +      bus_connections[0] = NULL; +      bus_connections[1] = NULL; +      bus_connections[2] = NULL; + +      /* Don't init these twice, we may run this code twice if +       * init_connections_unlocked() fails midway through. +       */ +       +       if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) +         { +           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM], +                              "DBUS_SYSTEM_BUS_ADDRESS")) +             return FALSE; +            +           if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) +             { +               /* Use default system bus address if none set in environment */ +               bus_connection_addresses[DBUS_BUS_SYSTEM] = +                 _dbus_strdup ("unix:path=" DBUS_SYSTEM_BUS_PATH); +               if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) +                 return FALSE; +             } +         } +           +      if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) +        { +          if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION], +                             "DBUS_SESSION_BUS_ADDRESS")) +            return FALSE; +        } + +      if (bus_connection_addresses[DBUS_BUS_ACTIVATION] == NULL) +        { +          if (!get_from_env (&bus_connection_addresses[DBUS_BUS_ACTIVATION], +                             "DBUS_ACTIVATION_ADDRESS")) +            return FALSE; +        } + +      s = _dbus_getenv ("DBUS_ACTIVATION_BUS_TYPE"); + +      if (s != NULL) +        { +          if (strcmp (s, "system") == 0) +            activation_bus_type = DBUS_BUS_SYSTEM; +          else if (strcmp (s, "session") == 0) +            activation_bus_type = DBUS_BUS_SESSION; +        } + +      /* If we return FALSE we have to be sure that restarting +       * the above code will work right +       */ +       +      if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL)) +        return FALSE; + +      if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL)) +        return FALSE; +       +      if (!_dbus_register_shutdown_func (addresses_shutdown_func, +                                         NULL)) +        return FALSE; +       +      initialized = TRUE; +    } + +  return initialized; +}  static dbus_bool_t  data_slot_ref (void) @@ -172,11 +294,6 @@ ensure_bus_data (DBusConnection *connection)   * @{   */ -/** Number of bus types */ -#define BUS_TYPES 2 - -static DBusConnection *bus_connections[BUS_TYPES]; -  /**   * Connects to a bus daemon and registers the client with it.   * If a connection to the bus already exists, then that connection is returned. @@ -191,11 +308,14 @@ DBusConnection *  dbus_bus_get (DBusBusType  type,  	      DBusError   *error)  { -  const char *name, *value; +  const char *address;    DBusConnection *connection;    BusData *bd; +  DBusBusType address_type; -  if (type <= 0 || type >= BUS_TYPES) +  _DBUS_ASSERT_ERROR_IS_CLEAR (error); +   +  if (type < 0 || type >= N_BUS_TYPES)      {        _dbus_assert_not_reached ("Invalid bus type specified."); @@ -203,6 +323,26 @@ dbus_bus_get (DBusBusType  type,      }    _DBUS_LOCK (bus); + +  if (!init_connections_unlocked ()) +    { +      _DBUS_UNLOCK (bus); +      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +      return NULL; +    } + +  /* We want to use the activation address even if the +   * activating bus is the session or system bus, +   * per the spec. +   */ +  address_type = type; +   +  /* Use the real type of the activation bus for getting its +   * connection. (If the activating bus isn't a well-known +   * bus then activation_bus_type == DBUS_BUS_ACTIVATION) +   */ +  if (type == DBUS_BUS_ACTIVATION) +    type = activation_bus_type;    if (bus_connections[type] != NULL)      { @@ -213,45 +353,27 @@ dbus_bus_get (DBusBusType  type,        return connection;      } -  switch (type) -    { -    case DBUS_BUS_SESSION: -      name = "DBUS_SESSION_BUS_ADDRESS"; -      break; -    case DBUS_BUS_SYSTEM: -      name = "DBUS_SYSTEM_BUS_ADDRESS"; -      break; -    } - -  value = _dbus_getenv (name); - -  if (type == DBUS_BUS_SYSTEM && -      (value == NULL || *value == '\0')) -    { -      /* Use default system bus address if none set */ -      value = "unix:path=" DBUS_SYSTEM_BUS_PATH; -    } -   -  if (value == NULL || *value == '\0') +  address = bus_connection_addresses[address_type]; +  if (address == NULL)      {        dbus_set_error (error, DBUS_ERROR_FAILED, -		      "Environment variable %s not set, address of message bus unknown", -                      name); +                      "Unable to determine the address of the message bus");        _DBUS_UNLOCK (bus); -              return NULL;      } -  connection = dbus_connection_open (value, error); +  connection = dbus_connection_open (address, error);    if (!connection)      { +      _DBUS_ASSERT_ERROR_IS_SET (error);        _DBUS_UNLOCK (bus);        return NULL;      }    if (!dbus_bus_register (connection, error))      { +      _DBUS_ASSERT_ERROR_IS_SET (error);        dbus_connection_disconnect (connection);        dbus_connection_unref (connection); @@ -265,7 +387,7 @@ dbus_bus_get (DBusBusType  type,    bd->connection = &bus_connections[type]; -  _DBUS_UNLOCK (bus);   +  _DBUS_UNLOCK (bus);    return connection;  } diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h index 508dc5b1..e3ec054c 100644 --- a/dbus/dbus-bus.h +++ b/dbus/dbus-bus.h @@ -33,8 +33,9 @@ DBUS_BEGIN_DECLS;  typedef enum  { -  DBUS_BUS_SESSION, /**< The login session bus */ -  DBUS_BUS_SYSTEM /**< The system bus */ +  DBUS_BUS_SESSION,    /**< The login session bus */ +  DBUS_BUS_SYSTEM,     /**< The systemwide bus */ +  DBUS_BUS_ACTIVATION  /**< The bus that activated us, if any */  } DBusBusType;  DBusConnection *dbus_bus_get              (DBusBusType     type, diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 4798aa73..17da1fbe 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -82,37 +82,76 @@ _dbus_abort (void)  }  /** - * Wrapper for setenv(). + * Wrapper for setenv(). If the value is #NULL, unsets + * the environment variable. + * + * @todo if someone can verify it's safe, we could avoid the + * memleak when doing an unset.   *   * @param varname name of environment variable   * @param value value of environment variable   * @returns #TRUE on success.   */  dbus_bool_t -_dbus_setenv (const char *varname, const char *value) +_dbus_setenv (const char *varname, +              const char *value)  { -#ifdef HAVE_SETENV -  return (setenv (varname, value, TRUE) == 0); +  _dbus_assert (varname != NULL); +   +  if (value == NULL) +    { +#ifdef HAVE_UNSETENV +      unsetenv (varname); +      return TRUE;  #else -  DBusString str; -  char *putenv_value; +      char *putenv_value; +      size_t len; -  if (!_dbus_string_init (&str)) -    return FALSE; +      len = strlen (varname); -  if (!_dbus_string_append (&str, varname) || -      !_dbus_string_append (&str, "=") || -      !_dbus_string_append (&str, value) || -      !_dbus_string_steal_data (&str, &putenv_value)) -    { -      _dbus_string_free (&str); -      return FALSE; +      /* Use system malloc to avoid memleaks that dbus_malloc +       * will get upset about. +       */ +       +      putenv_value = malloc (len + 1); +      if (putenv_value == NULL) +        return FALSE; + +      strcpy (putenv_value, varname); +       +      return (putenv (putenv_value) == 0); +#endif      } +  else +    { +#ifdef HAVE_SETENV +      return (setenv (varname, value, TRUE) == 0); +#else +      char *putenv_value; +      size_t len; +      size_t varname_len; +      size_t value_len; + +      varname_len = strlen (varname); +      value_len = strlen (value); +       +      len = varname_len + value_len + 1 /* '=' */ ; -  _dbus_string_free (&str); +      /* Use system malloc to avoid memleaks that dbus_malloc +       * will get upset about. +       */ +       +      putenv_value = malloc (len + 1); +      if (putenv_value == NULL) +        return FALSE; -  return (putenv (putenv_value) == 0); +      strcpy (putenv_value, varname); +      strcpy (putenv_value + varname_len, "="); +      strcpy (putenv_value + varname_len + 1, value); +       +      return (putenv (putenv_value) == 0);  #endif +    }  }  /** diff --git a/doc/config-file.txt b/doc/config-file.txt index b8230aab..8c2152b5 100644 --- a/doc/config-file.txt +++ b/doc/config-file.txt @@ -27,6 +27,15 @@ Elements:      Root element. + <type> + +    The well-known type of the message bus. Currently known values +    are "system" and "session"; if other values are set, they should  +    be either added to the D-BUS specification, or namespaced. +    The last <type> element "wins" + +    Example: <type>session</type> +   <include>    ignore_missing="(yes|no)"   optional attribute, defaults to no diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index 5d150e86..7e2fcb35 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -1235,10 +1235,22 @@        </para>        <para>          The executable launched will have the environment variable -        <literal>DBUS_BUS_ADDRESS</literal> set to the address of the +        <literal>DBUS_ACTIVATION_ADDRESS</literal> set to the address of the          message bus so it can connect and register the appropriate services.        </para>        <para> +        The executable being launched may want to know whether the message bus +        activating it is one of the well-known message buses (see <xref +        linkend="message-bus-types">). To facilitate this, the bus MUST also set +        the <literal>DBUS_ACTIVATION_BUS_TYPE</literal> environment variable if it is one +        of the well-known buses. The currently-defined values for this variable +        are <literal>system</literal> for the systemwide message bus, +        and <literal>session</literal> for the per-login-session message +        bus. The activated executable must still connect to the address given +        in <literal>DBUS_ACTIVATION_ADDRESS</literal>, but may assume that the +        resulting connection is to the well-known bus. +      </para> +      <para>          [FIXME there should be a timeout somewhere, either specified          in the .service file, by the client, or just a global value          and if the client being activated fails to connect within that @@ -1247,7 +1259,7 @@      </sect2>      <sect2 id="message-bus-types"> -      <title>Standard Message Bus Instances</title> +      <title>Well-known Message Bus Instances</title>        <para>          Two standard message bus instances are defined here, along with how           to locate them and where their service files live. @@ -1257,9 +1269,17 @@          <para>            Each time a user logs in, a <firstterm>login session message              bus</firstterm> may be started. All applications in the user's login -          session may interact with one another using this message bus.  [specify -          how to find the address of the login session message bus via -          environment variable and/or X property] +          session may interact with one another using this message bus. +        </para> +        <para> +          The address of the login session message bus is given  +          in the <literal>DBUS_SESSION_BUS_ADDRESS</literal> environment  +          variable. If that variable is not set, applications may  +          also try to read the address from the X Window System root  +          window property <literal>_DBUS_SESSION_BUS_ADDRESS</literal>. +          The root window property must have type <literal>STRING</literal>. +          The environment variable should have precedence over the  +          root window property.          </para>          <para>            [FIXME specify location of .service files, probably using  @@ -1272,8 +1292,22 @@          <para>            A computer may have a <firstterm>system message bus</firstterm>,            accessible to all applications on the system. This message bus may be -          used to broadcast system events, such as adding new hardware devices. -          [specify how to find the address of the system message bus] +          used to broadcast system events, such as adding new hardware devices,  +          changes in the printer queue, and so forth. +        </para> +        <para> +          The address of the login session message bus is given  +          in the <literal>DBUS_SYSTEM_BUS_ADDRESS</literal> environment  +          variable. If that variable is not set, applications should try  +          to connect to the well-known address +          <literal>unix:path=/var/run/dbus/system_bus_socket</literal>. +          <footnote> +            <para> +              The D-BUS reference implementation actually honors the  +              <literal>$(localstatedir)</literal> configure option  +              for this address, on both client and server side. +            </para> +          </footnote>          </para>          <para>            [FIXME specify location of system bus .service files] diff --git a/test/Makefile.am b/test/Makefile.am index 3ca62d65..46a66dbc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,7 +2,7 @@  INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS)   if DBUS_BUILD_TESTS -TEST_BINARIES=echo-client echo-server unbase64 break-loader spawn-test +TEST_BINARIES=test-service echo-client echo-server unbase64 break-loader spawn-test  else  TEST_BINARIES=  endif @@ -19,6 +19,11 @@ echo_server_SOURCES=				\  	watch.c					\  	watch.h +test_service_SOURCES=				\ +	test-service.c				\ +	watch.c					\ +	watch.h +  unbase64_SOURCES=				\  	unbase64.c @@ -39,6 +44,7 @@ TEST_LIBS=$(DBUS_TEST_LIBS) $(top_builddir)/dbus/libdbus-convenience.la  echo_client_LDADD=$(TEST_LIBS)  echo_server_LDADD=$(TEST_LIBS) +test_service_LDADD=$(TEST_LIBS)  unbase64_LDADD=$(TEST_LIBS)  break_loader_LDADD= $(TEST_LIBS)  #bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la diff --git a/test/test-service.c b/test/test-service.c new file mode 100644 index 00000000..a4dff0b3 --- /dev/null +++ b/test/test-service.c @@ -0,0 +1,30 @@ +#include <dbus/dbus.h> +#include <stdio.h> +#include "watch.h" + +int +main (int    argc, +      char **argv) +{ +  DBusConnection *connection; +  DBusError error; +  DBusMessage *message; + +  dbus_error_init (&error); +  connection = dbus_bus_get (DBUS_BUS_ACTIVATION, &error); +  if (connection == NULL) +    { +      fprintf (stderr, "Failed to open connection to activating message bus: %s\n", +               error.message); +      dbus_error_free (&error); +      return 1; +    } + +  setup_connection (connection); +   +  do_mainloop (); + +  dbus_connection_unref (connection); +   +  return 0; +} | 
