summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2005-11-22 20:37:00 +0000
committerJohn (J5) Palmieri <johnp@redhat.com>2005-11-22 20:37:00 +0000
commit1a163e765c0d6a86d2aa2ffb18a1d7e29a052e7a (patch)
treef03b91de2eea70ffcb02aebcb265e3552dd9e48d /dbus
parentc33af17b934fcc8528b393ed2dca603e4940e6b3 (diff)
* 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
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-bus.c47
-rw-r--r--dbus/dbus-glib-lowlevel.h7
-rw-r--r--dbus/dbus-shared.h5
-rw-r--r--dbus/dbus-sysdeps.c55
4 files changed, 84 insertions, 30 deletions
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index 9016f1b1..7578efb2 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -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 */
+
+
/** @} */
diff --git a/dbus/dbus-glib-lowlevel.h b/dbus/dbus-glib-lowlevel.h
index 9f6fc84e..cb015ccb 100644
--- a/dbus/dbus-glib-lowlevel.h
+++ b/dbus/dbus-glib-lowlevel.h
@@ -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
diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h
index a8519c13..2ef1dc9c 100644
--- a/dbus/dbus-shared.h
+++ b/dbus/dbus-shared.h
@@ -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
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 1b7cd906..030d0801 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -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",