diff --git a/bus/containers.c b/bus/containers.c index a65f3daf..24fe3de9 100644 --- a/bus/containers.c +++ b/bus/containers.c @@ -35,6 +35,7 @@ #include +#include "dbus/dbus-asv-util.h" #include "dbus/dbus-hash.h" #include "dbus/dbus-message-internal.h" #include "dbus/dbus-sysdeps-unix.h" @@ -680,8 +681,8 @@ bus_containers_handle_add_server (DBusConnection *connection, BusContainerCreatorData *creator_data; DBusMessageIter iter; DBusMessageIter dict_iter; - DBusMessageIter writer; - DBusMessageIter array_writer; + DBusMessageIter writer = DBUS_MESSAGE_ITER_INIT_CLOSED; + DBusMessageIter asv_writer = DBUS_MESSAGE_ITER_INIT_CLOSED; const char *type; const char *app_id; const char *instance_id; @@ -952,27 +953,21 @@ bus_containers_handle_add_server (DBusConnection *connection, dbus_message_iter_init_append (reply, &writer); - if (!dbus_message_iter_open_container (&writer, DBUS_TYPE_ARRAY, - DBUS_TYPE_BYTE_AS_STRING, - &array_writer)) + if (!dbus_message_iter_open_container (&writer, DBUS_TYPE_ARRAY, "{sv}", + &asv_writer)) goto oom; - if (!dbus_message_iter_append_fixed_array (&array_writer, DBUS_TYPE_BYTE, - &path, strlen (path) + 1)) - { - dbus_message_iter_abandon_container (&writer, &array_writer); - goto oom; - } - - if (!dbus_message_iter_close_container (&writer, &array_writer)) + if (!_dbus_asv_add_string (&asv_writer, "Address", address)) goto oom; - if (!dbus_message_append_args (reply, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) + if (!_dbus_asv_add_byte_array (&asv_writer, "SocketPath", + path, strlen (path) + 1)) goto oom; - _dbus_assert (dbus_message_has_signature (reply, "oays")); + if (!dbus_message_iter_close_container (&writer, &asv_writer)) + goto oom; + + _dbus_assert (dbus_message_has_signature (reply, "oa{sv}")); if (! bus_transaction_send_from_driver (transaction, connection, reply)) goto oom; @@ -988,6 +983,8 @@ oom: BUS_SET_OOM (error); /* fall through */ fail: + dbus_message_iter_abandon_container_if_open (&writer, &asv_writer); + if (server != NULL) bus_container_server_stop_listening (server); diff --git a/bus/driver.c b/bus/driver.c index 0ef07e92..f0063247 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -2647,7 +2647,7 @@ static const MessageHandler introspectable_message_handlers[] = { #ifdef DBUS_ENABLE_CONTAINERS static const MessageHandler containers_message_handlers[] = { - { "AddServer", "sssa{sv}a{sv}", "oays", bus_containers_handle_add_server, + { "AddServer", "sssa{sv}a{sv}", "oa{sv}", bus_containers_handle_add_server, METHOD_FLAG_NO_CONTAINERS }, { "StopServer", "o", "", bus_containers_handle_stop_server, METHOD_FLAG_NO_CONTAINERS }, diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index b4380dfb..a7663f5e 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -7489,8 +7489,7 @@ in DICT<STRING,VARIANT> metadata, in DICT<STRING,VARIANT> named_arguments, out OBJECT_PATH server_path, - out ARRAY<BYTE> socket_path, - out STRING connectable_address) + out DICT<STRING,VARIANT> results) Message arguments: @@ -7571,21 +7570,10 @@ 6 - ARRAY<BYTE> + DICT<STRING,VARIANT> - The absolute filesystem path of the resulting - AF_UNIX socket, followed by a single - zero (nul) byte, for example - /run/user/1000/dbus-12345vwxyz\x00 - where \x00 represents the terminating zero byte. - - - - 7 - STRING - - A connectable D-Bus address, for example - unix:path=/run/user/1000/dbus-12345vwxyz. + Details of the container-specific server that was + created (see below). @@ -7642,14 +7630,65 @@ extension point. + + Keys in the returned result dictionary not containing "." are defined + by this specification. Bus daemon implementors wishing to emit + information not mentioned in this document should use keys + containing "." and starting with a reversed domain name. + Additional keys may be added to the result at any time, and + callers must accept and ignore unknown keys in this dictionary. + + + + The defined keys for the result dictionary are: + + + + + Key + Value type + Value + + + + + Address + STRING + + A connectable D-Bus address, for example + unix:path=/run/user/1000/dbus-12345vwxyz. + + + + SocketPath + ARRAY of BYTE + + The absolute filesystem path of the resulting + AF_UNIX socket, followed by a single + zero (nul) byte, for example + /run/user/1000/dbus-12345vwxyz\x00 + where \x00 represents the terminating zero byte. + + + + + + + In the most basic form of a call to this method, the new server socket is an AF_UNIX socket at a path chosen - by the message bus and returned from the method. Future versions - of this specification are likely to provide a way for the - message bus implementation to receive a socket from the caller - and arrange for it to listen for connections, using the named - arguments dictionary. + by the message bus and returned from the method. + When operating in this way, each successful call will return a + result dictionary containing both Address and + SocketPath. + Callers may use whichever of those members is more convenient. + If a future version of this specification adds a mechanism to + request that the server listens in some way that makes these two + members inapplicable, for example receiving a socket from the + caller in the named arguments dictionary via file descriptor passing + and arranging for it to listen for connections, then those members + will be omitted from the result dictionary. diff --git a/test/containers.c b/test/containers.c index e613e0f4..d7df72f7 100644 --- a/test/containers.c +++ b/test/containers.c @@ -309,7 +309,9 @@ add_container_server (Fixture *f, GVariant *parameters) { GVariant *tuple; + GVariant *named_results; GStatBuf stat_buf; + gboolean found; f->proxy = g_dbus_proxy_new_sync (f->unconfined_conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, @@ -339,22 +341,30 @@ add_container_server (Fixture *f, g_assert_no_error (f->error); g_assert_nonnull (tuple); - g_assert_cmpstr (g_variant_get_type_string (tuple), ==, "(oays)"); - g_variant_get (tuple, "(o^ays)", &f->server_path, &f->socket_path, - &f->socket_dbus_address); + g_assert_cmpstr (g_variant_get_type_string (tuple), ==, "(oa{sv})"); + g_variant_get (tuple, "(o@a{sv})", &f->server_path, &named_results); + g_assert_nonnull (f->server_path); + g_assert_true (g_variant_is_object_path (f->server_path)); + + found = g_variant_lookup (named_results, "Address", + "s", &f->socket_dbus_address); + g_assert_true (found); + g_assert_nonnull (f->socket_dbus_address); g_assert_true (g_str_has_prefix (f->socket_dbus_address, "unix:")); g_assert_null (strchr (f->socket_dbus_address, ';')); g_assert_null (strchr (f->socket_dbus_address + strlen ("unix:"), ':')); - g_clear_pointer (&tuple, g_variant_unref); - g_assert_nonnull (f->server_path); - g_assert_true (g_variant_is_object_path (f->server_path)); + found = g_variant_lookup (named_results, "SocketPath", + "^ay", &f->socket_path); + g_assert_true (found); g_assert_nonnull (f->socket_path); g_assert_true (g_path_is_absolute (f->socket_path)); - g_assert_nonnull (f->socket_dbus_address); g_assert_cmpstr (g_stat (f->socket_path, &stat_buf) == 0 ? NULL : g_strerror (errno), ==, NULL); g_assert_cmpuint ((stat_buf.st_mode & S_IFMT), ==, S_IFSOCK); + + g_clear_pointer (&named_results, g_variant_unref); + g_clear_pointer (&tuple, g_variant_unref); return TRUE; } #endif @@ -1394,7 +1404,7 @@ test_max_containers (Fixture *f, NULL, &f->error); g_assert_no_error (f->error); g_assert_nonnull (tuple); - g_variant_get (tuple, "(o^ays)", &placeholders[i], NULL, NULL); + g_variant_get (tuple, "(o@a{sv})", &placeholders[i], NULL); g_variant_unref (tuple); g_test_message ("Placeholder server at %s", placeholders[i]); } @@ -1475,7 +1485,6 @@ test_max_connections_per_container (Fixture *f, * limit-containers.conf */ GSocket *placeholders[G_N_ELEMENTS (socket_paths) * 3] = { NULL }; GVariant *parameters; - GVariant *tuple; guint i; if (f->skip) @@ -1499,13 +1508,25 @@ test_max_connections_per_container (Fixture *f, for (i = 0; i < G_N_ELEMENTS (socket_paths); i++) { + GVariant *tuple; + GVariant *named_results; + gboolean found; + tuple = g_dbus_proxy_call_sync (f->proxy, "AddServer", parameters, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &f->error); g_assert_no_error (f->error); g_assert_nonnull (tuple); - g_variant_get (tuple, "(o^ays)", NULL, &socket_paths[i], - &dbus_addresses[i]); + g_variant_get (tuple, "(o@a{sv})", NULL, &named_results); + + found = g_variant_lookup (named_results, "Address", + "s", &dbus_addresses[i]); + g_assert_true (found); + found = g_variant_lookup (named_results, "SocketPath", + "^ay", &socket_paths[i]); + g_assert_true (found); + + g_variant_unref (named_results); g_variant_unref (tuple); socket_addresses[i] = g_unix_socket_address_new (socket_paths[i]); g_test_message ("Server #%u at %s", i, socket_paths[i]);