From 634989c499be0db83aba38c7d112b52a8e40db94 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 15 Jan 2018 16:40:06 +0000 Subject: [PATCH 7/8] containers: Add a method to ask to be sent the connection instance header Signed-off-by: Simon McVittie --- bus/connection.c | 35 ++++++++++++++++++++++++++++++++++- bus/connection.h | 9 +++++++++ bus/containers.c | 29 +++++++++++++++++++++++++++++ bus/containers.h | 4 ++++ bus/driver.c | 2 ++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/bus/connection.c b/bus/connection.c index 87f2f8a9..daef24bf 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -108,6 +108,7 @@ typedef struct long connection_tv_sec; /**< Time when we connected (seconds component) */ long connection_tv_usec; /**< Time when we connected (microsec component) */ int stamp; /**< connections->stamp last time we were traversed */ + BusExtraHeaders want_headers; #ifdef DBUS_ENABLE_STATS int peak_match_rules; @@ -2453,7 +2454,27 @@ bus_transaction_send (BusTransaction *transaction, d = BUS_CONNECTION_DATA (destination); _dbus_assert (d != NULL); - + + /* You might think that this is too late to be setting header fields, + * because the message is locked before sending - but remember that + * the message isn't actually queued to be sent (and hence locked) + * until we know we have enough memory for the entire transaction, + * and that doesn't happen until we know all the recipients. + * So this is about the last possible time we could edit the header. */ + if ((d->want_headers & BUS_EXTRA_HEADERS_CONTAINER_INSTANCE) && + dbus_message_get_container_instance (message) == NULL) + { + const char *path; + + if (sender == NULL || + !bus_containers_connection_is_contained (sender, &path, + NULL, NULL)) + path = "/"; + + if (!dbus_message_set_container_instance (message, path)) + return FALSE; + } + to_send = dbus_new (MessageToSend, 1); if (to_send == NULL) { @@ -2913,3 +2934,15 @@ bus_connection_be_monitor (DBusConnection *connection, return TRUE; } + +void +bus_connection_request_headers (DBusConnection *connection, + BusExtraHeaders headers) +{ + BusConnectionData *d; + + d = BUS_CONNECTION_DATA (connection); + _dbus_assert (d != NULL); + + d->want_headers |= headers; +} diff --git a/bus/connection.h b/bus/connection.h index 141fb0c0..736a3b28 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -28,6 +28,12 @@ #include #include "bus.h" +typedef enum +{ + BUS_EXTRA_HEADERS_CONTAINER_INSTANCE = (1 << 0), + BUS_EXTRA_HEADERS_NONE = 0 +} BusExtraHeaders; + typedef dbus_bool_t (* BusConnectionForeachFunction) (DBusConnection *connection, void *data); @@ -84,6 +90,9 @@ dbus_bool_t bus_connection_preallocate_oom_error (DBusConnection *connection); void bus_connection_send_oom_error (DBusConnection *connection, DBusMessage *in_reply_to); +void bus_connection_request_headers (DBusConnection *connection, + BusExtraHeaders headers); + /* called by signals.c */ dbus_bool_t bus_connection_add_match_rule (DBusConnection *connection, BusMatchRule *rule); diff --git a/bus/containers.c b/bus/containers.c index 6eb327ff..a125b739 100644 --- a/bus/containers.c +++ b/bus/containers.c @@ -1297,6 +1297,35 @@ failed: return FALSE; } +dbus_bool_t +bus_containers_handle_request_header (DBusConnection *caller, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + DBusMessage *reply = NULL; + dbus_bool_t ret = FALSE; + + reply = dbus_message_new_method_return (message); + + /* We prepare the transaction before carrying out its side-effects, + * because otherwise it isn't transactional */ + if (reply == NULL || + !bus_transaction_send_from_driver (transaction, caller, reply)) + { + BUS_SET_OOM (error); + goto out; + } + + bus_connection_request_headers (caller, + BUS_EXTRA_HEADERS_CONTAINER_INSTANCE); + ret = TRUE; + +out: + dbus_clear_message (&reply); + return ret; +} + void bus_containers_stop_listening (BusContainers *self) { diff --git a/bus/containers.h b/bus/containers.h index 05ed0e75..7046bcbc 100644 --- a/bus/containers.h +++ b/bus/containers.h @@ -52,6 +52,10 @@ dbus_bool_t bus_containers_handle_get_connection_instance (DBusConnection *conne BusTransaction *transaction, DBusMessage *message, DBusError *error); +dbus_bool_t bus_containers_handle_request_header (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 d0700029..0b2709a3 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -2598,6 +2598,8 @@ static const MessageHandler containers_message_handlers[] = { METHOD_FLAG_NONE }, { "GetInstanceInfo", "o", "a{sv}ssa{sv}", bus_containers_handle_get_instance_info, METHOD_FLAG_NONE }, + { "RequestHeader", "", "", bus_containers_handle_request_header, + METHOD_FLAG_NONE }, { NULL, NULL, NULL, NULL } }; static const PropertyHandler containers_property_handlers[] = { -- 2.15.1