[glib/wip/kdbus-junk: 37/37] wip junk
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/kdbus-junk: 37/37] wip junk
- Date: Wed, 10 Dec 2014 16:00:20 +0000 (UTC)
commit b3f8546dd21a65f2f938de78d9597364c42f0386
Author: Ryan Lortie <desrt desrt ca>
Date: Wed Dec 10 10:56:38 2014 -0500
wip junk
gio/gapplicationimpl-dbus.c | 12 +-
gio/gdbusconnection.c | 27 +--
gio/gdbusmessage.c | 330 ++----------------------
gio/gdbusmessage.h | 10 -
gio/gdbusmethodinvocation.c | 38 +++
gio/gdbusmethodinvocation.h | 5 +
gio/gdbusprivate.c | 39 +---
gio/gdbusprivate.h | 3 +
gio/gkdbus.c | 614 ++++++++++++++++++-------------------------
gio/gkdbus.h | 4 +-
gio/gunixfdlist.h | 3 +
gio/kdbus.h | 11 +-
glib/gvariant-core.c | 7 +-
13 files changed, 355 insertions(+), 748 deletions(-)
---
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index 94cf6ea..4b1b5c9 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -852,13 +852,13 @@ g_dbus_command_line_get_stdin (GApplicationCommandLine *cmdline)
if (fd_list && g_unix_fd_list_get_length (fd_list))
{
- gint *fds, n_fds, i;
+ gint *fds, i;
- fds = g_unix_fd_list_steal_fds (fd_list, &n_fds);
- result = g_unix_input_stream_new (fds[0], TRUE);
- for (i = 1; i < n_fds; i++)
- (void) g_close (fds[i], NULL);
- g_free (fds);
+ fds = g_unix_fd_list_peek_fds (fd_list, NULL);
+ result = g_unix_input_stream_new (fds[0], FALSE);
+ g_object_weak_ref (G_OBJECT (result),
+ (GWeakNotify) g_object_unref,
+ g_object_ref (fd_list));
}
return result;
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index d9ee982..1a896b9 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -2124,29 +2124,20 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
error))
goto out;
- /* [KDBUS]
- * Setting protocol version, before invoking g_dbus_message_to_blob() will
- * be removed after preparing new function only for kdbus transport purposes
- * (this function will be able to create blob directly/unconditionally in memfd
- * object, without making copy)
- */
-
- if (G_IS_KDBUS_CONNECTION (connection->stream))
- _g_dbus_message_set_protocol_ver (message,2);
- else
- _g_dbus_message_set_protocol_ver (message,1);
-
blob = g_dbus_message_to_blob (message,
&blob_size,
connection->capabilities,
error);
+
if (blob == NULL)
goto out;
- if (flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL)
- serial_to_use = g_dbus_message_get_serial (message);
- else
- serial_to_use = ++connection->last_serial; /* TODO: handle overflow */
+ if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL))
+ g_dbus_message_set_serial (message, ++connection->last_serial);
+
+ serial_to_use = g_dbus_message_get_serial (message);
+
+ g_dbus_message_lock (message);
switch (blob[0])
{
@@ -2183,10 +2174,6 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
g_thread_self (),
GUINT_TO_POINTER (serial_to_use));
- if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL))
- g_dbus_message_set_serial (message, serial_to_use);
-
- g_dbus_message_lock (message);
_g_dbus_worker_send_message (connection->worker,
message,
(gchar*) blob,
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 4d4cb69..a0e1f7b 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -49,7 +49,6 @@
#include "gdbusprivate.h"
#ifdef G_OS_UNIX
-#include "gkdbus.h"
#include "gunixfdlist.h"
#endif
@@ -973,38 +972,6 @@ g_dbus_message_set_serial (GDBusMessage *message,
/* ---------------------------------------------------------------------------------------------------- */
-/**
- * _g_dbus_message_get_protocol_ver:
- * To remove - more info [1]
- * [1] https://bugzilla.gnome.org/show_bug.cgi?id=721861
- */
-guint32
-_g_dbus_message_get_protocol_ver (GDBusMessage *message)
-{
- g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
- return message->major_protocol_version;
-}
-
-/**
- * _g_dbus_message_set_protocol_ver:
- * To remove - more info [1]
- * [1] https://bugzilla.gnome.org/show_bug.cgi?id=721861
- */
-void
-_g_dbus_message_set_protocol_ver (GDBusMessage *message,
- guint32 protocol_ver)
-{
- g_return_if_fail (G_IS_DBUS_MESSAGE (message));
-
- if (message->locked)
- {
- g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
- return;
- }
-
- message->major_protocol_version = protocol_ver;
-}
-
/* TODO: need GI annotations to specify that any guchar value goes for header_field */
/**
@@ -2225,219 +2192,6 @@ g_dbus_message_new_from_blob (guchar *blob,
/* ---------------------------------------------------------------------------------------------------- */
-/*
- * _g_dbus_message_new_from_kdbus_items:
- *
- * Single kdbus message may contain zero, one or more items
- * (PAYLOAD_VEC or PAYLOAD_MEMFD), so we need this function
- * (only for kdbus transport purposes) to parse them to GDBusMessage.
- * kdbus_msg_items list contain list of pointer + data pair for each received item.
- *
- * TODO: Add support for two and more items
- */
-
-GDBusMessage *
-_g_dbus_message_new_from_kdbus_items (GSList *kdbus_msg_items,
- GError **error)
-{
- gboolean ret;
- GMemoryBuffer mbuf;
- GDBusMessage *message;
- guchar endianness;
- guchar major_protocol_version;
- guint32 message_body_len;
- guint32 message_headers_len;
- GVariant *headers;
- GVariant *item;
- GVariantIter iter;
- GVariant *signature;
-
- ret = FALSE;
-
- g_return_val_if_fail (kdbus_msg_items != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- message = g_dbus_message_new ();
- memset (&mbuf, 0, sizeof (mbuf));
-
- /*
- * MESSAGE HEADER
- * message header in its entirety must be contained in a first single item
- */
- mbuf.data = ((msg_part*)kdbus_msg_items->data)->data;
- mbuf.len = mbuf.valid_len = ((msg_part*)kdbus_msg_items->data)->size;
-
- endianness = g_memory_buffer_read_byte (&mbuf);
- switch (endianness)
- {
- case 'l':
- mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
- message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
- break;
- case 'B':
- mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
- message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
- break;
- default:
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value 0x%02x"),
- endianness);
- goto out;
- }
-
- message->type = g_memory_buffer_read_byte (&mbuf);
- message->flags = g_memory_buffer_read_byte (&mbuf);
- major_protocol_version = g_memory_buffer_read_byte (&mbuf);
-
- if (major_protocol_version != 2)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid major protocol version. Expected 2 but found %d"),
- major_protocol_version);
- goto out;
- }
-
- message_body_len = g_memory_buffer_read_uint32 (&mbuf);
- message->serial = g_memory_buffer_read_uint32 (&mbuf);
-
- message_headers_len = g_memory_buffer_read_uint32 (&mbuf);
- headers = g_variant_new_from_data (G_VARIANT_TYPE ("a{yv}"),
- mbuf.data + mbuf.pos,
- message_headers_len,
- TRUE,
- NULL,
- NULL);
- mbuf.pos += message_headers_len;
-
- if (headers == NULL)
- goto out;
- g_variant_iter_init (&iter, headers);
- while ((item = g_variant_iter_next_value (&iter)) != NULL)
- {
- guchar header_field;
- GVariant *value;
- g_variant_get (item,
- "{yv}",
- &header_field,
- &value);
- g_dbus_message_set_header (message, header_field, value);
- g_variant_unref (value);
- g_variant_unref (item);
- }
- g_variant_unref (headers);
-
- signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
- if (signature != NULL)
- {
- const gchar *signature_str;
- gsize signature_str_len;
-
- signature_str = g_variant_get_string (signature, &signature_str_len);
-
- if (signature_str_len > 0)
- {
- GVariantType *variant_type;
- gchar *tupled_signature_str;
-
- gchar *data = NULL;
- gsize size = NULL;
-
- if (!g_variant_is_signature (signature_str))
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Parsed value '%s' is not a valid D-Bus signature (for body)"),
- signature_str);
- goto out;
- }
- tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
- variant_type = g_variant_type_new (tupled_signature_str);
- g_free (tupled_signature_str);
-
- /*
- * MESSAGE BODY
- */
-
- if (g_slist_length(kdbus_msg_items) == 1)
- {
- /* if kdbus_msg_items has only one element, head and body are
- contained in a single PAYLOAD_VEC item */
- ensure_input_padding (&mbuf,8);
- data = mbuf.data + mbuf.pos;
- size = message_body_len;
- }
- else if (g_slist_length(kdbus_msg_items) > 1)
- {
- /* message consists two or more items
- TODO: Add support for three and more items */
- data = ((msg_part*)g_slist_next(kdbus_msg_items)->data)->data;
- size = ((msg_part*)g_slist_next(kdbus_msg_items)->data)->size;
- }
- else
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("[KDBUS] Received message is not valid"));
- goto out;
- }
-
- message->body = g_variant_new_from_data (variant_type,
- data,
- size,
- TRUE,
- NULL,
- NULL);
-
- g_variant_type_free (variant_type);
- if (message->body == NULL)
- goto out;
- }
- }
- else
- {
- /* no signature, this is only OK if the body is empty */
- if (message_body_len != 0)
- {
- /* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- g_dngettext (GETTEXT_PACKAGE,
- "No signature header in message but the message body is %u byte",
- "No signature header in message but the message body is %u bytes",
- message_body_len),
- message_body_len);
- goto out;
- }
- }
-
- if (!validate_headers (message, error))
- {
- g_prefix_error (error, _("Cannot deserialize message: "));
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (ret)
- {
- return message;
- }
- else
- {
- if (message != NULL)
- g_object_unref (message);
- return NULL;
- }
-}
-
static gsize
ensure_output_padding (GMemoryBuffer *mbuf,
gsize padding_size)
@@ -2813,12 +2567,6 @@ append_body_to_blob (GVariant *value,
/* ---------------------------------------------------------------------------------------------------- */
-/* [KDBUS]
- * g_dbus_message_to_blob() will be replaced by new function only for kdbus transport
- * purposes (this function will be able to create blob directly/unconditionally in memfd
- * object, without making copy)
- */
-
/**
* g_dbus_message_to_blob:
* @message: A #GDBusMessage.
@@ -2847,11 +2595,7 @@ g_dbus_message_to_blob (GDBusMessage *message,
goffset body_len_offset;
goffset body_start_offset;
gsize body_size;
- gconstpointer message_body_data;
- gsize message_body_size;
GVariant *header_fields;
- gsize header_fields_size;
- gconstpointer header_fields_data;
GVariantBuilder builder;
GHashTableIter hash_iter;
gpointer key;
@@ -2869,20 +2613,6 @@ g_dbus_message_to_blob (GDBusMessage *message,
g_return_val_if_fail (out_size != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- /* temporary solution */
- if (!message->major_protocol_version)
- g_error ("message->major_protocol_version is not set");
-
- if (message->major_protocol_version != 1 && message->major_protocol_version != 2)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid major protocol version. Expected 1 or 2 but found %d"),
- message->major_protocol_version);
- goto out;
- }
-
memset (&mbuf, 0, sizeof (mbuf));
mbuf.len = MIN_ARRAY_SIZE;
mbuf.data = g_malloc (mbuf.len);
@@ -2902,10 +2632,7 @@ g_dbus_message_to_blob (GDBusMessage *message,
g_memory_buffer_put_byte (&mbuf, (guchar) message->byte_order);
g_memory_buffer_put_byte (&mbuf, message->type);
g_memory_buffer_put_byte (&mbuf, message->flags);
-
- /* major protocol version */
- g_memory_buffer_put_byte (&mbuf, message->major_protocol_version);
-
+ g_memory_buffer_put_byte (&mbuf, 1); /* major protocol version */
body_len_offset = mbuf.valid_len;
/* body length - will be filled in later */
g_memory_buffer_put_uint32 (&mbuf, 0xF00DFACE);
@@ -2945,30 +2672,15 @@ g_dbus_message_to_blob (GDBusMessage *message,
}
header_fields = g_variant_builder_end (&builder);
- /* header - dbus1 marshaliling */
- if (message->major_protocol_version == 1)
- {
- if (!append_value_to_blob (header_fields,
- g_variant_get_type (header_fields),
- &mbuf,
- NULL,
- error))
- {
- g_variant_unref (header_fields);
- goto out;
- }
-
- }
- /* header - GVariant marshalling */
- else if (message->major_protocol_version == 2)
+ if (!append_value_to_blob (header_fields,
+ g_variant_get_type (header_fields),
+ &mbuf,
+ NULL,
+ error))
{
- header_fields_data = g_variant_get_data (header_fields);
- header_fields_size = g_variant_get_size (header_fields);
-
- g_memory_buffer_put_uint32 (&mbuf, header_fields_size);
- g_memory_buffer_write (&mbuf, header_fields_data, header_fields_size);
+ g_variant_unref (header_fields);
+ goto out;
}
-
g_variant_unref (header_fields);
/* header size must be a multiple of 8 */
@@ -3005,23 +2717,8 @@ g_dbus_message_to_blob (GDBusMessage *message,
goto out;
}
g_free (tupled_signature_str);
-
- /* body - dbus1 marshaliling */
- if (message->major_protocol_version == 1)
- {
- if (!append_body_to_blob (message->body, &mbuf, error))
- goto out;
- }
-#if 0
- /* body - GVariant marshalling */
- else if (message->major_protocol_version == 2)
- {
- message_body_data = g_variant_get_data (message->body);
- message_body_size = g_variant_get_size (message->body);
-
- g_memory_buffer_write (&mbuf, message_body_data, message_body_size);
- }
-#endif
+ if (!append_body_to_blob (message->body, &mbuf, error))
+ goto out;
}
else
{
@@ -3931,3 +3628,10 @@ g_dbus_message_copy (GDBusMessage *message,
#endif
return ret;
}
+
+void
+g_dbus_message_init_header_iter (GDBusMessage *message,
+ GHashTableIter *iter)
+{
+ g_hash_table_iter_init (iter, message->headers);
+}
diff --git a/gio/gdbusmessage.h b/gio/gdbusmessage.h
index 8f9b25e..f791889 100644
--- a/gio/gdbusmessage.h
+++ b/gio/gdbusmessage.h
@@ -192,16 +192,6 @@ GLIB_AVAILABLE_IN_ALL
gboolean g_dbus_message_to_gerror (GDBusMessage *message,
GError **error);
-GDBusMessage *_g_dbus_message_new_from_kdbus_items (GSList *kdbus_msg_items,
- GError **error);
-
-/* to remove */
-guint32 _g_dbus_message_get_protocol_ver (GDBusMessage *message);
-
-/* to remove */
-void _g_dbus_message_set_protocol_ver (GDBusMessage *message,
- guint32 protocol_ver);
-
G_END_DECLS
#endif /* __G_DBUS_MESSAGE_H__ */
diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c
index 5bd850b..412ed36 100644
--- a/gio/gdbusmethodinvocation.c
+++ b/gio/gdbusmethodinvocation.c
@@ -306,6 +306,44 @@ g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation)
}
/**
+ * g_dbus_method_invocation_peek_unix_fd:
+ * @invocation: A #GDBusMethodInvocation.
+ * @index_: the index
+ *
+ * Gets the fd associated with @index in the method invocation.
+ *
+ * If there is no file descriptor at the given index, -1 is returned.
+ *
+ * The returned file descriptor is owned by the message and must not be
+ * closed by the caller. Use dup() if you want your own copy.
+ *
+ * Returns: the file descriptor, or -1
+ */
+#ifdef G_OS_UNIX
+gint
+g_dbus_method_invocation_peek_unix_fd (GDBusMethodInvocation *invocation,
+ guint index_)
+{
+ GUnixFDList *fd_list;
+
+ fd_list = g_dbus_message_get_unix_fd_list (invocation->message);
+
+ if (fd_list)
+ {
+ const gint *fds;
+ gint n_fds;
+
+ fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
+
+ if (index_ < (guint) n_fds)
+ return fds[index_];
+ }
+
+ return -1;
+}
+#endif
+
+/**
* g_dbus_method_invocation_get_user_data: (skip)
* @invocation: A #GDBusMethodInvocation.
*
diff --git a/gio/gdbusmethodinvocation.h b/gio/gdbusmethodinvocation.h
index 6354e41..1d24283 100644
--- a/gio/gdbusmethodinvocation.h
+++ b/gio/gdbusmethodinvocation.h
@@ -53,6 +53,11 @@ GLIB_AVAILABLE_IN_ALL
GDBusMessage *g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation);
GLIB_AVAILABLE_IN_ALL
GVariant *g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation);
+#ifdef G_OS_UNIX
+GLIB_AVAILABLE_IN_2_44
+gint g_dbus_method_invocation_peek_unix_fd (GDBusMethodInvocation *invocation,
+ guint index_);
+#endif
GLIB_AVAILABLE_IN_ALL
gpointer g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation);
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 27d63bc..934bebf 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -702,12 +702,6 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
res,
&error);
- /* [KDBUS] Get all received items*/
- worker->read_kdbus_msg_items = _g_kdbus_get_last_msg_items (worker->kdbus);
-
- /* [KDBUS] Attach fds (if any) to worker->read_fd_list */
- _g_kdbus_attach_fds_to_msg (worker->kdbus, &worker->read_fd_list);
-
/* [KDBUS] For KDBUS transport we read whole message at once*/
worker->read_buffer_bytes_wanted = bytes_read;
}
@@ -886,30 +880,6 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
else if (G_IS_KDBUS_CONNECTION (worker->stream))
{
- GDBusMessageType message_type;
- gchar *sender;
- gchar *destination;
-
- message = _g_dbus_message_new_from_kdbus_items (worker->read_kdbus_msg_items,
- &error);
-
- /* [KDBUS] override informations from the user header with kernel msg header */
- sender = _g_kdbus_get_last_msg_sender (worker->kdbus);
- g_dbus_message_set_sender (message, sender);
-
- message_type = g_dbus_message_get_message_type (message);
- if (message_type == G_DBUS_MESSAGE_TYPE_SIGNAL)
- {
- destination = _g_kdbus_get_last_msg_destination (worker->kdbus);
- g_dbus_message_set_destination (message, destination);
- }
-
- if (message == NULL)
- {
- g_warning ("Error decoding D-Bus (kdbus) message\n");
- g_error_free (error);
- goto out;
- }
}
#endif
else
@@ -995,11 +965,6 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
/* [KDBUS] release memory occupied by kdbus message */
if (G_IS_KDBUS_CONNECTION (worker->stream))
{
- if (!_g_kdbus_is_closed (worker->kdbus))
- {
- _g_kdbus_release_kmsg (worker->kdbus);
- worker->read_kdbus_msg_items = NULL;
- }
worker->read_buffer = NULL;
}
#endif
@@ -1766,9 +1731,7 @@ continue_writing (GDBusWorker *worker)
*/
if (G_IS_KDBUS_CONNECTION (worker->stream))
- _g_dbus_message_set_protocol_ver (data->message,2);
- else
- _g_dbus_message_set_protocol_ver (data->message,1);
+ g_assert_not_reached ();
new_blob = g_dbus_message_to_blob (data->message,
&new_blob_size,
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
index 0e38121..ba1e60a 100644
--- a/gio/gdbusprivate.h
+++ b/gio/gdbusprivate.h
@@ -145,6 +145,9 @@ void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy,
/* Implemented in gdbusconnection.c */
GDBusConnection *_g_bus_get_singleton_if_exists (GBusType bus_type);
+void g_dbus_message_init_header_iter (GDBusMessage *message,
+ GHashTableIter *iter);
+
G_END_DECLS
#endif /* __G_DBUS_PRIVATE_H__ */
diff --git a/gio/gkdbus.c b/gio/gkdbus.c
index f249b2f..67fdc43 100644
--- a/gio/gkdbus.c
+++ b/gio/gkdbus.c
@@ -93,7 +93,6 @@ struct _GKdbusPrivate
gint fd;
gchar *kdbus_buffer;
- struct kdbus_msg *kmsg;
gchar *unique_name;
guint64 unique_id;
@@ -102,13 +101,6 @@ struct _GKdbusPrivate
guint64 attach_flags_send;
guint64 attach_flags_recv;
- GString *msg_sender;
- GString *msg_destination;
- GSList *kdbus_msg_items;
-
- gint *fds;
- gint num_fds;
-
gsize bloom_size;
guint bloom_n_hash;
@@ -151,55 +143,6 @@ const guint8 hash_keys[8][16] =
/**
- * _g_kdbus_get_last_msg_sender
- *
- */
-gchar *
-_g_kdbus_get_last_msg_sender (GKdbus *kdbus)
-{
- return kdbus->priv->msg_sender->str;
-}
-
-
-/**
- * _g_kdbus_get_last_msg_destination
- *
- */
-gchar *
-_g_kdbus_get_last_msg_destination (GKdbus *kdbus)
-{
- return kdbus->priv->msg_destination->str;
-}
-
-
-/**
- * _g_kdbus_get_last_msg_items:
- *
- */
-GSList *
-_g_kdbus_get_last_msg_items (GKdbus *kdbus)
-{
- return kdbus->priv->kdbus_msg_items;
-}
-
-
-/**
- * g_kdbus_add_msg_part:
- *
- */
-static void
-g_kdbus_add_msg_part (GKdbus *kdbus,
- gchar *data,
- gsize size)
-{
- msg_part* part = g_new (msg_part, 1);
- part->data = data;
- part->size = size;
- kdbus->priv->kdbus_msg_items = g_slist_append (kdbus->priv->kdbus_msg_items, part);
-}
-
-
-/**
* _g_kdbus_hexdump_all_items:
*
*/
@@ -241,9 +184,6 @@ g_kdbus_finalize (GObject *object)
if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
_g_kdbus_close (kdbus, NULL);
- g_string_free (kdbus->priv->msg_sender, TRUE);
- g_string_free (kdbus->priv->msg_destination, TRUE);
-
if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
(*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
}
@@ -289,17 +229,10 @@ g_kdbus_init (GKdbus *kdbus)
kdbus->priv->unique_name = NULL;
kdbus->priv->kdbus_buffer = NULL;
- kdbus->priv->kdbus_msg_items = NULL;
-
- kdbus->priv->msg_sender = g_string_new (NULL);
- kdbus->priv->msg_destination = g_string_new (NULL);
kdbus->priv->flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
kdbus->priv->attach_flags_send = _KDBUS_ATTACH_ALL;
kdbus->priv->attach_flags_recv = _KDBUS_ATTACH_ALL;
-
- kdbus->priv->fds = NULL;
- kdbus->priv->num_fds = 0;
}
@@ -1361,7 +1294,7 @@ _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
struct kdbus_cmd_match *cmd_match;
gssize size, len;
gint ret;
- guint64 old_id;
+ guint64 old_id = 0; /* XXX why? */
guint64 new_id = KDBUS_MATCH_ID_ANY;
kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
@@ -1539,94 +1472,6 @@ _g_kdbus_unsubscribe_name_lost (GDBusConnection *connection)
/**
- * _g_kdbus_release_msg:
- *
- */
-void
-_g_kdbus_release_kmsg (GKdbus *kdbus)
-{
- struct kdbus_item *item = NULL;
- GSList *iterator = NULL;
- guint64 offset;
-
- offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
- ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
-
- for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
- g_free ((msg_part*)iterator->data);
-
- g_slist_free (kdbus->priv->kdbus_msg_items);
- kdbus->priv->kdbus_msg_items = NULL;
-
- KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
- {
- if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
- close(item->memfd.fd);
- else if (item->type == KDBUS_ITEM_FDS)
- {
- gint i;
- gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
-
- for (i = 0; i < num_fds; i++)
- close(item->fds[i]);
- }
- }
-}
-
-
-/**
- * g_kdbus_append_payload_vec:
- *
- */
-static void
-g_kdbus_append_payload_vec (struct kdbus_item **item,
- const void *data_ptr,
- gssize size)
-{
- *item = KDBUS_ALIGN8_PTR(*item);
- (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
- (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
- (*item)->vec.address = (guint64)((guintptr)data_ptr);
- (*item)->vec.size = size;
- *item = KDBUS_ITEM_NEXT(*item);
-}
-
-/**
- * g_kdbus_append_payload_memfd:
- *
- */
-static void
-g_kdbus_append_payload_memfd (struct kdbus_item **item,
- gint fd,
- gssize size)
-{
- *item = KDBUS_ALIGN8_PTR(*item);
- (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
- (*item)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
- (*item)->memfd.fd = fd;
- (*item)->memfd.size = size;
- *item = KDBUS_ITEM_NEXT(*item);
-}
-
-
-/**
- * g_kdbus_append_payload_destiantion:
- *
- */
-static void
-g_kdbus_append_destination (struct kdbus_item **item,
- const gchar *destination,
- gsize size)
-{
- *item = KDBUS_ALIGN8_PTR(*item);
- (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
- (*item)->type = KDBUS_ITEM_DST_NAME;
- memcpy ((*item)->str, destination, size+1);
- *item = KDBUS_ITEM_NEXT(*item);
-}
-
-
-/**
* g_kdbus_append_payload_bloom:
*
*/
@@ -1649,50 +1494,6 @@ g_kdbus_append_bloom (struct kdbus_item **item,
/**
- * g_kdbus_append_fds:
- *
- */
-static void
-g_kdbus_append_fds (struct kdbus_item **item,
- GUnixFDList *fd_list)
-{
- *item = KDBUS_ALIGN8_PTR(*item);
- (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) *
g_unix_fd_list_get_length(fd_list);
- (*item)->type = KDBUS_ITEM_FDS;
- memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) *
g_unix_fd_list_get_length(fd_list));
-
- *item = KDBUS_ITEM_NEXT(*item);
-}
-
-
-/**
- * _g_kdbus_attach_fds_to_msg:
- *
- */
-void
-_g_kdbus_attach_fds_to_msg (GKdbus *kdbus,
- GUnixFDList **fd_list)
-{
- if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
- {
- gint n;
-
- if (*fd_list == NULL)
- *fd_list = g_unix_fd_list_new();
-
- for (n = 0; n < kdbus->priv->num_fds; n++)
- {
- g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
- (void) g_close (kdbus->priv->fds[n], NULL);
- }
-
- g_free (kdbus->priv->fds);
- kdbus->priv->fds = NULL;
- kdbus->priv->num_fds = 0;
- }
-}
-
-/**
* g_kdbus_bloom_add_data:
* Based on bus-bloom.c from systemd
* http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
@@ -1884,13 +1685,13 @@ g_kdbus_setup_bloom (GKdbus *kdbus,
* g_kdbus_decode_kernel_msg:
*
*/
-static gssize
-g_kdbus_decode_kernel_msg (GKdbus *kdbus)
+static void
+g_kdbus_decode_kernel_msg (GKdbus *kdbus,
+ struct kdbus_msg *msg)
{
struct kdbus_item *item = NULL;
- gssize size = 0;
- KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
+ KDBUS_ITEM_FOREACH(item, msg, items)
{
switch (item->type)
{
@@ -1914,7 +1715,7 @@ g_kdbus_decode_kernel_msg (GKdbus *kdbus)
}
}
-
+#if 0
/* Override information from the user header with data from the kernel */
g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
@@ -1928,6 +1729,7 @@ g_kdbus_decode_kernel_msg (GKdbus *kdbus)
g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64)
kdbus->priv->kmsg->dst_id);
return size;
+#endif
}
@@ -1936,21 +1738,28 @@ g_kdbus_decode_kernel_msg (GKdbus *kdbus)
*
*/
static GDBusMessage *
-g_kdbus_decode_dbus_msg (GKdbus *kdbus,
- struct kdbus_cmd_recv *recv)
+g_kdbus_decode_dbus_msg (GKdbus *kdbus,
+ struct kdbus_msg *msg)
{
+ GDBusMessage *message;
struct kdbus_item *item;
gssize data_size = 0;
- const gchar *destination = NULL;
GArray *body_vectors;
gsize body_size;
GVariant *body;
+ gchar *tmp;
guint i;
+ message = g_dbus_message_new ();
+
+ tmp = g_strdup_printf (":1.%"G_GUINT64_FORMAT, (guint64) msg->src_id);
+ g_dbus_message_set_sender (message, tmp);
+ g_free (tmp);
+
body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
body_size = 0;
- KDBUS_ITEM_FOREACH(item, (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv->offset), items)
+ KDBUS_ITEM_FOREACH(item, msg, items)
{
if (item->size <= KDBUS_ITEM_HEADER_SIZE)
g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
@@ -1961,7 +1770,10 @@ g_kdbus_decode_dbus_msg (GKdbus *kdbus,
{
/* KDBUS_ITEM_DST_NAME */
case KDBUS_ITEM_DST_NAME:
- destination = item->str;
+ /* Classic D-Bus doesn't make this known to the receiver, so
+ * we don't do it here either (for compatibility with the
+ * fallback case).
+ */
break;
/* KDBUS_ITEM_PALOAD_OFF */
@@ -1998,8 +1810,7 @@ g_kdbus_decode_dbus_msg (GKdbus *kdbus,
flavour = body_size & 7;
//g_assert ((item->vec.offset & 7) == flavour); FIXME: kdbus bug doesn't count memfd in
flavouring
- vector.gbytes = g_bytes_new (((guchar *) kdbus->priv->kmsg) + item->vec.offset - flavour,
- item->vec.size + flavour);
+ vector.gbytes = g_bytes_new (((guchar *) msg) + item->vec.offset - flavour, item->vec.size +
flavour);
vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
vector.data.pointer += flavour;
vector.size = item->vec.size;
@@ -2025,11 +1836,13 @@ g_kdbus_decode_dbus_msg (GKdbus *kdbus,
/* KDBUS_ITEM_FDS */
case KDBUS_ITEM_FDS:
+ {
+ GUnixFDList *fd_list;
- kdbus->priv->num_fds = data_size / sizeof(int);
- kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
- memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
-
+ fd_list = g_unix_fd_list_new_from_array (item->fds, data_size / sizeof (int));
+ g_dbus_message_set_unix_fd_list (message, fd_list);
+ g_object_unref (fd_list);
+ }
break;
/* All of the following items, like CMDLINE,
@@ -2053,9 +1866,6 @@ g_kdbus_decode_dbus_msg (GKdbus *kdbus,
}
case KDBUS_ITEM_PIDS:
- {
- }
-
case KDBUS_ITEM_PID_COMM:
case KDBUS_ITEM_TID_COMM:
case KDBUS_ITEM_EXE:
@@ -2087,26 +1897,10 @@ g_kdbus_decode_dbus_msg (GKdbus *kdbus,
g_array_free (body_vectors, TRUE);
- g_print ("body is %s\n", g_variant_print (body, TRUE));
-
- /* Override information from the user header with data from the kernel */
-
- if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
- g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
- else
- g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
-
- if (destination)
- g_string_printf (kdbus->priv->msg_destination, "%s", destination);
- else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
- /* for broadcast messages we don't have to set destination */
- ;
- else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
- g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64)
kdbus->priv->unique_id);
- else
- g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64)
kdbus->priv->kmsg->dst_id);
+ g_dbus_message_set_body (message, body);
+ g_variant_unref (body);
- return NULL;
+ return message;
}
@@ -2120,6 +1914,7 @@ _g_kdbus_receive (GKdbus *kdbus,
GError **error)
{
struct kdbus_cmd_recv recv = {};
+ struct kdbus_msg *msg;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return -1;
@@ -2137,12 +1932,12 @@ again:
return -1;
}
- kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
+ msg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
- if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
- g_kdbus_decode_dbus_msg (kdbus, &recv);
- else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
- g_kdbus_decode_kernel_msg (kdbus);
+ if (msg->payload_type == KDBUS_PAYLOAD_DBUS)
+ g_kdbus_decode_dbus_msg (kdbus, msg);
+ else if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
+ g_kdbus_decode_kernel_msg (kdbus, msg);
else
{
g_set_error (error,
@@ -2152,167 +1947,266 @@ again:
return -1;
}
+ ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &recv.offset);
+
return 0;
}
+struct dbus_fixed_header {
+ guint8 endian;
+ guint8 type;
+ guint8 flags;
+ guint8 version;
+ guint32 reserved;
+ guint64 serial;
+};
+
+#define DBUS_FIXED_HEADER_TYPE ((const GVariantType *) "(yyyyut)")
+#define DBUS_EXTENDED_HEADER_TYPE ((const GVariantType *) "a{tv}")
+#define DBUS_MESSAGE_TYPE ((const GVariantType *) "((yyyyut)a{tv}v)")
+
+#define KDBUS_MSG_MAX_SIZE 8192
+
+static gboolean
+g_kdbus_msg_append_item (struct kdbus_msg *msg,
+ gsize type,
+ gconstpointer data,
+ gsize size)
+{
+ struct kdbus_item *item;
+ gsize item_size;
+
+ item_size = size + sizeof (struct kdbus_item);
+
+ if (msg->size + item_size > KDBUS_MSG_MAX_SIZE)
+ return FALSE;
+
+ item = (struct kdbus_item *) ((guchar *) msg) + msg->size;
+ item->type = type;
+ item->size = item_size;
+ memcpy (item->data, data, size);
+
+ msg->size += (item_size + 7) & ~7ull;
+
+ return TRUE;
+}
+
+static gboolean
+g_kdbus_msg_append_payload_vec (struct kdbus_msg *msg,
+ gconstpointer data,
+ gsize size)
+{
+ struct kdbus_vec vec = {
+ .size = size,
+ .address = (gsize) data
+ };
+
+ return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_VEC, &vec, sizeof vec);
+}
+
+static gboolean
+g_kdbus_msg_append_payload_memfd (struct kdbus_msg *msg,
+ gint fd,
+ gsize offset,
+ gsize size)
+{
+ struct kdbus_memfd mfd = {
+ .start = offset,
+ .size = size,
+ .fd = fd,
+ };
+
+ return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_MEMFD, &mfd, sizeof mfd);
+}
+
/**
* _g_kdbus_send:
* Returns: size of data sent or -1 when error
*/
gboolean
-_g_kdbus_send (GDBusWorker *worker,
- GKdbus *kdbus,
- GDBusMessage *dbus_msg,
- GUnixFDList *fd_list,
+_g_kdbus_send (GKdbus *kdbus,
+ GDBusMessage *message,
GCancellable *cancellable,
GError **error)
{
+ struct kdbus_msg *msg = alloca (KDBUS_MSG_MAX_SIZE);
GVariantVectors body_vectors;
- GVariant *body;
- struct kdbus_msg* kmsg;
- struct kdbus_item *item;
- guint64 kmsg_size = 0;
- const gchar *name;
- guint64 dst_id = KDBUS_DST_ID_BROADCAST;
- guint i;
g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
- body = g_dbus_message_get_body (dbus_msg);
- if (body == NULL)
- {
- g_warning ("no body!");
- body = g_variant_new ("()");
- g_variant_ref_sink (body);
- }
- else
- g_variant_ref (body);
- GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
+ /* fill in as we go... */
+ memset (msg, 0, sizeof (struct kdbus_msg));
+ msg->size = sizeof (struct kdbus_msg);
+ msg->payload_type = KDBUS_PAYLOAD_DBUS;
+ msg->src_id = kdbus->priv->unique_id;
+ msg->cookie = g_dbus_message_get_serial(message);
- /*
- * check destination
- */
- if ((name = g_dbus_message_get_destination(dbus_msg)))
- {
- dst_id = KDBUS_DST_ID_NAME;
- if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
- {
- dst_id = strtoull(&name[3], NULL, 10);
- name=NULL;
- }
- }
+ /* Message destination */
+ {
+ const gchar *dst_name;
- /*
- * check and set message size
- */
- kmsg_size = sizeof(struct kdbus_msg);
+ dst_name = g_dbus_message_get_destination (message);
- { G_STATIC_ASSERT (sizeof (struct kdbus_vec) == sizeof (struct kdbus_memfd)); }
- kmsg_size += KDBUS_ITEM_SIZE(sizeof (struct kdbus_vec)) * body_vectors.vectors->len;
+ if (dst_name != NULL)
+ {
+ if (g_dbus_is_unique_name (dst_name))
+ {
+ if (dst_name[1] != '1' || dst_name[2] != '.')
+ {
+ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
+ "Invalid unique D-Bus name '%s'", dst_name);
+ return FALSE;
+ }
- if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
- kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) *
g_unix_fd_list_get_length(fd_list));
+ /* We already know that it passes the checks for unique
+ * names, so no need to perform error checking on strtoull.
+ */
+ msg->dst_id = strtoull (dst_name + 3, NULL, 10);
+ dst_name = NULL;
+ }
+ else
+ {
+ g_kdbus_msg_append_item (msg, KDBUS_ITEM_DST_NAME, dst_name, strlen (dst_name) + 1);
+ msg->dst_id = KDBUS_DST_ID_NAME;
+ }
+ }
+ else
+ msg->dst_id = KDBUS_DST_ID_BROADCAST;
+ }
- if (name)
- kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
- else if (dst_id == KDBUS_DST_ID_BROADCAST)
- kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
- G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
- kdbus->priv->bloom_size);
+ /* File descriptors */
+ {
+ GUnixFDList *fd_list;
- kmsg = malloc(kmsg_size);
- if (!kmsg)
- g_error ("[KDBUS] kmsg malloc error");
+ fd_list = g_dbus_message_get_unix_fd_list (message);
+ if (fd_list != NULL)
+ {
+ const gint *fds;
+ gint n_fds;
- /*
- * set message header
- */
- memset(kmsg, 0, kmsg_size);
- kmsg->size = kmsg_size;
- kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
- kmsg->dst_id = name ? 0 : dst_id;
- kmsg->src_id = kdbus->priv->unique_id;
- kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
- kmsg->priority = 0;
+ fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
+ if (n_fds)
+ g_kdbus_msg_append_item (msg, KDBUS_ITEM_FDS, fds, sizeof (gint) * n_fds);
+ }
+ }
+
+ /* Message body */
+ {
+ struct dbus_fixed_header fh;
+ GHashTableIter header_iter;
+ GVariantBuilder builder;
+ gpointer key, value;
+ GVariant *parts[3];
+ GVariant *body;
+
+ fh.endian = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'l': 'B';
+ fh.type = g_dbus_message_get_message_type (message);
+ fh.flags = g_dbus_message_get_flags (message);
+ fh.version = 2;
+ fh.reserved = 0;
+ fh.serial = g_dbus_message_get_serial (message);
+ parts[0] = g_variant_new_from_data (DBUS_FIXED_HEADER_TYPE, &fh, sizeof fh, TRUE, NULL, NULL);
+
+ g_dbus_message_init_header_iter (message, &header_iter);
+ g_variant_builder_init (&builder, DBUS_EXTENDED_HEADER_TYPE);
+ while (g_hash_table_iter_next (&header_iter, &key, &value))
+ {
+ guint64 key_int = (gsize) key;
- /*
- * set message flags
- */
- kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 :
KDBUS_MSG_FLAGS_EXPECT_REPLY) |
- ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ?
KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
+ /* We don't send these in GVariant format */
+ if (key_int == G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE ||
+ key_int == G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS)
+ continue;
- if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
- kmsg->timeout_ns = 2000000000;
- else
- kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
+ g_variant_builder_add (&builder, "{tv}", key_int, value);
+ }
+ parts[1] = g_variant_builder_end (&builder);
+ body = g_dbus_message_get_body (message);
+ if (!body)
+ body = g_variant_new ("()");
+ parts[2] = g_variant_new_variant (body);
- /*
- * append payload
- */
- item = kmsg->items;
- for (i = 0; i < body_vectors.vectors->len; i++)
- {
- GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
+ body = g_variant_ref_sink (g_variant_new_tuple (parts, G_N_ELEMENTS (parts)));
+ GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
+ g_variant_unref (body);
+ }
- if (vector.gbytes)
- {
- gint fd;
+ {
+ guint i;
- fd = g_bytes_get_zero_copy_fd (vector.gbytes);
+ for (i = 0; i < body_vectors.vectors->len; i++)
+ {
+ GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
- if (fd >= 0)
- {
- gconstpointer bytes_data;
- gsize bytes_size;
+ if (vector.gbytes)
+ {
+ gint fd;
- bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
+ fd = g_bytes_get_zero_copy_fd (vector.gbytes);
- if (bytes_data == vector.data.pointer && bytes_size == vector.size)
- g_kdbus_append_payload_memfd (&item, fd, vector.size);
- else
- g_kdbus_append_payload_vec (&item, vector.data.pointer, vector.size);
- }
- else
- g_kdbus_append_payload_vec (&item, vector.data.pointer, vector.size);
- }
- else
- g_kdbus_append_payload_vec (&item, body_vectors.extra_bytes->data + vector.data.offset, vector.size);
- }
+ if (fd >= 0)
+ {
+ const guchar *bytes_data;
+ gsize bytes_size;
+
+ bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
+
+ if (bytes_data <= vector.data.pointer && vector.data.pointer + vector.size <= bytes_data +
bytes_size)
+ {
+ if (!g_kdbus_msg_append_payload_memfd (msg, fd, vector.data.pointer - bytes_data,
vector.size))
+ goto need_compact;
+ }
+ else
+ {
+ if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
+ goto need_compact;
+ }
+ }
+ else
+ {
+ if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
+ goto need_compact;
+ }
+ }
+ else
+ if (!g_kdbus_msg_append_payload_vec (msg, body_vectors.extra_bytes->data + vector.data.offset,
vector.size))
+ goto need_compact;
+ }
+ }
- /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
+ /*
+ * set message flags
+ */
+ msg->flags = ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 :
KDBUS_MSG_FLAGS_EXPECT_REPLY) |
+ ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ?
KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
+
+ if ((msg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
+ msg->timeout_ns = 2000000000;
+ else
+ msg->cookie_reply = g_dbus_message_get_reply_serial(message);
/*
- * append destination or bloom filters
- */
- if (name)
- g_kdbus_append_destination (&item, name, strlen(name));
- else if (dst_id == KDBUS_DST_ID_BROADCAST)
+ if (dst_id == KDBUS_DST_ID_BROADCAST)
{
struct kdbus_bloom_filter *bloom_filter;
bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
- g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
+ g_kdbus_setup_bloom (kdbus, message, bloom_filter);
}
-
- /*
- * append fds if any
- */
- if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
- g_kdbus_append_fds (&item, fd_list);
-
+ */
/*
* send message
*/
//again:
- if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
+ if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, msg))
{
/*
GString *error_name;
@@ -2365,7 +2259,15 @@ _g_kdbus_send (GDBusWorker *worker,
return FALSE;
}
- free(kmsg);
-
return TRUE;
+
+need_compact:
+ /* We end up here if:
+ * - too many kdbus_items
+ * - too large kdbus_msg size
+ * - too much vector data
+ *
+ * We need to compact the message before sending it.
+ */
+ g_assert_not_reached ();
}
diff --git a/gio/gkdbus.h b/gio/gkdbus.h
index d8c8df1..43563b2 100644
--- a/gio/gkdbus.h
+++ b/gio/gkdbus.h
@@ -121,10 +121,8 @@ void _g_kdbus_unsubscribe_name_acquired (GDB
void _g_kdbus_unsubscribe_name_lost (GDBusConnection *connection);
-gboolean _g_kdbus_send (GDBusWorker *worker,
- GKdbus *kdbus,
+gboolean _g_kdbus_send (GKdbus *kdbus,
GDBusMessage *dbus_msg,
- GUnixFDList *fd_list,
GCancellable *cancellable,
GError **error);
diff --git a/gio/gunixfdlist.h b/gio/gunixfdlist.h
index 6b1c383..cbedc95 100644
--- a/gio/gunixfdlist.h
+++ b/gio/gunixfdlist.h
@@ -68,6 +68,9 @@ GLIB_AVAILABLE_IN_ALL
GUnixFDList * g_unix_fd_list_new_from_array (const gint *fds,
gint n_fds);
+GLIB_AVAILABLE_IN_2_44
+void g_unix_fd_list_lock (GUnixFDList *list);
+
GLIB_AVAILABLE_IN_ALL
gint g_unix_fd_list_append (GUnixFDList *list,
gint fd,
diff --git a/gio/kdbus.h b/gio/kdbus.h
index 7137fc9..b0e9203 100644
--- a/gio/kdbus.h
+++ b/gio/kdbus.h
@@ -183,7 +183,8 @@ struct kdbus_bloom_filter {
/**
* struct kdbus_memfd - a kdbus memfd
- * @size: The memfd's size
+ * @start: The offset into the memfd where the segment starts
+ * @size: The size of the memfd segment
* @fd: The file descriptor number
* @__pad: Padding to ensure proper alignment and size
*
@@ -191,6 +192,7 @@ struct kdbus_bloom_filter {
* KDBUS_ITEM_PAYLOAD_MEMFD
*/
struct kdbus_memfd {
+ __u64 start;
__u64 size;
int fd;
__u32 __pad;
@@ -583,12 +585,15 @@ enum kdbus_policy_type {
* a service
* @KDBUS_HELLO_MONITOR: Special-purpose connection to monitor
* bus traffic
+ * @KDBUS_HELLO_UNPRIVILEGED: Don't treat this connection as privileged once
+ * the bus connection was established.
*/
enum kdbus_hello_flags {
KDBUS_HELLO_ACCEPT_FD = 1ULL << 0,
KDBUS_HELLO_ACTIVATOR = 1ULL << 1,
KDBUS_HELLO_POLICY_HOLDER = 1ULL << 2,
KDBUS_HELLO_MONITOR = 1ULL << 3,
+ KDBUS_HELLO_UNPRIVILEGED = 1ULL << 4,
};
/**
@@ -768,6 +773,7 @@ enum kdbus_name_list_flags {
* @offset: The returned offset in the caller's pool buffer.
* The user must use KDBUS_CMD_FREE to free the
* allocated memory.
+ * @size: Output buffer to report size of data at @offset.
*
* This structure is used with the KDBUS_CMD_NAME_LIST ioctl.
*/
@@ -775,6 +781,7 @@ struct kdbus_cmd_name_list {
__u64 flags;
__u64 kernel_flags;
__u64 offset;
+ __u64 size;
} __attribute__((aligned(8)));
/**
@@ -801,6 +808,7 @@ struct kdbus_name_list {
* @offset: Returned offset in the caller's pool buffer where the
* kdbus_info struct result is stored. The user must
* use KDBUS_CMD_FREE to free the allocated memory.
+ * @info_size: Output buffer to report size of data at @offset.
* @items: The optional item list, containing the
* well-known name to look up as a KDBUS_ITEM_NAME.
* Only needed in case @id is zero.
@@ -815,6 +823,7 @@ struct kdbus_cmd_info {
__u64 kernel_flags;
__u64 id;
__u64 offset;
+ __u64 info_size;
struct kdbus_item items[0];
} __attribute__((aligned(8)));
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index 55409c3..44f570b 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -731,6 +731,7 @@ g_variant_vector_deserialise (GVariantTypeInfo *type_info,
if (unpacked->size == 0)
{
children[i] = g_variant_new_serialised (unpacked->type_info, g_bytes_new (NULL, 0), NULL, 0,
trusted);
+ g_variant_ref_sink (children[i]);
continue;
}
@@ -765,7 +766,10 @@ g_variant_vector_deserialise (GVariantTypeInfo *type_info,
vector->data.pointer = resume_at_data;
vector->size = resume_at_size;
- failed |= children[i] == NULL;
+ if (children[i])
+ g_variant_ref_sink (children[i]);
+ else
+ failed = TRUE;
}
/* We consumed all the type infos */
@@ -813,6 +817,7 @@ g_variant_from_vectors (const GVariantType *type,
tmp = g_array_new (FALSE, FALSE, sizeof (GVariantUnpacked));
result = g_variant_vector_deserialise (g_variant_type_info_get (type),
vectors, vectors + n_vectors - 1, size, trusted, tmp);
+ g_variant_ref_sink (result);
g_array_free (tmp, TRUE);
return result;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]