]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
containers: Add a method to ask to be sent the connection instance header
authorSimon McVittie <smcv@collabora.com>
Mon, 15 Jan 2018 16:40:06 +0000 (16:40 +0000)
committerSimon McVittie <smcv@collabora.com>
Fri, 16 Feb 2018 15:27:51 +0000 (15:27 +0000)
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

bus/connection.c
bus/connection.h
bus/containers.c
bus/containers.h
bus/driver.c

index 87f2f8a9debe9a276713c4e25449777fccc17add..daef24bf17e25960136de7de6764546b368146d9 100644 (file)
@@ -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;
+}
index 141fb0c0bc7583755ac315317ed0cabef3fb6c11..736a3b28ddb6b8c9eb7d937768e5642e4fb1ce29 100644 (file)
 #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);
index 6eb327ff55874c38226cebe887741f65068d0708..a125b73914d763fe3dfa520a2cf2782680f1ca4c 100644 (file)
@@ -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)
 {
index 05ed0e75d7412261c8635318106184f2979f1d92..7046bcbc393a69b62083ecd8e4dde0837b0fa9c7 100644 (file)
@@ -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);
 
index d07000292059ffc593cff697d4cb7461ff0af143..0b2709a3be1d0114905a341cfb1a628a155848ae 100644 (file)
@@ -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[] = {