From c8f9cd665b048ef4ee7c187a321526333084c86c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 22 Jun 2017 22:18:34 +0100 Subject: [PATCH 27/49] bus/containers: Implement methods to stop containers explicitly Signed-off-by: Simon McVittie --- bus/containers.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ bus/containers.h | 10 ++++++ bus/driver.c | 6 ++++ dbus/dbus-protocol.h | 3 ++ 4 files changed, 119 insertions(+) diff --git a/bus/containers.c b/bus/containers.c index c7c1e432..8189711a 100644 --- a/bus/containers.c +++ b/bus/containers.c @@ -38,6 +38,7 @@ #include "dbus/dbus-sysdeps-unix.h" #include "connection.h" +#include "driver.h" #include "utils.h" /* @@ -710,6 +711,105 @@ bus_containers_supported_arguments_getter (BusContext *context, dbus_message_iter_close_container (var_iter, &arr_iter); } +dbus_bool_t +bus_containers_handle_stop_container_instance (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + BusContext *context; + BusContainers *containers; + BusContainerInstance *instance = NULL; + DBusList *iter; + const char *path; + + if (!dbus_message_get_args (message, error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto failed; + + context = bus_transaction_get_context (transaction); + containers = bus_context_get_containers (context); + + if (containers->instances_by_path != NULL) + { + instance = _dbus_hash_table_lookup_string (containers->instances_by_path, + path); + } + + if (instance == NULL) + { + dbus_set_error (error, DBUS_ERROR_NOT_CONTAINER, + "There is no container with path '%s'", path); + goto failed; + } + + bus_container_instance_ref (instance); + bus_container_instance_stop_listening (instance); + + for (iter = _dbus_list_get_first_link (&instance->connections); + iter != NULL; + iter = _dbus_list_get_next_link (&instance->connections, iter)) + dbus_connection_close (iter->data); + + bus_container_instance_unref (instance); + + if (!bus_driver_send_ack_reply (connection, transaction, message, error)) + goto failed; + + return TRUE; + +failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + return FALSE; +} + +dbus_bool_t +bus_containers_handle_stop_container_listening (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + BusContext *context; + BusContainers *containers; + BusContainerInstance *instance = NULL; + const char *path; + + if (!dbus_message_get_args (message, error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto failed; + + context = bus_transaction_get_context (transaction); + containers = bus_context_get_containers (context); + + if (containers->instances_by_path != NULL) + { + instance = _dbus_hash_table_lookup_string (containers->instances_by_path, + path); + } + + if (instance == NULL) + { + dbus_set_error (error, DBUS_ERROR_NOT_CONTAINER, + "There is no container with path '%s'", path); + goto failed; + } + + bus_container_instance_ref (instance); + bus_container_instance_stop_listening (instance); + bus_container_instance_unref (instance); + + if (!bus_driver_send_ack_reply (connection, transaction, message, error)) + goto failed; + + return TRUE; + +failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + return FALSE; +} + #else BusContainers * diff --git a/bus/containers.h b/bus/containers.h index eb20599a..cbbaf980 100644 --- a/bus/containers.h +++ b/bus/containers.h @@ -34,6 +34,16 @@ dbus_bool_t bus_containers_handle_add_container_server (DBusConnection *connecti DBusMessage *message, DBusError *error); +dbus_bool_t bus_containers_handle_stop_container_instance (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error); + +dbus_bool_t bus_containers_handle_stop_container_listening (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error); + dbus_bool_t bus_containers_supported_arguments_getter (BusContext *context, DBusMessageIter *var_iter); diff --git a/bus/driver.c b/bus/driver.c index 8fcfd020..42139a62 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -2523,6 +2523,12 @@ static const MessageHandler containers_message_handlers[] = { { "AddContainerServer", "ssa{sv}a{sv}", "oays", bus_containers_handle_add_container_server, METHOD_FLAG_PRIVILEGED }, + { "StopContainerInstance", "o", "", + bus_containers_handle_stop_container_instance, + METHOD_FLAG_PRIVILEGED }, + { "StopContainerListening", "o", "", + bus_containers_handle_stop_container_listening, + METHOD_FLAG_PRIVILEGED }, { NULL, NULL, NULL, NULL } }; static const PropertyHandler containers_property_handlers[] = { diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 933c3658..56be9832 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -455,6 +455,9 @@ extern "C" { * but could have succeeded if an interactive authorization step was * allowed. */ #define DBUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired" +/** The connection is not from a container, or the specified container instance + * does not exist. */ +#define DBUS_ERROR_NOT_CONTAINER "org.freedesktop.DBus.Error.NotContainer" /* XML introspection format */ -- 2.11.0