o.fd.DBus.ReleaseName

Daniel Reed n at ml.org
Fri Mar 11 23:01:26 PST 2005


This patch introduces a ReleaseName method to complement RequestName.
ReleaseName can be used to give up a bus name without breaking the
connection to the bus.

-- 
Daniel Reed <n at ml.org>	http://naim-users.org/nmlorg/	http://naim.n.ml.org/
The pursuit of pretty formulas and neat theorems can no doubt quickly
degenerate into a silly vice, but so can the quest for austere
generalities which are so very general indeed that they are incapable
of application to any particular. -- Eric Temple Bell, Mathematician
-------------- next part --------------
Index: bus/driver.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/driver.c,v
retrieving revision 1.67
diff -u -r1.67 driver.c
--- bus/driver.c	17 Feb 2005 21:19:49 -0000	1.67
+++ bus/driver.c	12 Mar 2005 06:10:25 -0000
@@ -524,6 +524,61 @@
 } 
 
 static dbus_bool_t
+bus_driver_handle_release_service (DBusConnection *connection,
+                                   BusTransaction *transaction,
+                                   DBusMessage    *message,
+                                   DBusError      *error)
+{
+  DBusMessage *reply;
+  DBusString service_name;
+  const char *name;
+  dbus_bool_t retval;
+  BusRegistry *registry;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  
+  registry = bus_connection_get_registry (connection);
+  
+  if (!dbus_message_get_args (message, error,
+                              DBUS_TYPE_STRING, &name,
+                              DBUS_TYPE_INVALID))
+    return FALSE;
+  
+  _dbus_verbose ("Trying to release name %s\n", name);
+  
+  retval = FALSE;
+  reply = NULL;
+
+  _dbus_string_init_const (&service_name, name);
+
+  if (!bus_registry_release_service (registry, connection,
+                                     &service_name,
+                                     transaction,
+                                     error))
+    goto out;
+  
+  reply = dbus_message_new_method_return (message);
+  if (reply == NULL)
+    {
+      BUS_SET_OOM (error);
+      goto out;
+    }
+
+  if (!bus_transaction_send_from_driver (transaction, connection, reply))
+    {
+      BUS_SET_OOM (error);
+      goto out;
+    }
+
+  retval = TRUE;
+  
+ out:
+  if (reply)
+    dbus_message_unref (reply);
+  return retval;
+} 
+
+static dbus_bool_t
 bus_driver_handle_service_exists (DBusConnection *connection,
                                   BusTransaction *transaction,
                                   DBusMessage    *message,
@@ -1056,6 +1111,10 @@
     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
     DBUS_TYPE_UINT32_AS_STRING,
     bus_driver_handle_acquire_service },
+  { "ReleaseName",
+    DBUS_TYPE_STRING_AS_STRING,
+    DBUS_TYPE_INVALID_AS_STRING,
+    bus_driver_handle_release_service },
   { "StartServiceByName",
     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
     DBUS_TYPE_UINT32_AS_STRING,
Index: bus/services.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/services.c,v
retrieving revision 1.30
diff -u -r1.30 services.c
--- bus/services.c	21 Jan 2005 03:44:10 -0000	1.30
+++ bus/services.c	12 Mar 2005 06:10:26 -0000
@@ -427,6 +427,87 @@
 }
 
 dbus_bool_t
