Commit 1a163e76 authored by John Palmieri's avatar John Palmieri

* configure.in: Add test/name-test/Makefile to the generated

	Makefile list

	* dbus/dbus-shared.h (#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT):
	New flag which replaces DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
	(#define DBUS_NAME_FLAG_DO_NOT_QUEUE): New flag for specifying
	not to queue an ower if it can't be the primary owner

	* bus/bus.h: Add new internal BusOwner struct

	* bus/driver.c (bus_driver_handle_hello): Send flags (0 for default)
	to bus_registry_ensure and don't set the prohibit_replacement flag
	since they are now set per BusOwner and not per name.
	(bus_driver_handle_list_queued_owners): bus method (ListQueuedOwners)
	that returns the list of connections in a name's connection queue

	* bus/services.c (struct BusService): remove prohibit_replacement field
	(struct BusOwner): new struct for keeping track of queued connections
	and their associated flags for the queue
	(struct BusRegistry): add a BusOwner memory pool
	(bus_registry_new): initialize the BusOwner memory pool
	(bus_registry_unref): free the BusOwner memory pool
	(_bus_service_find_owner_link): new internal method for
	searching the queue for a specific connection
	(bus_owner_set_flags): new method for adding setting the flags on a
	bus owner
	(bus_owner_new): new method that creates a BusOwner object from the
	pool and sets its flags
	(bus_owner_ref, bus_owner_unref): ref counting for BusOwner objects
	(bus_registry_ensure): Add the flags parameter
	(bus_registry_acquire_service): Switch from using raw connections to
	using the BusOwner struct
	Add new state machine for dealing with the new set of flags
	(bus_registry_set_service_context_table, struct OwnershipCancelData,
	cancel_ownership, free_ownership_cancel_data,
	add_cancel_ownership_to_transaction, struct OwnershipRestoreData,
	restore_ownership, free_ownership_restore_data,
	add_restore_ownership_to_transaction): Switch to using BusOwner
	instead of raw connections
	(bus_service_add_owner): Add flags parameter
	Switch to using BusOwner instead of raw connections
	Add state machine for dealing with the new set of flags
	(bus_service_swap_owner): Swaps the first and second owners in the
	queue.  Used to make sure proper signals are sent when a service looses
	or gains primary ownership.  We never insert an owner at the top of the
	queue.  Instead we insert it in the second position and then swap.
	(bus_service_remove_owner): Remove the owner from the queue sending
	out the NameLost and NameOwnerChanged signals if the we were the
	primary owner
	(bus_service_get_primary_owners_connection): New method that extracts
	the connection from the primary owner
	(bus_service_get_primary_owner): Returns the BusOwner instead of the
	connection
	(bus_service_get_allow_replacement): Changed from the old
	bus_service_get_prohibit_replacement method.  Checks the flags of the
	primary owner and returns if it can be replaced or not
	(bus_service_set_prohibit_replacement): removed
	(bus_service_has_owner): returns TRUE if and owner with
	the specified connection exists in the queue

	* dbus/dbus-bus.c (dbus_bus_connection_get_unique_name): New helper
	method that only compiles if tests are enabled.  Allows us to get the
	unique name of a connection so we can check it against the queue when
	doing regression tests

	* bus/activation.c (bus_activation_send_pending_auto_activate),
	bus/dispatch.c (bus_dispatch),
	bus/driver.c (bus_driver_handle_get_service_owner,
	bus_driver_handle_get_connection_unix_user,
	bus_driver_handle_get_connection_unix_process_id,
	bus_driver_handle_get_connection_selinux_security_context),
	bus/signals.c (connection_is_primary_owner):
	use bus_service_get_primary_owners_connection instead of
	bus_service_get_primary_owner

	* dbus/dbus-sysdeps.c (_dbus_connect_unix_socket,
	_dbus_listen_unix_socket): Calculate the length of the socket
	path and use that instead of using a fixed length which was
	causing socket names to contain many trailing Nul bytes.

	* dbus/dbus-glib-lowlevel.h, glib/dbus-gobject.c
	(dbus_g_method_get_sender): New method for extracting the sender
	from a DBusGMethodInvocation
	(dbus_g_method_return_get_reply): changed name to
	dbus_g_method_get_reply
	(dbus_g_method_return_send_reply): changed name to
	dbus_g_method_send reply

	* doc/dbus-specification.xml: New docs that describe how the new
	queueing system works and talks about the changes to the how
	we specify socket names

	* glib/examples/example-service.c,
	glib/examples/example-signal-emitter.c,
	glib/examples/statemachine/statemachine-server.c:
	Changed the RequestName flags to the new system

	* test/name-test/ (test-names.c, run-test.sh, Makefile.am): New
	regression test suite for testing various states of the new
	queueing system
parent c33af17b
2005-11-22 John (J5) Palmieri <johnp@redhat.com>
* configure.in: Add test/name-test/Makefile to the generated
Makefile list
* dbus/dbus-shared.h (#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT):
New flag which replaces DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
(#define DBUS_NAME_FLAG_DO_NOT_QUEUE): New flag for specifying
not to queue an ower if it can't be the primary owner
* bus/bus.h: Add new internal BusOwner struct
* bus/driver.c (bus_driver_handle_hello): Send flags (0 for default)
to bus_registry_ensure and don't set the prohibit_replacement flag
since they are now set per BusOwner and not per name.
(bus_driver_handle_list_queued_owners): bus method (ListQueuedOwners)
that returns the list of connections in a name's connection queue
* bus/services.c (struct BusService): remove prohibit_replacement field
(struct BusOwner): new struct for keeping track of queued connections
and their associated flags for the queue
(struct BusRegistry): add a BusOwner memory pool
(bus_registry_new): initialize the BusOwner memory pool
(bus_registry_unref): free the BusOwner memory pool
(_bus_service_find_owner_link): new internal method for
searching the queue for a specific connection
(bus_owner_set_flags): new method for adding setting the flags on a
bus owner
(bus_owner_new): new method that creates a BusOwner object from the
pool and sets its flags
(bus_owner_ref, bus_owner_unref): ref counting for BusOwner objects
(bus_registry_ensure): Add the flags parameter
(bus_registry_acquire_service): Switch from using raw connections to
using the BusOwner struct
Add new state machine for dealing with the new set of flags
(bus_registry_set_service_context_table, struct OwnershipCancelData,
cancel_ownership, free_ownership_cancel_data,
add_cancel_ownership_to_transaction, struct OwnershipRestoreData,
restore_ownership, free_ownership_restore_data,
add_restore_ownership_to_transaction): Switch to using BusOwner
instead of raw connections
(bus_service_add_owner): Add flags parameter
Switch to using BusOwner instead of raw connections
Add state machine for dealing with the new set of flags
(bus_service_swap_owner): Swaps the first and second owners in the
queue. Used to make sure proper signals are sent when a service looses
or gains primary ownership. We never insert an owner at the top of the
queue. Instead we insert it in the second position and then swap.
(bus_service_remove_owner): Remove the owner from the queue sending
out the NameLost and NameOwnerChanged signals if the we were the
primary owner
(bus_service_get_primary_owners_connection): New method that extracts
the connection from the primary owner
(bus_service_get_primary_owner): Returns the BusOwner instead of the
connection
(bus_service_get_allow_replacement): Changed from the old
bus_service_get_prohibit_replacement method. Checks the flags of the
primary owner and returns if it can be replaced or not
(bus_service_set_prohibit_replacement): removed
(bus_service_has_owner): returns TRUE if and owner with
the specified connection exists in the queue
* dbus/dbus-bus.c (dbus_bus_connection_get_unique_name): New helper
method that only compiles if tests are enabled. Allows us to get the
unique name of a connection so we can check it against the queue when
doing regression tests
* bus/activation.c (bus_activation_send_pending_auto_activate),
bus/dispatch.c (bus_dispatch),
bus/driver.c (bus_driver_handle_get_service_owner,
bus_driver_handle_get_connection_unix_user,
bus_driver_handle_get_connection_unix_process_id,
bus_driver_handle_get_connection_selinux_security_context),
bus/signals.c (connection_is_primary_owner):
use bus_service_get_primary_owners_connection instead of
bus_service_get_primary_owner
* dbus/dbus-sysdeps.c (_dbus_connect_unix_socket,
_dbus_listen_unix_socket): Calculate the length of the socket
path and use that instead of using a fixed length which was
causing socket names to contain many trailing Nul bytes.
* dbus/dbus-glib-lowlevel.h, glib/dbus-gobject.c
(dbus_g_method_get_sender): New method for extracting the sender
from a DBusGMethodInvocation
(dbus_g_method_return_get_reply): changed name to
dbus_g_method_get_reply
(dbus_g_method_return_send_reply): changed name to
dbus_g_method_send reply
* doc/dbus-specification.xml: New docs that describe how the new
queueing system works and talks about the changes to the how
we specify socket names
* glib/examples/example-service.c,
glib/examples/example-signal-emitter.c,
glib/examples/statemachine/statemachine-server.c:
Changed the RequestName flags to the new system
* test/name-test/ (test-names.c, run-test.sh, Makefile.am): New
regression test suite for testing various states of the new
queueing system
2005-11-15 Robert McQueen <robot101@debian.org>
* dbus/dbus-glib-lowlevel.h, glib/dbus-gobject.c: Patch from Rob
......
......@@ -980,7 +980,7 @@ bus_activation_send_pending_auto_activation_messages (BusActivation *activation
{
DBusConnection *addressed_recipient;
addressed_recipient = bus_service_get_primary_owner (service);
addressed_recipient = bus_service_get_primary_owners_connection (service);
/* Check the security policy, which has the side-effect of adding an
* expected pending reply.
......
......@@ -40,6 +40,7 @@ typedef struct BusPolicyRule BusPolicyRule;
typedef struct BusRegistry BusRegistry;
typedef struct BusSELinuxID BusSELinuxID;
typedef struct BusService BusService;
typedef struct BusOwner BusOwner;
typedef struct BusTransaction BusTransaction;
typedef struct BusMatchmaker BusMatchmaker;
typedef struct BusMatchRule BusMatchRule;
......
......@@ -287,7 +287,7 @@ bus_dispatch (DBusConnection *connection,
}
else
{
addressed_recipient = bus_service_get_primary_owner (service);
addressed_recipient = bus_service_get_primary_owners_connection (service);
_dbus_assert (addressed_recipient != NULL);
if (!bus_context_check_security_policy (context, transaction,
......
......@@ -308,12 +308,10 @@ bus_driver_handle_hello (DBusConnection *connection,
/* Create the service */
service = bus_registry_ensure (registry,
&unique_name, connection, transaction, error);
&unique_name, connection, 0, transaction, error);
if (service == NULL)
goto out_0;
bus_service_set_prohibit_replacement (service, TRUE);
_dbus_assert (bus_connection_is_active (connection));
retval = TRUE;
......@@ -883,7 +881,7 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
}
else
{
base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
if (base_name == NULL)
{
/* FIXME - how is this error possible? */
......@@ -923,6 +921,113 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
return FALSE;
}
static dbus_bool_t
bus_driver_handle_list_queued_owners (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error)
{
const char *text;
DBusList *base_names;
DBusList *link;
DBusString str;
BusRegistry *registry;
BusService *service;
DBusMessage *reply;
DBusMessageIter iter, array_iter;
char *dbus_service_name = DBUS_SERVICE_DBUS;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
registry = bus_connection_get_registry (connection);
base_names = NULL;
text = NULL;
reply = NULL;
if (! dbus_message_get_args (message, error,
DBUS_TYPE_STRING, &text,
DBUS_TYPE_INVALID))
goto failed;
_dbus_string_init_const (&str, text);
service = bus_registry_lookup (registry, &str);
if (service == NULL &&
_dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
{
/* ORG_FREEDESKTOP_DBUS owns itself */
if (! _dbus_list_append (&base_names, dbus_service_name))
goto oom;
}
else if (service == NULL)
{
dbus_set_error (error,
DBUS_ERROR_NAME_HAS_NO_OWNER,
"Could not get owners of name '%s': no such name", text);
goto failed;
}
else
{
if (!bus_service_list_queued_owners (service,
&base_names,
error))
goto failed;
}
_dbus_assert (base_names != NULL);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
goto oom;
dbus_message_iter_init_append (reply, &iter);
if (!dbus_message_iter_open_container (&iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
&array_iter))
goto oom;
link = _dbus_list_get_first_link (&base_names);
while (link != NULL)
{
char *uname;
_dbus_assert (link->data != NULL);
uname = (char *)link->data;
if (!dbus_message_iter_append_basic (&array_iter,
DBUS_TYPE_STRING,
&uname))
goto oom;
link = _dbus_list_get_next_link (&base_names, link);
}
if (! dbus_message_iter_close_container (&iter, &array_iter))
goto oom;
if (! bus_transaction_send_from_driver (transaction, connection, reply))
goto oom;
dbus_message_unref (reply);
return TRUE;
oom:
BUS_SET_OOM (error);
failed:
_DBUS_ASSERT_ERROR_IS_SET (error);
if (reply)
dbus_message_unref (reply);
if (base_names)
_dbus_list_clear (&base_names);
return FALSE;
}
static dbus_bool_t
bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
BusTransaction *transaction,
......@@ -962,7 +1067,7 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
goto failed;
}
conn = bus_service_get_primary_owner (serv);
conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
......@@ -1038,7 +1143,7 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
goto failed;
}
conn = bus_service_get_primary_owner (serv);
conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
......@@ -1113,7 +1218,7 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
goto failed;
}
conn = bus_service_get_primary_owner (serv);
conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
......@@ -1235,6 +1340,10 @@ struct
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_STRING_AS_STRING,
bus_driver_handle_get_service_owner },
{ "ListQueuedOwners",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
bus_driver_handle_list_queued_owners },
{ "GetConnectionUnixUser",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
......
This diff is collapsed.
......@@ -40,7 +40,8 @@ BusService* bus_registry_lookup (BusRegistry *registry
const DBusString *service_name);
BusService* bus_registry_ensure (BusRegistry *registry,
const DBusString *service_name,
DBusConnection *owner_if_created,
DBusConnection *owner_connection_if_created,
dbus_uint32_t flags,
BusTransaction *transaction,
DBusError *error);
void bus_registry_foreach (BusRegistry *registry,
......@@ -65,23 +66,29 @@ dbus_bool_t bus_registry_release_service (BusRegistry *registry
dbus_bool_t bus_registry_set_service_context_table (BusRegistry *registry,
DBusHashTable *table);
BusService* bus_service_ref (BusService *service);
void bus_service_unref (BusService *service);
dbus_bool_t bus_service_add_owner (BusService *service,
DBusConnection *owner,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_service_remove_owner (BusService *service,
DBusConnection *owner,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_service_has_owner (BusService *service,
DBusConnection *owner);
DBusConnection* bus_service_get_primary_owner (BusService *service);
void bus_service_set_prohibit_replacement (BusService *service,
dbus_bool_t prohibit_replacement);
dbus_bool_t bus_service_get_prohibit_replacement (BusService *service);
const char* bus_service_get_name (BusService *service);
BusService* bus_service_ref (BusService *service);
void bus_service_unref (BusService *service);
dbus_bool_t bus_service_add_owner (BusService *service,
DBusConnection *connection,
dbus_uint32_t flags,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_service_swap_owner (BusService *service,
DBusConnection *connection,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_service_remove_owner (BusService *service,
DBusConnection *connection,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_service_has_owner (BusService *service,
DBusConnection *connection);
BusOwner* bus_service_get_primary_owner (BusService *service);
dbus_bool_t bus_service_get_allow_replacement (BusService *service);
const char* bus_service_get_name (BusService *service);
dbus_bool_t bus_service_list_queued_owners (BusService *service,
DBusList **return_list,
DBusError *error);
DBusConnection* bus_service_get_primary_owners_connection (BusService *service);
#endif /* BUS_SERVICES_H */
......@@ -1274,7 +1274,7 @@ connection_is_primary_owner (DBusConnection *connection,
if (service == NULL)
return FALSE; /* Service doesn't exist so connection can't own it. */
return bus_service_get_primary_owner (service) == connection;
return bus_service_get_primary_owners_connection (service) == connection;
}
static dbus_bool_t
......
......@@ -1349,6 +1349,7 @@ test/Makefile
test/glib/Makefile
test/python/Makefile
test/qt/Makefile
test/name-test/Makefile
doc/Makefile
dbus-1.pc
dbus-glib-1.pc
......
......@@ -655,20 +655,17 @@ dbus_bus_get_unix_user (DBusConnection *connection,
* result codes are discussed here, but the specification is the
* canonical version of this information.
*
* The #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT flag indicates that
* if the name is successfully requested, other applications
* will not be able to take over the name. i.e. the name's
* owner (the application calling this function) must let go of
* the name, it will not lose it involuntarily.
* The #DBUS_NAME_FLAG_ALLOW_REPLACEMENT flag indicates that the caller
* will allow other services to take over the name from the current owner.
*
* The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller
* would like to take over the name from the current owner.
* If the current name owner used #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
* If the current name owner did not use #DBUS_NAME_FLAG_ALLOW_REPLACEMENT
* then this flag indicates that the caller would like to be placed
* in the queue to own the name when the current owner lets go.
*
* If no flags are given, an application will receive the requested
* name only if the name is currently unowned; and it will give
* name only if the name is currently unowned; it will NOT give
* up the name if another application asks to take it over using
* #DBUS_NAME_FLAG_REPLACE_EXISTING.
*
......@@ -678,27 +675,31 @@ dbus_bus_get_unix_user (DBusConnection *connection,
* #DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER means that the name had no
* existing owner, and the caller is now the primary owner; or that
* the name had an owner, and the caller specified
* #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner did not
* specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT.
* #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner
* specified #DBUS_NAME_FLAG_ALLOW_REPLACEMENT.
*
* #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the current owner
* specified #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT and the caller specified
* #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up in
* a queue to own the name after the current owner gives it up.
* #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the caller does NOT
* specify #DBUS_NAME_FLAG_DO_NOT_QUEUE and either the current owner
* did NOT specify #DBUS_NAME_FLAG_ALLOW_REPLACEMENT or the caller did NOT
* specify #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up
* in a queue to own the name after the current owner gives it up.
*
* #DBUS_REQUEST_NAME_REPLY_EXISTS happens if the name has an owner
* #already and DBUS_NAME_FLAG_REPLACE_EXISTING was not specified.
* already and the caller specifies #DBUS_NAME_FLAG_DO_NOT_QUEUE
* and either the current owner has NOT specified
* #DBUS_NAME_FLAG_ALLOW_REPLACEMENT or the caller did NOT specify
* #DBUS_NAME_FLAG_REPLACE_EXISTING.
*
* #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application
* requests a name it already owns.
*
* When a service represents an application, say "text editor," then
* it should specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT if it wants
* the first editor started to be the user's editor vs. the last one
* it should specify #DBUS_NAME_FLAG_ALLOW_REPLACEMENT if it wants
* the last editor started to be the user's editor vs. the first one
* started. Then any editor that can be the user's editor should
* specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over
* (last-started-wins) or be queued up (first-started-wins) according
* to whether #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT was given.
* to whether #DBUS_NAME_FLAG_ALLOW_REPLACEMENT was given.
*
* @todo this all seems sort of broken. Shouldn't the flags be a property
* of the name, not the app requesting the name? What are the use-cases
......@@ -1097,4 +1098,16 @@ dbus_bus_remove_match (DBusConnection *connection,
dbus_message_unref (msg);
}
#ifdef DBUS_BUILD_TESTS
const char *
dbus_bus_connection_get_unique_name (DBusConnection *connection)
{
BusData *bd;
bd = dbus_connection_get_data (connection, bus_data_slot);
return bd->unique_name;
}
#endif /* DBUS_BUILD_TESTS */
/** @} */
......@@ -57,9 +57,12 @@ DBusMessage* dbus_g_message_get_message (DBusGMessage *gmessage);
* g-functions anyhow)
*/
DBusMessage * dbus_g_method_return_get_reply (DBusGMethodInvocation *context);
gchar* dbus_g_method_get_sender (DBusGMethodInvocation *context);
void dbus_g_method_return_send_reply (DBusGMethodInvocation *context, DBusMessage *reply);
DBusMessage* dbus_g_method_get_reply (DBusGMethodInvocation *context);
void dbus_g_method_send_reply (DBusGMethodInvocation *context,
DBusMessage *reply);
G_END_DECLS
......
......@@ -68,8 +68,9 @@ typedef enum
#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
/* Owner flags */
#define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT 0x1
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2
#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2
#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4
/* Replies to request for a name */
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
......
......@@ -398,6 +398,7 @@ _dbus_connect_unix_socket (const char *path,
DBusError *error)
{
int fd;
size_t path_len;
struct sockaddr_un addr;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
......@@ -419,15 +420,23 @@ _dbus_connect_unix_socket (const char *path,
_DBUS_ZERO (addr);
addr.sun_family = AF_UNIX;
path_len = strlen (path);
if (abstract)
{
#ifdef HAVE_ABSTRACT_SOCKETS
/* remember that abstract names aren't nul-terminated so we rely
* on sun_path being filled in with zeroes above.
*/
addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
strncpy (&addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2);
path_len++; /* Account for the extra nul byte added to the start of sun_path */
if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
{
dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
"Abstract socket name too long\n");
close (fd);
return -1;
}
strncpy (&addr.sun_path[1], path, path_len);
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
#else /* HAVE_ABSTRACT_SOCKETS */
dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
......@@ -438,10 +447,18 @@ _dbus_connect_unix_socket (const char *path,
}
else
{
strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
{
dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
"Socket name too long\n");
close (fd);
return -1;
}
strncpy (addr.sun_path, path, path_len);
}
if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
{
dbus_set_error (error,
_dbus_error_from_errno (errno),
......@@ -489,6 +506,7 @@ _dbus_listen_unix_socket (const char *path,
{
int listen_fd;
struct sockaddr_un addr;
size_t path_len;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
......@@ -507,6 +525,7 @@ _dbus_listen_unix_socket (const char *path,
_DBUS_ZERO (addr);
addr.sun_family = AF_UNIX;
path_len = strlen (path);
if (abstract)
{
......@@ -515,7 +534,17 @@ _dbus_listen_unix_socket (const char *path,
* on sun_path being filled in with zeroes above.
*/
addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
strncpy (&addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2);
path_len++; /* Account for the extra nul byte added to the start of sun_path */
if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
{
dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
"Abstract socket name too long\n");
close (listen_fd);
return -1;
}
strncpy (&addr.sun_path[1], path, path_len);
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
#else /* HAVE_ABSTRACT_SOCKETS */
dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
......@@ -544,10 +573,18 @@ _dbus_listen_unix_socket (const char *path,
unlink (path);
}
strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
{
dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
"Abstract socket name too long\n");
close (listen_fd);
return -1;
}
strncpy (addr.sun_path, path, path_len);
}
if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to bind socket \"%s\": %s",
......
......@@ -28,11 +28,6 @@ Important for 1.0
Kind of a major API change, but seems high-value.
- figure out what the deal is with trailing nul bytes in
abstract socket names
http://lists.freedesktop.org/archives/dbus/2005-August/003179.html
Important for 1.0 GLib Bindings
===
......
This diff is collapsed.
......@@ -1858,6 +1858,28 @@ dbus_g_object_register_marshaller_array (GClosureMarshal marshaller,
g_static_rw_lock_writer_unlock (&globals_lock);
}
/**
* Get the sender of a message so we can send a
* "reply" later (i.e. send a message directly
* to a service which invoked the method at a
* later time).
*
* @param context the method context
*
* @return the unique name of teh sender
*/
gchar *
dbus_g_method_get_sender (DBusGMethodInvocation *context)
{
const gchar *sender;
sender = dbus_message_get_sender (dbus_g_message_get_message (context->message));
if (sender == NULL)
return NULL;
return strdup (sender);
}
/**
* Get the reply message to append reply values
......@@ -1867,9 +1889,9 @@ dbus_g_object_register_marshaller_array (GClosureMarshal marshaller,
* @param context the method context
*/
DBusMessage *
dbus_g_method_return_get_reply (DBusGMethodInvocation *context)
dbus_g_method_get_reply (DBusGMethodInvocation *context)
{
return dbus_message_new_method_return (dbus_g_message_get_message (context->message));
return dbus_message_new_method_return (dbus_g_message_get_message (context->message));
}
/**
......@@ -1881,7 +1903,7 @@ dbus_g_method_return_get_reply (DBusGMethodInvocation *context)
* @param reply the reply message, will be unreffed
*/
void
dbus_g_method_return_send_reply (DBusGMethodInvocation *context, DBusMessage *reply)
dbus_g_method_send_reply (DBusGMethodInvocation *context, DBusMessage *reply)
{
dbus_connection_send (dbus_g_connection_get_connection (context->connection), reply, NULL);
dbus_message_unref (reply);
......
......@@ -135,7 +135,7 @@ main (int argc, char **argv)
if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
G_TYPE_STRING, "org.designfu.SampleService",
G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT,
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID))
......
......@@ -114,7 +114,7 @@ main (int argc, char **argv)
if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
G_TYPE_STRING, "org.designfu.TestService",
G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT,
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID))
......
......@@ -211,7 +211,7 @@ main (int argc, char **argv)
if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
G_TYPE_STRING, "com.example.StateServer",
G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT,
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID))
......
......@@ -9,8 +9,8 @@ if HAVE_QTESTLIB
QT_SUBDIR=qt
endif
SUBDIRS=$(GLIB_SUBDIR) $(PYTHON_SUBDIR) $(QT_SUBDIR)
DIST_SUBDIRS=glib python qt
SUBDIRS=name-test $(GLIB_SUBDIR) $(PYTHON_SUBDIR) $(QT_SUBDIR)
DIST_SUBDIRS=glib python qt name-test
INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS)
......
INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_COMPILATION
## note that TESTS has special meaning (stuff to use in make check)
## so if adding tests not to be run in make check, don't add them to
## TESTS
if DBUS_BUILD_TESTS
TESTS_ENVIRONMENT=DBUS_TOP_BUILDDIR=$(ABSOLUTE_TOP_BUILDDIR)
TESTS=run-test.sh
else
TESTS=
endif
EXTRA_DIST=run-test.sh
if DBUS_BUILD_TESTS
## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we
## build even when not doing "make check"
noinst_PROGRAMS=test-names
test_names_SOURCES= \
test-names.c
test_names_LDADD=$(top_builddir)/dbus/libdbus-1.la $(top_builddir)/dbus/libdbus-convenience.la
endif
#! /bin/bash
function die()
{
if ! test -z "$DBUS_SESSION_BUS_PID" ; then
echo "killing message bus "$DBUS_SESSION_BUS_PID >&2
kill -9 $DBUS_SESSION_BUS_PID