summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2018-01-15 16:40:06 +0000
committerSimon McVittie <smcv@collabora.com>2018-02-16 15:27:51 +0000
commit624e9242840ed2b15fff5490c24802c47154f725 (patch)
tree6dd25af2c9eb8b2ac13422f5039fa824e5e1b531
parent953bc072a3335a7fb232790a2d323094ad4a0e13 (diff)
containers: Add a method to ask to be sent the connection instance header
Signed-off-by: Simon McVittie <smcv@collabora.com> Reviewed-by: Philip Withnall <withnall@endlessm.com> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101899
-rw-r--r--bus/connection.c35
-rw-r--r--bus/connection.h9
-rw-r--r--bus/containers.c29
-rw-r--r--bus/containers.h4
-rw-r--r--bus/driver.c2
5 files changed, 78 insertions, 1 deletions
diff --git a/bus/connection.c b/bus/connection.c
index 87f2f8a9d..daef24bf1 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 141fb0c0b..736a3b28d 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -28,6 +28,12 @@
#include <dbus/dbus-list.h>
#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 6eb327ff5..a125b7391 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 05ed0e75d..7046bcbc3 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 d07000292..0b2709a3b 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[] = {