+bus_registry_release_service (BusRegistry      *registry,
+                              DBusConnection   *connection,
+                              const DBusString *service_name,
+                              BusTransaction   *transaction,
+                              DBusError        *error)
+{
+  dbus_bool_t retval;
+  DBusConnection *old_owner;
+  BusService *service;
+  BusActivation  *activation;
+  
+  retval = FALSE;
+
+  if (!_dbus_validate_bus_name (service_name, 0,
+                                _dbus_string_get_length (service_name)))
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                      "Bus name \"%s\" is not valid",
+                      _dbus_string_get_const_data (service_name));
+      
+      _dbus_verbose ("Attempt to acquire invalid service name\n");
+      
+      goto out;
+    }
+  
+  if (_dbus_string_get_byte (service_name, 0) == ':')
+    {
+      /* Not allowed; only base services can start with ':' */
+      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                      "Cannot release a service starting with ':' such as \"%s\"",
+                      _dbus_string_get_const_data (service_name));
+      
+      _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
+                     _dbus_string_get_const_data (service_name));
+      
+      goto out;
+    }
+
+  service = bus_registry_lookup (registry, service_name);
+
+  if (service == NULL)
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                      "Service \"%s\" does not exist",
+                      _dbus_string_get_const_data (service_name));
+      
+      _dbus_verbose ("Attempt to release non-existent service \"%s\"",
+                     _dbus_string_get_const_data (service_name));
+      
+      goto out;
+    }
+
+  old_owner = bus_service_get_primary_owner (service);
+
+  if (old_owner != connection)
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                      "Service \"%s\" is not currently owned by you",
+                      _dbus_string_get_const_data (service_name));
+      
+      _dbus_verbose ("Attempt to release unowned service \"%s\"",
+                     _dbus_string_get_const_data (service_name));
+      
+      goto out;
+    }
+
+  if (!bus_service_remove_owner (service, old_owner,
+                                 transaction, error))
+    goto out;
+      
+  activation = bus_context_get_activation (registry->context);
+  retval = bus_activation_send_pending_auto_activation_messages (activation,
+								 service,
+								 transaction,
+								 error);
+
+ out:
+  return retval;
+}
+
+dbus_bool_t
 bus_registry_set_service_context_table (BusRegistry   *registry,
 					DBusHashTable *table)
 {
Index: bus/services.h
===================================================================
RCS file: /cvs/dbus/dbus/bus/services.h,v
retrieving revision 1.13
diff -u -r1.13 services.h
--- bus/services.h	7 Nov 2004 17:05:19 -0000	1.13
+++ bus/services.h	12 Mar 2005 06:10:26 -0000
@@ -56,6 +56,12 @@
                                            dbus_uint32_t               *result,
                                            BusTransaction              *transaction,
                                            DBusError                   *error);
+dbus_bool_t  bus_registry_release_service (BusRegistry                 *registry,
+                                           DBusConnection              *connection,
+                                           const DBusString            *service_name,
+                                           BusTransaction              *transaction,
+                                           DBusError                   *error);
+
 dbus_bool_t  bus_registry_set_service_context_table (BusRegistry           *registry,
 						     DBusHashTable         *table);
 
Index: dbus/dbus-bus.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.c,v
retrieving revision 1.41
diff -u -r1.41 dbus-bus.c
--- dbus/dbus-bus.c	25 Feb 2005 22:03:30 -0000	1.41
+++ dbus/dbus-bus.c	12 Mar 2005 06:10:27 -0000
@@ -705,6 +705,69 @@
 }
 
 /**
+ * Asks the bus to release the given name from this connection.
+ *
+ * @param connection the connection
+ * @param name the name to request
+ * @param error location to store the error
+ * @returns #TRUE on success
+ */ 
+dbus_bool_t
+dbus_bus_release_name (DBusConnection *connection,
+                       const char     *name,
+                       DBusError      *error)
+{
+  DBusMessage *message, *reply;
+
+  _dbus_return_val_if_fail (connection != NULL, 0);
+  _dbus_return_val_if_fail (name != NULL, 0);
+  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
+  _dbus_return_val_if_error_is_set (error, 0);
+  
+  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+                                          DBUS_PATH_DBUS,
+                                          DBUS_INTERFACE_DBUS,
+                                          "ReleaseName");
+
+  if (message == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return FALSE;
+    }
+ 
+  if (!dbus_message_append_args (message,
+				 DBUS_TYPE_STRING, &name,
+				 DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      _DBUS_SET_OOM (error);
+      return FALSE;
+    }
+  
+  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
+                                                     error);
+  
+  dbus_message_unref (message);
+  
+  if (reply == NULL)
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      return FALSE;
+    }  
+
+  if (dbus_set_error_from_message (error, reply))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      dbus_message_unref (reply);
+      return FALSE;
+    }
+  
+  dbus_message_unref (reply);
+  
+  return TRUE;
+}
+
+/**
  * Checks whether a certain name has an owner.
  *
  * @param connection the connection
Index: dbus/dbus-bus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.h,v
retrieving revision 1.14
diff -u -r1.14 dbus-bus.h
--- dbus/dbus-bus.h	18 Jan 2005 20:42:15 -0000	1.14
+++ dbus/dbus-bus.h	12 Mar 2005 06:10:27 -0000
@@ -45,6 +45,9 @@
 					   const char     *name,
 					   unsigned int    flags,
 					   DBusError      *error);
+dbus_bool_t     dbus_bus_release_name     (DBusConnection *connection,
+					   const char     *name,
+					   DBusError      *error);
 dbus_bool_t     dbus_bus_name_has_owner   (DBusConnection *connection,
 					   const char     *name,
 					   DBusError      *error);


More information about the dbus mailing list