mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-01-11 06:20:17 +01:00
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
This commit is contained in:
parent
5364beac6c
commit
eeb88949d8
16 changed files with 429 additions and 85 deletions
25
ChangeLog
25
ChangeLog
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
14
bus/bus.c
14
bus/bus.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ typedef enum
|
|||
ELEMENT_DENY,
|
||||
ELEMENT_FORK,
|
||||
ELEMENT_SERVICEDIR,
|
||||
ELEMENT_INCLUDEDIR
|
||||
ELEMENT_INCLUDEDIR,
|
||||
ELEMENT_TYPE
|
||||
} ElementType;
|
||||
|
||||
typedef struct
|
||||
|
|
@ -57,11 +58,6 @@ typedef struct
|
|||
unsigned int ignore_missing : 1;
|
||||
} include;
|
||||
|
||||
struct
|
||||
{
|
||||
char *mechanism;
|
||||
} auth;
|
||||
|
||||
struct
|
||||
{
|
||||
char *context;
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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="*"/>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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)])
|
||||
|
||||
|
|
|
|||
188
dbus/dbus-bus.c
188
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
#else
|
||||
DBusString str;
|
||||
char *putenv_value;
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
return FALSE;
|
||||
|
||||
if (!_dbus_string_append (&str, varname) ||
|
||||
!_dbus_string_append (&str, "=") ||
|
||||
!_dbus_string_append (&str, value) ||
|
||||
!_dbus_string_steal_data (&str, &putenv_value))
|
||||
_dbus_assert (varname != NULL);
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
_dbus_string_free (&str);
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef HAVE_UNSETENV
|
||||
unsetenv (varname);
|
||||
return TRUE;
|
||||
#else
|
||||
char *putenv_value;
|
||||
size_t len;
|
||||
|
||||
_dbus_string_free (&str);
|
||||
len = strlen (varname);
|
||||
|
||||
return (putenv (putenv_value) == 0);
|
||||
/* 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 /* '=' */ ;
|
||||
|
||||
/* 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);
|
||||
strcpy (putenv_value + varname_len, "=");
|
||||
strcpy (putenv_value + varname_len + 1, value);
|
||||
|
||||
return (putenv (putenv_value) == 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1235,9 +1235,21 @@
|
|||
</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
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
30
test/test-service.c
Normal file
30
test/test-service.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue