Commit 9c3d566e authored by Havoc Pennington's avatar Havoc Pennington

2005-01-15 Havoc Pennington <hp@redhat.com>

	* Land the new message args API and type system.

	This patch is huge, but the public API change is not
	really large. The set of D-BUS types has changed somewhat,
	and the arg "getters" are more geared toward language bindings;
	they don't make a copy, etc.

	There are also some known issues. See these emails for details
	on this huge patch:
	http://lists.freedesktop.org/archives/dbus/2004-December/001836.html
        http://lists.freedesktop.org/archives/dbus/2005-January/001922.html

	* dbus/dbus-marshal-*: all the new stuff

	* dbus/dbus-message.c: basically rewritten

	* dbus/dbus-memory.c (check_guards): with "guards" enabled, init
	freed blocks to be all non-nul bytes so using freed memory is less
	likely to work right

	* dbus/dbus-internals.c (_dbus_test_oom_handling): add
	DBUS_FAIL_MALLOC=N environment variable, so you can do
	DBUS_FAIL_MALLOC=0 to skip the out-of-memory checking, or
	DBUS_FAIL_MALLOC=10 to make it really, really, really slow and
	thorough.

	* qt/message.cpp: port to the new message args API
	(operator<<): use str.utf8() rather than str.unicode()
	(pretty sure this is right from the Qt docs?)

	* glib/dbus-gvalue.c: port to the new message args API

	* bus/dispatch.c, bus/driver.c: port to the new message args API

	* dbus/dbus-string.c (_dbus_string_init_const_len): initialize the
	"locked" flag to TRUE and align_offset to 0; I guess we never
	looked at these anyhow, but seems cleaner.

	* dbus/dbus-string.h (_DBUS_STRING_ALLOCATION_PADDING):
	move allocation padding macro to this header; use it to implement
	(_DBUS_STRING_STATIC): ability to declare a static string.

	* dbus/dbus-message.c (_dbus_message_has_type_interface_member):
	change to return TRUE if the interface is not set.

	* dbus/dbus-string.[hc]: move the D-BUS specific validation stuff
	to dbus-marshal-validate.[hc]

	* dbus/dbus-marshal-basic.c (_dbus_type_to_string): move here from
	dbus-internals.c

	* dbus/Makefile.am: cut over from dbus-marshal.[hc]
	to dbus-marshal-*.[hc]

	* dbus/dbus-object-tree.c (_dbus_decompose_path): move this
	function here from dbus-marshal.c
parent 6ec04e91
2005-01-15 Havoc Pennington <hp@redhat.com>
* Land the new message args API and type system.
This patch is huge, but the public API change is not
really large. The set of D-BUS types has changed somewhat,
and the arg "getters" are more geared toward language bindings;
they don't make a copy, etc.
There are also some known issues. See these emails for details
on this huge patch:
http://lists.freedesktop.org/archives/dbus/2004-December/001836.html
http://lists.freedesktop.org/archives/dbus/2005-January/001922.html
* dbus/dbus-marshal-*: all the new stuff
* dbus/dbus-message.c: basically rewritten
* dbus/dbus-memory.c (check_guards): with "guards" enabled, init
freed blocks to be all non-nul bytes so using freed memory is less
likely to work right
* dbus/dbus-internals.c (_dbus_test_oom_handling): add
DBUS_FAIL_MALLOC=N environment variable, so you can do
DBUS_FAIL_MALLOC=0 to skip the out-of-memory checking, or
DBUS_FAIL_MALLOC=10 to make it really, really, really slow and
thorough.
* qt/message.cpp: port to the new message args API
(operator<<): use str.utf8() rather than str.unicode()
(pretty sure this is right from the Qt docs?)
* glib/dbus-gvalue.c: port to the new message args API
* bus/dispatch.c, bus/driver.c: port to the new message args API
* dbus/dbus-string.c (_dbus_string_init_const_len): initialize the
"locked" flag to TRUE and align_offset to 0; I guess we never
looked at these anyhow, but seems cleaner.
* dbus/dbus-string.h (_DBUS_STRING_ALLOCATION_PADDING):
move allocation padding macro to this header; use it to implement
(_DBUS_STRING_STATIC): ability to declare a static string.
* dbus/dbus-message.c (_dbus_message_has_type_interface_member):
change to return TRUE if the interface is not set.
* dbus/dbus-string.[hc]: move the D-BUS specific validation stuff
to dbus-marshal-validate.[hc]
* dbus/dbus-marshal-basic.c (_dbus_type_to_string): move here from
dbus-internals.c
* dbus/Makefile.am: cut over from dbus-marshal.[hc]
to dbus-marshal-*.[hc]
* dbus/dbus-object-tree.c (_dbus_decompose_path): move this
function here from dbus-marshal.c
2005-01-12 Joe Shaw <joeshaw@novell.com>
* NEWS: Update for 0.23.
......
......@@ -127,6 +127,17 @@ dbus_realloc to fail if the number of bytes to be allocated is greater
than the specified number. This only works if D-BUS has been compiled with
--enable-tests.
DBUS_TEST_MALLOC_FAILURES=n
Many of the D-BUS tests will run over and over, once for each malloc
involved in the test. Each run will fail a different malloc, plus some
number of mallocs following that malloc (because a fair number of bugs
only happen if two or more mallocs fail in a row, e.g. error recovery
that itself involves malloc). This env variable sets the number of
mallocs to fail.
Here's why you care: If set to 0, then the malloc checking is skipped,
which makes the test suite a heck of a lot faster. Just run with this
env variable unset before you commit.
Tests
===
......
......@@ -93,6 +93,7 @@ typedef struct
unsigned int timeout_added : 1;
} BusPendingActivation;
#if 0
static BusServiceDirectory *
bus_service_directory_ref (BusServiceDirectory *dir)
{
......@@ -102,6 +103,7 @@ bus_service_directory_ref (BusServiceDirectory *dir)
return dir;
}
#endif
static void
bus_service_directory_unref (BusServiceDirectory *dir)
......@@ -909,6 +911,8 @@ bus_activation_service_created (BusActivation *activation,
/* Only send activation replies to regular activation requests. */
if (!entry->auto_activation)
{
dbus_uint32_t result;
message = dbus_message_new_method_return (entry->activation_message);
if (!message)
{
......@@ -916,8 +920,10 @@ bus_activation_service_created (BusActivation *activation,
goto error;
}
result = DBUS_ACTIVATION_REPLY_ACTIVATED;
if (!dbus_message_append_args (message,
DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,
DBUS_TYPE_UINT32, &result,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -1328,6 +1334,8 @@ bus_activation_activate_service (BusActivation *activation,
_dbus_string_init_const (&service_str, service_name);
if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
{
dbus_uint32_t result;
_dbus_verbose ("Service \"%s\" is already active\n", service_name);
message = dbus_message_new_method_return (activation_message);
......@@ -1339,8 +1347,10 @@ bus_activation_activate_service (BusActivation *activation,
return FALSE;
}
result = DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE;
if (!dbus_message_append_args (message,
DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE,
DBUS_TYPE_UINT32, &result,
DBUS_TYPE_INVALID))
{
_dbus_verbose ("No memory to set args of reply to activate message\n");
......
......@@ -1398,6 +1398,7 @@ bus_pending_reply_send_no_reply (BusConnections *connections,
DBusMessage *message;
DBusMessageIter iter;
dbus_bool_t retval;
const char *errmsg;
retval = FALSE;
......@@ -1415,8 +1416,9 @@ bus_pending_reply_send_no_reply (BusConnections *connections,
DBUS_ERROR_NO_REPLY))
goto out;
errmsg = "Message did not receive a reply (timeout by message bus)";
dbus_message_append_iter_init (message, &iter);
if (!dbus_message_iter_append_string (&iter, "Message did not receive a reply (timeout by message bus)"))
if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &errmsg))
goto out;
if (!bus_transaction_send_from_driver (transaction, pending->will_get_reply,
......
......@@ -2,7 +2,7 @@
/* dispatch.c Message dispatcher
*
* Copyright (C) 2003 CodeFactory AB
* Copyright (C) 2003, 2004 Red Hat, Inc.
* Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
* Copyright (C) 2004 Imendio HB
*
* Licensed under the Academic Free License version 2.1
......@@ -526,7 +526,7 @@ check_service_owner_changed_foreach (DBusConnection *connection,
CheckServiceOwnerChangedData *d = data;
DBusMessage *message;
DBusError error;
char *service_name, *old_owner, *new_owner;
const char *service_name, *old_owner, *new_owner;
if (d->expected_kind == SERVICE_CREATED
&& connection == d->skip_connection)
......@@ -567,9 +567,6 @@ check_service_owner_changed_foreach (DBusConnection *connection,
{
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (new_owner);
dbus_error_free (&error);
_dbus_wait_for_memory ();
goto reget_service_info_data;
......@@ -609,9 +606,6 @@ check_service_owner_changed_foreach (DBusConnection *connection,
d->failed = FALSE;
out:
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (new_owner);
dbus_error_free (&error);
if (message)
......@@ -725,7 +719,11 @@ check_no_leftovers (BusContext *context)
&nmd);
if (nmd.failed)
{
_dbus_verbose ("%s: leftover message found\n",
_DBUS_FUNCTION_NAME);
return FALSE;
}
else
return TRUE;
}
......@@ -738,17 +736,19 @@ check_hello_message (BusContext *context,
DBusConnection *connection)
{
DBusMessage *message;
DBusMessage *name_message;
dbus_uint32_t serial;
dbus_bool_t retval;
DBusError error;
char *name;
char *acquired;
const char *name;
const char *acquired;
retval = FALSE;
dbus_error_init (&error);
name = NULL;
acquired = NULL;
message = NULL;
name_message = NULL;
_dbus_verbose ("check_hello_message for %p\n", connection);
......@@ -890,8 +890,9 @@ check_hello_message (BusContext *context,
if (socd.failed)
goto out;
name_message = message;
/* Client should also have gotten ServiceAcquired */
dbus_message_unref (message);
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
......@@ -935,6 +936,7 @@ check_hello_message (BusContext *context,
acquired, name);
goto out;
}
acquired = NULL;
}
if (!check_no_leftovers (context))
......@@ -943,14 +945,16 @@ check_hello_message (BusContext *context,
retval = TRUE;
out:
dbus_error_free (&error);
_dbus_verbose ("ending %s retval = %d\n", _DBUS_FUNCTION_NAME, retval);
dbus_free (name);
dbus_free (acquired);
dbus_error_free (&error);
if (message)
dbus_message_unref (message);
if (name_message)
dbus_message_unref (name_message);
return retval;
}
......@@ -1075,7 +1079,7 @@ check_get_connection_unix_user (BusContext *context,
base_service_name = dbus_bus_get_base_service (connection);
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, base_service_name,
DBUS_TYPE_STRING, &base_service_name,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -1212,7 +1216,7 @@ check_get_connection_unix_process_id (BusContext *context,
base_service_name = dbus_bus_get_base_service (connection);
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, base_service_name,
DBUS_TYPE_STRING, &base_service_name,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -1344,6 +1348,7 @@ check_add_match_all (BusContext *context,
dbus_bool_t retval;
dbus_uint32_t serial;
DBusError error;
const char *empty = "";
retval = FALSE;
dbus_error_init (&error);
......@@ -1360,7 +1365,7 @@ check_add_match_all (BusContext *context,
return TRUE;
/* empty string match rule matches everything */
if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -1525,6 +1530,8 @@ check_nonexistent_service_activation (BusContext *context,
DBusMessage *message;
dbus_uint32_t serial;
dbus_bool_t retval;
const char *nonexistent = NONEXISTENT_SERVICE_NAME;
dbus_uint32_t flags;
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
......@@ -1534,9 +1541,10 @@ check_nonexistent_service_activation (BusContext *context,
if (message == NULL)
return TRUE;
flags = 0;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
DBUS_TYPE_UINT32, 0,
DBUS_TYPE_STRING, &nonexistent,
DBUS_TYPE_UINT32, &flags,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -1715,12 +1723,12 @@ static dbus_bool_t
check_base_service_activated (BusContext *context,
DBusConnection *connection,
DBusMessage *initial_message,
char **base_service_p)
const char **base_service_p)
{
DBusMessage *message;
dbus_bool_t retval;
DBusError error;
char *base_service, *base_service_from_bus, *old_owner;
const char *base_service, *base_service_from_bus, *old_owner;
retval = FALSE;
......@@ -1752,9 +1760,6 @@ check_base_service_activated (BusContext *context,
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
dbus_error_free (&error);
dbus_free (base_service);
dbus_free (old_owner);
dbus_free (base_service_from_bus);
_dbus_wait_for_memory ();
goto reget_service_name_arg;
}
......@@ -1805,20 +1810,14 @@ check_base_service_activated (BusContext *context,
goto out;
}
retval = TRUE;
if (base_service_p)
{
*base_service_p = base_service;
base_service = NULL;
}
retval = TRUE;
out:
if (message)
dbus_message_unref (message);
dbus_free (base_service);
dbus_free (base_service_from_bus);
dbus_free (old_owner);
dbus_error_free (&error);
return retval;
......@@ -1848,7 +1847,7 @@ check_service_activated (BusContext *context,
"ServiceOwnerChanged"))
{
CheckServiceOwnerChangedData socd;
char *service_name, *base_service_from_bus, *old_owner;
const char *service_name, *base_service_from_bus, *old_owner;
reget_service_name_arg:
service_name = NULL;
......@@ -1864,9 +1863,6 @@ check_service_activated (BusContext *context,
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
dbus_error_free (&error);
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (base_service_from_bus);
_dbus_wait_for_memory ();
goto reget_service_name_arg;
}
......@@ -1875,9 +1871,6 @@ check_service_activated (BusContext *context,
_dbus_warn ("Message %s doesn't have a service name: %s\n",
"ServiceOwnerChanged (creation)",
error.message);
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (base_service_from_bus);
goto out;
}
}
......@@ -1886,9 +1879,6 @@ check_service_activated (BusContext *context,
{
_dbus_warn ("Expected to see service %s created, saw %s instead\n",
activated_name, service_name);
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (base_service_from_bus);
goto out;
}
......@@ -1896,23 +1886,16 @@ check_service_activated (BusContext *context,
{
_dbus_warn ("ServiceOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
base_service_from_bus, base_service_name);
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (base_service_from_bus);
goto out;
}
dbus_free (base_service_from_bus);
if (old_owner[0])
{
_dbus_warn ("expected a %s, got a %s\n",
"ServiceOwnerChanged (creation)",
"ServiceOwnerChanged (change)");
dbus_free (service_name);
dbus_free (old_owner);
goto out;
}
dbus_free (old_owner);
socd.expected_kind = SERVICE_CREATED;
socd.skip_connection = connection;
......@@ -1921,12 +1904,14 @@ check_service_activated (BusContext *context,
bus_test_clients_foreach (check_service_owner_changed_foreach,
&socd);
dbus_free (service_name);
if (socd.failed)
goto out;
dbus_message_unref (message);
service_name = NULL;
old_owner = NULL;
base_service_from_bus = NULL;
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
......@@ -2018,7 +2003,7 @@ check_service_auto_activated (BusContext *context,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceOwnerChanged"))
{
char *service_name;
const char *service_name;
CheckServiceOwnerChangedData socd;
reget_service_name_arg:
......@@ -2046,7 +2031,6 @@ check_service_auto_activated (BusContext *context,
{
_dbus_warn ("Expected to see service %s created, saw %s instead\n",
activated_name, service_name);
dbus_free (service_name);
goto out;
}
......@@ -2057,8 +2041,6 @@ check_service_auto_activated (BusContext *context,
bus_test_clients_foreach (check_service_owner_changed_foreach,
&socd);
dbus_free (service_name);
if (socd.failed)
goto out;
......@@ -2068,6 +2050,7 @@ check_service_auto_activated (BusContext *context,
dbus_message_unref (message);
message = NULL;
service_name = NULL;
}
else
{
......@@ -2245,7 +2228,7 @@ check_send_exit_to_service (BusContext *context,
if (!dbus_message_is_error (message,
DBUS_ERROR_NO_REPLY))
{
warn_unexpected (connection, NULL,
warn_unexpected (connection, message,
"NoReply error from Exit() method call");
goto out;
}
......@@ -2355,7 +2338,7 @@ check_got_service_info (DBusMessage *message)
"ServiceOwnerChanged"))
{
DBusError error;
char *service_name, *old_owner, *new_owner;
const char *service_name, *old_owner, *new_owner;
dbus_error_init (&error);
reget_service_info_data:
......@@ -2373,9 +2356,6 @@ check_got_service_info (DBusMessage *message)
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
dbus_error_free (&error);
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (new_owner);
goto reget_service_info_data;
}
else
......@@ -2391,9 +2371,6 @@ check_got_service_info (DBusMessage *message)
else
message_kind = GOT_SOMETHING_ELSE;
dbus_free (service_name);
dbus_free (old_owner);
dbus_free (new_owner);
dbus_error_free (&error);
}
else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
......@@ -2414,11 +2391,14 @@ check_existent_service_activation (BusContext *context,
DBusConnection *connection)
{
DBusMessage *message;
DBusMessage *base_service_message;
const char *base_service;
dbus_uint32_t serial;
dbus_bool_t retval;
char *base_service;
const char *existent = EXISTENT_SERVICE_NAME;
dbus_uint32_t flags;
base_service = NULL;
base_service_message = NULL;
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
......@@ -2428,9 +2408,10 @@ check_existent_service_activation (BusContext *context,
if (message == NULL)
return TRUE;
flags = 0;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
DBUS_TYPE_UINT32, 0,
DBUS_TYPE_STRING, &existent,
DBUS_TYPE_UINT32, &flags,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -2511,7 +2492,7 @@ check_existent_service_activation (BusContext *context,
message, &base_service))
goto out;
dbus_message_unref (message);
base_service_message = message;
message = NULL;
/* We may need to block here for the test service to exit or finish up */
......@@ -2620,8 +2601,8 @@ check_existent_service_activation (BusContext *context,
if (message)
dbus_message_unref (message);
if (base_service)
dbus_free (base_service);
if (base_service_message)
dbus_message_unref (base_service_message);
return retval;
}
......@@ -2636,6 +2617,8 @@ check_segfault_service_activation (BusContext *context,
DBusMessage *message;
dbus_uint32_t serial;
dbus_bool_t retval;
const char *segv_service;
dbus_uint32_t flags;
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
......@@ -2645,10 +2628,11 @@ check_segfault_service_activation (BusContext *context,
if (message == NULL)
return TRUE;
segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService";
flags = 0;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING,
"org.freedesktop.DBus.TestSuiteSegfaultService",
DBUS_TYPE_UINT32, 0,
DBUS_TYPE_STRING, &segv_service,
DBUS_TYPE_UINT32, &flags,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -2833,11 +2817,13 @@ check_existent_service_auto_activation (BusContext *context,
DBusConnection *connection)
{
DBusMessage *message;
DBusMessage *base_service_message;
dbus_uint32_t serial;
dbus_bool_t retval;
char *base_service;
const char *base_service;
const char *text;
base_service = NULL;
base_service_message = NULL;
message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
"/org/freedesktop/TestSuite",
......@@ -2849,8 +2835,9 @@ check_existent_service_auto_activation (BusContext *context,
dbus_message_set_auto_activation (message, TRUE);
text = TEST_ECHO_MESSAGE;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, TEST_ECHO_MESSAGE,
DBUS_TYPE_STRING, &text,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -2902,7 +2889,7 @@ check_existent_service_auto_activation (BusContext *context,
message, &base_service))
goto out;
dbus_message_unref (message);
base_service_message = message;
message = NULL;
/* We may need to block here for the test service to exit or finish up */
......@@ -3010,8 +2997,8 @@ check_existent_service_auto_activation (BusContext *context,
if (message)
dbus_message_unref (message);
if (base_service)
dbus_free (base_service);
if (base_service_message)
dbus_message_unref (base_service_message);
return retval;
}
......
......@@ -47,10 +47,11 @@ bus_driver_send_service_owner_changed (const char *service_name,
{
DBusMessage *message;
dbus_bool_t retval;
const char null_service[] = { '\000' };
const char *null_service;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
null_service = "";
_dbus_verbose ("sending service owner changed: %s [%s -> %s]\n",
service_name,
old_owner ? old_owner : null_service,
......@@ -70,9 +71,9 @@ bus_driver_send_service_owner_changed (const char *service_name,
goto oom;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, service_name,
DBUS_TYPE_STRING, old_owner ? old_owner : null_service,
DBUS_TYPE_STRING, new_owner ? new_owner : null_service,
DBUS_TYPE_STRING, &service_name,
DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
DBUS_TYPE_INVALID))
goto oom;
......@@ -111,7 +112,7 @@ bus_driver_send_service_lost (DBusConnection *connection,
if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
!dbus_message_append_args (message,
DBUS_TYPE_STRING, service_name,
DBUS_TYPE_STRING, &service_name,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -154,7 +155,7 @@ bus_driver_send_service_acquired (DBusConnection *connection,
if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
!dbus_message_append_args (message,
DBUS_TYPE_STRING, service_name,
DBUS_TYPE_STRING, &service_name,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
......@@ -341,7 +342,7 @@ bus_driver_send_welcome_message (DBusConnection *connection,
}
if (!dbus_message_append_args (welcome,
DBUS_TYPE_STRING, name,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
{
dbus_message_unref (welcome);
......@@ -374,6 +375,9 @@ bus_driver_handle_list_services (DBusConnection *connection,
int len;
char **services;
BusRegistry *registry;
int i;
DBusMessageIter iter;
DBusMessageIter sub;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
......@@ -393,9 +397,33 @@ bus_driver_handle_list_services (DBusConnection *connection,
return FALSE;
}
if (!dbus_message_append_args (reply,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, services, len,
DBUS_TYPE_INVALID))
dbus_message_append_iter_init (reply, &iter);
if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
&sub))
{
dbus_free_string_array (services);