diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | bus/driver.c | 76 | ||||
-rw-r--r-- | dbus/dbus-errors.h | 1 | ||||
-rw-r--r-- | doc/.cvsignore | 1 | ||||
-rw-r--r-- | doc/dbus-specification.xml | 52 | ||||
-rw-r--r-- | glib/dbus-gproxy.c | 55 | ||||
-rw-r--r-- | test/glib/test-dbus-glib.c | 17 |
7 files changed, 211 insertions, 5 deletions
@@ -1,3 +1,17 @@ +2004-04-15 Olivier Andrieu <oliv__a@users.sourceforge.net> + + * bus/driver.c (bus_driver_handle_get_service_owner): + implement a GetServiceOwner method. + * doc/dbus-specification.xml: document it. + * dbus/dbus-errors.h: add a 'ServiceHasNoOwner' error. + + * glib/dbus-gproxy.c (dbus_gproxy_new_for_service_owner): + implement, using the bus GetServiceOwner method. + + * test/glib/test-dbus-glib.c: + use dbus_gproxy_new_for_service_owner so that we can receive the + signal. + 2004-04-14 Olivier Andrieu <oliv__a@users.sourceforge.net> * test/glib/test-dbus-glib.c (timed_exit): fail the test after diff --git a/bus/driver.c b/bus/driver.c index 3ffae2e0..a9dddd19 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -756,6 +756,79 @@ bus_driver_handle_remove_match (DBusConnection *connection, return FALSE; } +static dbus_bool_t +bus_driver_handle_get_service_owner (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + char *text; + const char *base_name; + DBusString str; + BusRegistry *registry; + BusService *service; + DBusMessage *reply; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + registry = bus_connection_get_registry (connection); + + 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_set_error (error, + DBUS_ERROR_SERVICE_HAS_NO_OWNER, + "Could not get owner of service '%s': no such service", text); + goto failed; + } + + base_name = bus_connection_get_name (bus_service_get_primary_owner (service)); + if (base_name == NULL) + { + dbus_set_error (error, + DBUS_ERROR_FAILED, + "Could not determine base service for '%s'", text); + goto failed; + } + _dbus_assert (*base_name == ':'); + + reply = dbus_message_new_method_return (message); + if (reply == NULL) + goto oom; + + if (! dbus_message_append_args (reply, + DBUS_TYPE_STRING, base_name, + DBUS_TYPE_INVALID)) + goto oom; + + if (! bus_transaction_send_from_driver (transaction, connection, reply)) + goto oom; + + dbus_message_unref (reply); + dbus_free (text); + + return TRUE; + + oom: + BUS_SET_OOM (error); + + failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + if (reply) + dbus_message_unref (reply); + dbus_free (text); + return FALSE; +} + /* For speed it might be useful to sort this in order of * frequency of use (but doesn't matter with only a few items * anyhow) @@ -774,7 +847,8 @@ struct { "ServiceExists", bus_driver_handle_service_exists }, { "ListServices", bus_driver_handle_list_services }, { "AddMatch", bus_driver_handle_add_match }, - { "RemoveMatch", bus_driver_handle_remove_match } + { "RemoveMatch", bus_driver_handle_remove_match }, + { "GetServiceOwner", bus_driver_handle_get_service_owner } }; dbus_bool_t diff --git a/dbus/dbus-errors.h b/dbus/dbus-errors.h index 9d201230..ec8c5d96 100644 --- a/dbus/dbus-errors.h +++ b/dbus/dbus-errors.h @@ -56,6 +56,7 @@ struct DBusError #define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" #define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.ServiceNotFound" #define DBUS_ERROR_SERVICE_DOES_NOT_EXIST "org.freedesktop.DBus.Error.ServiceDoesNotExist" +#define DBUS_ERROR_SERVICE_HAS_NO_OWNER "org.freedesktop.DBus.Error.ServiceHasNoOwner" #define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply" #define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError" #define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress" diff --git a/doc/.cvsignore b/doc/.cvsignore index eded08f0..371668d9 100644 --- a/doc/.cvsignore +++ b/doc/.cvsignore @@ -8,3 +8,4 @@ Makefile.in api dbus-specification.html dbus-test-plan.html +dbus-tutorial.html diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 94dc740c..2f22b772 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -2206,6 +2206,58 @@ </sect3> + <sect3 id="bus-messages-get-service-owner"> + <title><literal>org.freedesktop.DBus.GetServiceOwner</literal></title> + <para> + As a method: + <programlisting> + STRING GetServiceOwner (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols="3"> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service to query</entry> + </row> + </tbody> + </tgroup> + </informaltable> + Reply arguments: + <informaltable> + <tgroup cols="3"> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Return value, a base service name</entry> + </row> + </tbody> + </tgroup> + </informaltable> + Returns the base service name of the primary owner of the + service in argument. If the requested service isn't active, + returns a + <literal>org.freedesktop.DBus.Error.ServiceHasNoOwner</literal> error. + </para> + </sect3> + <sect3 id="bus-messages-out-of-memory"> <title><literal>org.freedesktop.DBus.Error.NoMemory</literal></title> <para> diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 878c2a25..906fd2e0 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -932,12 +932,67 @@ dbus_gproxy_new_for_service_owner (DBusConnection *connection, const char *interface_name, GError **error) { + DBusGProxy *proxy; + + DBusMessage *request, *reply; + DBusError derror; + char *base_service_name; + g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (service_name != NULL, NULL); g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); + dbus_error_init (&derror); + + proxy = NULL; + base_service_name = NULL; + reply = NULL; + + request = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, + DBUS_PATH_ORG_FREEDESKTOP_DBUS, + DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, + "GetServiceOwner"); + if (request == NULL) + g_error ("Out of memory"); + + if (! dbus_message_append_args (request, + DBUS_TYPE_STRING, service_name, + DBUS_TYPE_INVALID)) + g_error ("Out of memory"); + + reply = dbus_connection_send_with_reply_and_block (connection, request, + 2000, &derror); + if (reply == NULL) + goto error; + + if (dbus_set_error_from_message (&derror, reply)) + goto error; + + if (! dbus_message_get_args (reply, &derror, + DBUS_TYPE_STRING, &base_service_name, + DBUS_TYPE_INVALID)) + goto error; + + + proxy = dbus_gproxy_new (connection, base_service_name, + path_name, interface_name); + + goto out; + error: + g_assert (dbus_error_is_set (&derror)); + dbus_set_g_error (error, &derror); + dbus_error_free (&derror); + + out: + if (request) + dbus_message_unref (request); + if (reply) + dbus_message_unref (reply); + dbus_free (base_service_name); + + return proxy; } /** diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index ed94afae..ad08164a 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -172,11 +172,20 @@ main (int argc, char **argv) /* Talk to the new service */ - proxy = dbus_gproxy_new_for_service (connection, - "org.freedesktop.DBus.TestSuiteEchoService", - "/org/freedesktop/TestSuite", - "org.freedesktop.TestSuite"); + proxy = dbus_gproxy_new_for_service_owner (connection, + "org.freedesktop.DBus.TestSuiteEchoService", + "/org/freedesktop/TestSuite", + "org.freedesktop.TestSuite", + &error); + if (proxy == NULL) + { + g_printerr ("Failed to create proxy for service owner: %s\n", + error->message); + g_error_free (error); + exit (1); + } + call = dbus_gproxy_begin_call (proxy, "Echo", DBUS_TYPE_STRING, "my string hello", |