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;
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)
{
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;
+}
#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);
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);
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)
{
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);
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[] = {