1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2013 Samsung Electronics
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Michal Eljasiewicz <m.eljasiewic@samsung.com>
21 * Author: Lukasz Skalski <l.skalski@samsung.com>
27 #include "glib-unix.h"
34 #ifdef HAVE_SYS_FILIO_H
35 # include <sys/filio.h>
42 #include <glib/gstdio.h>
44 #include <gio/gunixfdlist.h>
47 #include "gunixfdmessage.h"
48 #include "gdbusprivate.h"
54 * @short_description: Low-level kdbus object
57 * A #GKdbus is a lowlevel adapter for kdbus IPC solution. It is meant
58 * to replace DBUS as fundamental IPC solution for Linux, however it
59 * is still experimental work in progress. You may find detailed
60 * description in kdbus.txt at https://github.com/gregkh/kdbus
65 /* Size of memory registered with kdbus for receiving messages */
66 #define KDBUS_POOL_SIZE (16 * 1024 * 1024)
68 #define ALIGN8(l) (((l) + 7) & ~7)
69 #define ALIGN8_PTR(p) ((void*) ALIGN8((gulong) p))
71 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
72 #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
74 #define KDBUS_ITEM_NEXT(item) \
75 (typeof(item))(((guint8 *)item) + ALIGN8((item)->size))
77 #define KDBUS_ITEM_FOREACH(item, head, first) \
78 for (item = (head)->first; \
79 ((guint8 *)(item) < (guint8 *)(head) + (head)->size) && \
80 ((guint8 *)(item) >= (guint8 *)(head)); \
81 item = KDBUS_ITEM_NEXT(item))
83 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
86 * use systemd-bus-drvierd (from systemd) which implements the all
87 * org.freedesktop.DBus methods on kdbus
90 #define SYSTEMD_BUS_DRIVERD
93 /* GBusNameOwnerReturnFlags */
96 G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1, /* Caller is now the primary owner of the name, replacing any previous owner */
97 G_BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2, /* The name already had an owner, the application will be placed in a queue */
98 G_BUS_REQUEST_NAME_REPLY_EXISTS = 3, /* The name already has an owner */
99 G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4 /* The application trying to request ownership of a name is already the owner of it */
100 } GBusNameOwnerReturnFlags;
103 /* GBusReleaseNameReturnFlags */
106 G_BUS_RELEASE_NAME_REPLY_RELEASED = 1, /* The caller has released his claim on the given name */
107 G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT = 2, /* The given name does not exist on this bus*/
108 G_BUS_RELEASE_NAME_REPLY_NOT_OWNER = 3 /* The caller not waiting in the queue to own this name*/
109 } GBusReleaseNameReturnFlags;
112 /* GBusStartServiceReturnFlags */
115 G_BUS_START_REPLY_SUCCESS = 1, /* The service was successfully started */
116 G_BUS_START_REPLY_ALREADY_RUNNING = 2, /* A connection already owns the given name */
117 } GBusStartServiceReturnFlags;
120 /* GBusCredentialsFlags */
125 G_BUS_CREDS_UNIQUE_NAME = 3,
126 G_BUS_CREDS_SELINUX_CONTEXT = 4
127 } GBusCredentialsFlags;
130 static void g_kdbus_initable_iface_init (GInitableIface *iface);
131 static gboolean g_kdbus_initable_init (GInitable *initable,
132 GCancellable *cancellable,
135 #define g_kdbus_get_type _g_kdbus_get_type
136 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
137 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
138 g_kdbus_initable_iface_init));
141 struct _GKdbusPrivate
146 GSList *kdbus_msg_items;
149 guint64 attach_flags;
155 struct kdbus_msg *kmsg;
157 GString *msg_destination;
173 GIOCondition condition;
174 GCancellable *cancellable;
175 GPollFD cancel_pollfd;
180 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
181 GIOCondition condition,
185 /* Hash keys for bloom filters*/
186 const guint8 hash_keys[8][16] =
188 {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
189 {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
190 {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
191 {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
192 {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
193 {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
194 {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
195 {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
200 * _g_kdbus_get_last_msg_sender
204 _g_kdbus_get_last_msg_sender (GKdbus *kdbus)
206 return kdbus->priv->msg_sender->str;
211 * _g_kdbus_get_last_msg_destination
215 _g_kdbus_get_last_msg_destination (GKdbus *kdbus)
217 return kdbus->priv->msg_destination->str;
222 * _g_kdbus_get_last_msg_items:
226 _g_kdbus_get_last_msg_items (GKdbus *kdbus)
228 return kdbus->priv->kdbus_msg_items;
233 * g_kdbus_add_msg_part:
237 g_kdbus_add_msg_part (GKdbus *kdbus,
241 msg_part* part = g_new (msg_part, 1);
244 kdbus->priv->kdbus_msg_items = g_slist_append(kdbus->priv->kdbus_msg_items, part);
249 * _g_kdbus_hexdump_all_items:
253 _g_kdbus_hexdump_all_items (GSList *kdbus_msg_items)
258 ret = g_string_new (NULL);
260 while (kdbus_msg_items != NULL)
262 g_string_append_printf (ret, "\n Item %d\n", item);
263 g_string_append (ret, _g_dbus_hexdump (((msg_part*)kdbus_msg_items->data)->data, ((msg_part*)kdbus_msg_items->data)->size, 2));
265 kdbus_msg_items = g_slist_next(kdbus_msg_items);
269 return g_string_free (ret, FALSE);
278 g_kdbus_finalize (GObject *object)
280 GKdbus *kdbus = G_KDBUS (object);
282 if (kdbus->priv->kdbus_buffer != NULL)
283 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
285 kdbus->priv->kdbus_buffer = NULL;
287 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
288 _g_kdbus_close (kdbus, NULL);
290 g_string_free (kdbus->priv->msg_sender, TRUE);
291 g_string_free (kdbus->priv->msg_destination, TRUE);
293 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
294 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
299 * g_kdbus_class_init:
303 g_kdbus_class_init (GKdbusClass *klass)
305 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
307 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
308 gobject_class->finalize = g_kdbus_finalize;
313 * g_kdbus_initable_iface_init:
317 g_kdbus_initable_iface_init (GInitableIface *iface)
319 iface->init = g_kdbus_initable_init;
328 g_kdbus_init (GKdbus *kdbus)
330 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
332 kdbus->priv->fd = -1;
333 kdbus->priv->unique_id = -1;
334 kdbus->priv->memfd = -1;
336 kdbus->priv->path = NULL;
337 kdbus->priv->kdbus_buffer = NULL;
338 kdbus->priv->kdbus_msg_items = NULL;
340 kdbus->priv->msg_sender = g_string_new (NULL);
341 kdbus->priv->msg_destination = g_string_new (NULL);
343 kdbus->priv->fds = NULL;
344 kdbus->priv->num_fds = 0;
346 kdbus->priv->hello_flags = KDBUS_HELLO_ACCEPT_FD;
347 kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
352 * g_kdbus_initable_init:
356 g_kdbus_initable_init (GInitable *initable,
357 GCancellable *cancellable,
362 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
364 kdbus = G_KDBUS (initable);
366 if (cancellable != NULL)
368 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
369 _("Cancellable initialization not supported"));
373 kdbus->priv->inited = TRUE;
380 * kdbus_source_prepare:
384 kdbus_source_prepare (GSource *source,
387 GKdbusSource *kdbus_source = (GKdbusSource *)source;
389 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
392 if (kdbus_source->timeout_time)
396 now = g_source_get_time (source);
398 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
401 kdbus_source->kdbus->priv->timed_out = TRUE;
409 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
417 * kdbus_source_check:
421 kdbus_source_check (GSource *source)
425 return kdbus_source_prepare (source, &timeout);
430 * kdbus_source_dispatch
434 kdbus_source_dispatch (GSource *source,
435 GSourceFunc callback,
438 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
439 GKdbusSource *kdbus_source = (GKdbusSource *)source;
440 GKdbus *kdbus = kdbus_source->kdbus;
443 if (kdbus_source->kdbus->priv->timed_out)
444 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
446 ret = (*func) (kdbus,
447 kdbus_source->pollfd.revents & kdbus_source->condition,
450 if (kdbus->priv->timeout)
451 kdbus_source->timeout_time = g_get_monotonic_time ()
452 + kdbus->priv->timeout * 1000000;
455 kdbus_source->timeout_time = 0;
462 * kdbus_source_finalize
466 kdbus_source_finalize (GSource *source)
468 GKdbusSource *kdbus_source = (GKdbusSource *)source;
471 kdbus = kdbus_source->kdbus;
473 g_object_unref (kdbus);
475 if (kdbus_source->cancellable)
477 g_cancellable_release_fd (kdbus_source->cancellable);
478 g_object_unref (kdbus_source->cancellable);
484 * kdbus_source_closure_callback:
488 kdbus_source_closure_callback (GKdbus *kdbus,
489 GIOCondition condition,
492 GClosure *closure = data;
493 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
494 GValue result_value = G_VALUE_INIT;
497 g_value_init (&result_value, G_TYPE_BOOLEAN);
499 g_value_init (¶ms[0], G_TYPE_KDBUS);
500 g_value_set_object (¶ms[0], kdbus);
501 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
502 g_value_set_flags (¶ms[1], condition);
504 g_closure_invoke (closure, &result_value, 2, params, NULL);
506 result = g_value_get_boolean (&result_value);
507 g_value_unset (&result_value);
508 g_value_unset (¶ms[0]);
509 g_value_unset (¶ms[1]);
515 static GSourceFuncs kdbus_source_funcs =
517 kdbus_source_prepare,
519 kdbus_source_dispatch,
520 kdbus_source_finalize,
521 (GSourceFunc)kdbus_source_closure_callback,
530 kdbus_source_new (GKdbus *kdbus,
531 GIOCondition condition,
532 GCancellable *cancellable)
535 GKdbusSource *kdbus_source;
537 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
538 g_source_set_name (source, "GKdbus");
539 kdbus_source = (GKdbusSource *)source;
541 kdbus_source->kdbus = g_object_ref (kdbus);
542 kdbus_source->condition = condition;
544 if (g_cancellable_make_pollfd (cancellable,
545 &kdbus_source->cancel_pollfd))
547 kdbus_source->cancellable = g_object_ref (cancellable);
548 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
551 kdbus_source->pollfd.fd = kdbus->priv->fd;
552 kdbus_source->pollfd.events = condition;
553 kdbus_source->pollfd.revents = 0;
554 g_source_add_poll (source, &kdbus_source->pollfd);
556 if (kdbus->priv->timeout)
557 kdbus_source->timeout_time = g_get_monotonic_time ()
558 + kdbus->priv->timeout * 1000000;
560 kdbus_source->timeout_time = 0;
567 * _g_kdbus_create_source:
571 _g_kdbus_create_source (GKdbus *kdbus,
572 GIOCondition condition,
573 GCancellable *cancellable)
575 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
577 return kdbus_source_new (kdbus, condition, cancellable);
584 * @address: path to kdbus bus file.
585 * @error: #GError for error reporting, or %NULL to ignore.
587 * Opens file descriptor to kdbus bus control.
588 * It is located in /dev/kdbus/uid-name/bus.
590 * Returns: TRUE on success.
593 _g_kdbus_open (GKdbus *kdbus,
594 const gchar *address,
597 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
599 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
601 if (kdbus->priv->fd<0)
603 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
607 kdbus->priv->closed = FALSE;
616 * @error: #GError for error reporting, or %NULL to ignore.
618 * Closes file descriptor to kdbus bus.
619 * Disconnect a connection. If the connection's message list is empty,
620 * the calls succeeds, closes file descriptor to kdbus bus. Otherwise
621 * FALSE is returned without any further side-effects.
623 * Returns: TRUE on success.
627 _g_kdbus_close (GKdbus *kdbus,
632 if (kdbus->priv->closed)
633 return TRUE; /* Multiple close not an error */
635 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
637 if (ioctl(kdbus->priv->fd, KDBUS_CMD_BYEBYE) < 0)
642 res = close (kdbus->priv->fd);
649 g_set_error (error, G_IO_ERROR,
650 g_io_error_from_errno (errno),
651 _("Error closing kdbus fd: %s"),
658 kdbus->priv->closed = TRUE;
659 kdbus->priv->fd = -1;
666 * _g_kdbus_is_closed:
669 * checks whether a kdbus is closed.
673 _g_kdbus_is_closed (GKdbus *kdbus)
675 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
677 return kdbus->priv->closed;
682 * g_kdbus_generate_local_reply:
685 static GDBusMessage *
686 g_kdbus_generate_local_reply (GDBusMessage *message,
687 GDBusMessageType message_type,
688 GDBusMessageFlags message_flags,
689 guint32 message_reply_serial,
690 GVariant *message_body,
691 const gchar *error_name)
695 reply = g_dbus_message_new ();
697 g_dbus_message_set_sender (reply, "org.freedesktop.DBus");
698 g_dbus_message_set_message_type (reply, message_type);
699 g_dbus_message_set_flags (reply, message_flags);
700 g_dbus_message_set_reply_serial (reply, message_reply_serial);
702 g_dbus_message_set_body (reply, message_body);
705 g_dbus_message_set_destination (reply, g_dbus_message_get_sender (message));
707 if (message_type == G_DBUS_MESSAGE_TYPE_ERROR)
708 g_dbus_message_set_error_name (reply, error_name);
710 if (G_UNLIKELY (_g_dbus_debug_message ()))
713 _g_dbus_debug_print_lock ();
714 g_print ("========================================================================\n"
715 "GDBus-debug:Message:\n"
716 " <<<< RECEIVED LOCAL D-Bus message (N/A bytes)\n");
718 s = g_dbus_message_print (reply, 2);
721 _g_dbus_debug_print_unlock ();
729 * g_kdbus_generate_local_error:
733 g_kdbus_generate_local_error (GDBusWorker *worker,
734 GDBusMessage *dbus_msg,
735 GVariant *message_body,
739 GError *error = NULL;
740 gchar *dbus_error_name;
742 error = g_error_new_literal (G_DBUS_ERROR, error_code, "");
743 dbus_error_name = g_dbus_error_encode_gerror (error);
745 reply = g_kdbus_generate_local_reply (dbus_msg,
746 G_DBUS_MESSAGE_TYPE_ERROR,
747 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
748 g_dbus_message_get_serial (dbus_msg),
751 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
756 * g_kdbus_check_signature:
757 * Returns: TRUE on success.
760 g_kdbus_check_signature (GDBusWorker *worker,
761 GDBusMessage *dbus_msg,
762 const gchar *method_name,
764 const GVariantType *type)
767 if (!g_variant_is_of_type (body, type))
769 GString *error_name = g_string_new (NULL);
770 g_string_printf (error_name, "Call to %s has wrong args (expected %s)", method_name, g_variant_type_peek_string (type));
771 g_kdbus_generate_local_error (worker,
773 g_variant_new ("(s)",error_name->str),
774 G_DBUS_ERROR_INVALID_ARGS);
775 g_string_free (error_name,TRUE);
784 * g_kdbus_check_name:
785 * Returns: TRUE on success.
788 g_kdbus_check_name (GDBusWorker *worker,
789 GDBusMessage *dbus_msg,
792 if (!g_dbus_is_name (name))
794 GString *error_name = g_string_new (NULL);
795 g_string_printf (error_name, "Name \"%s\" is not valid", name);
796 g_kdbus_generate_local_error (worker,
798 g_variant_new ("(s)",error_name->str),
799 G_DBUS_ERROR_INVALID_ARGS);
800 g_string_free (error_name,TRUE);
809 * g_kdbus_translate_request_name_flags:
813 g_kdbus_translate_request_name_flags (GBusNameOwnerFlags flags,
814 guint64 *kdbus_flags)
816 guint64 new_flags = 0;
818 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
819 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
821 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
822 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
824 *kdbus_flags = new_flags;
829 * g_kdbus_NameHasOwner:
830 * Returns: TRUE on success.
833 g_kdbus_NameHasOwner (GKdbus *kdbus, const gchar *name)
835 struct kdbus_cmd_conn_info *cmd;
839 if (g_dbus_is_unique_name(name))
841 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name);
842 cmd = g_alloca0 (size);
843 cmd->id = g_ascii_strtoull (name+3,NULL,10);
847 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
848 cmd = g_alloca0 (size);
849 strcpy(cmd->name, name);
852 cmd->flags = KDBUS_ATTACH_NAMES;
855 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
869 g_kdbus_take_fd (GKdbus *kdbus)
871 struct kdbus_cmd_hello *hello;
872 struct kdbus_item *item;
874 size_t size, conn_name_size;
876 conn_name = "gdbus-kdbus";
877 conn_name_size = strlen (conn_name);
879 size = ALIGN8(G_STRUCT_OFFSET(struct kdbus_cmd_hello, items)) +
880 ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, str) + conn_name_size + 1);
882 hello = g_alloca0(size);
883 hello->conn_flags = kdbus->priv->hello_flags;
884 hello->attach_flags = kdbus->priv->attach_flags;
886 hello->pool_size = KDBUS_POOL_SIZE;
888 /* connection's human-readable name (only for debugging purposes)*/
890 item->size = G_STRUCT_OFFSET(struct kdbus_item, str) + conn_name_size + 1;
891 item->type = KDBUS_ITEM_CONN_NAME;
892 memcpy(item->str, conn_name, conn_name_size+1);
893 item = KDBUS_ITEM_NEXT(item);
895 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
896 g_error("[KDBUS] fd=%d failed to send hello: %m, %d", kdbus->priv->fd,errno);
898 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
900 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
901 g_error("[KDBUS] error when mmap: %m, %d", errno);
903 if (hello->bus_flags > 0xFFFFFFFFULL || hello->conn_flags > 0xFFFFFFFFULL)
904 g_error("[KDBUS] incompatible flags");
906 /* read bloom filters parameters */
907 kdbus->priv->bloom_size = (gsize) hello->bloom.size;
908 kdbus->priv->bloom_n_hash = (guint) hello->bloom.n_hash;
910 /* validate bloom filters parameters here? */
912 kdbus->priv->unique_id = hello->id;
913 memcpy (kdbus->priv->bus_id, hello->id128, 16);
918 * g_kdbus_Hello_reply:
919 * Returns: TRUE on success.
922 g_kdbus_Hello_reply (GDBusWorker *worker,
924 GDBusMessage *dbus_msg)
926 GString *unique_name;
929 unique_name = g_string_new(NULL);
930 g_string_printf (unique_name,":1.%" G_GUINT64_FORMAT, kdbus->priv->unique_id);
932 reply = g_kdbus_generate_local_reply (dbus_msg,
933 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
934 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
935 g_dbus_message_get_serial (dbus_msg),
936 g_variant_new ("(s)",unique_name->str),
938 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
940 g_string_free (unique_name,TRUE);
946 * g_kdbus_RequestName_handler:
947 * Returns: TRUE on success.
950 g_kdbus_RequestName_handler (GDBusWorker *worker,
952 GDBusMessage *dbus_msg)
955 GBusNameOwnerFlags flags;
956 struct kdbus_cmd_name *kdbus_name;
961 gint status = G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
963 /* read and validate message */
964 GVariant *body = g_dbus_message_get_body (dbus_msg);
966 if (!g_kdbus_check_signature (worker, dbus_msg, "RequestName", body, G_VARIANT_TYPE("(su)")))
969 g_variant_get (body, "(&su)", &name, &flags);
971 if (!g_kdbus_check_name (worker, dbus_msg, name))
976 GString *error_name = g_string_new (NULL);
977 g_string_printf (error_name, "Cannot acquire a service starting with ':' such as \"%s\"", name);
978 g_kdbus_generate_local_error (worker,
980 g_variant_new ("(s)",error_name->str),
981 G_DBUS_ERROR_INVALID_ARGS);
982 g_string_free (error_name,TRUE);
986 g_kdbus_translate_request_name_flags (flags, &kdbus_flags);
989 size = sizeof(*kdbus_name) + strlen(name) + 1;
990 kdbus_name = g_alloca(size);
992 /* set message header */
993 memset(kdbus_name, 0, size);
994 strcpy(kdbus_name->name, name);
995 kdbus_name->size = size;
996 kdbus_name->flags = kdbus_flags;
999 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
1002 if (errno == EEXIST)
1003 status = G_BUS_REQUEST_NAME_REPLY_EXISTS;
1004 else if (errno == EALREADY)
1005 status = G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
1010 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
1011 status = G_BUS_REQUEST_NAME_REPLY_IN_QUEUE;
1013 /* generate local reply */
1014 reply = g_kdbus_generate_local_reply (dbus_msg,
1015 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1016 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1017 g_dbus_message_get_serial (dbus_msg),
1018 g_variant_new ("(u)",status),
1020 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1027 * g_kdbus_ReleaseName_handler:
1028 * Returns: TRUE on success.
1031 g_kdbus_ReleaseName_handler (GDBusWorker *worker,
1033 GDBusMessage *dbus_msg)
1035 GDBusMessage *reply;
1036 struct kdbus_cmd_name *kdbus_name;
1040 gint status = G_BUS_RELEASE_NAME_REPLY_RELEASED;
1042 /* read and validate message */
1043 GVariant *body = g_dbus_message_get_body (dbus_msg);
1045 if (!g_kdbus_check_signature (worker, dbus_msg, "ReleaseName", body, G_VARIANT_TYPE("(s)")))
1048 g_variant_get (body, "(&s)", &name);
1050 if (!g_kdbus_check_name (worker, dbus_msg, name))
1055 GString *error_name = g_string_new (NULL);
1056 g_string_printf (error_name, "Cannot release a service starting with ':' such as \"%s\"", name);
1057 g_kdbus_generate_local_error (worker,
1059 g_variant_new ("(s)",error_name->str),
1060 G_DBUS_ERROR_INVALID_ARGS);
1061 g_string_free (error_name,TRUE);
1065 /* calculate size */
1066 size = sizeof(*kdbus_name) + strlen(name) + 1;
1067 kdbus_name = g_alloca(size);
1069 /* set message header */
1070 memset(kdbus_name, 0, size);
1071 strcpy(kdbus_name->name, name);
1072 kdbus_name->size = size;
1075 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
1079 status = G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT;
1080 else if (errno == EADDRINUSE)
1081 status = G_BUS_RELEASE_NAME_REPLY_NOT_OWNER;
1086 /* generate local reply */
1087 reply = g_kdbus_generate_local_reply (dbus_msg,
1088 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1089 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1090 g_dbus_message_get_serial (dbus_msg),
1091 g_variant_new ("(u)",status),
1093 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1100 * g_kdbus_ListNames_handler:
1101 * Returns: TRUE on success.
1104 g_kdbus_ListNames_handler (GDBusWorker *worker,
1106 GDBusMessage *dbus_msg,
1109 GDBusMessage *reply;
1110 GVariantBuilder *builder;
1111 struct kdbus_cmd_name_list cmd = {};
1112 struct kdbus_name_list *name_list;
1113 struct kdbus_cmd_name *name;
1114 guint64 prev_id = 0;
1119 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1124 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1126 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1127 KDBUS_ITEM_FOREACH(name, name_list, names)
1129 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
1131 GString *unique_name = g_string_new (NULL);
1133 g_string_printf (unique_name, ":1.%llu", name->owner_id);
1135 g_variant_builder_add (builder, "s", unique_name->str);
1136 g_string_free (unique_name,TRUE);
1137 prev_id = name->owner_id;
1140 if (g_dbus_is_name (name->name))
1141 g_variant_builder_add (builder, "s", name->name);
1144 /* generate local reply */
1145 reply = g_kdbus_generate_local_reply (dbus_msg,
1146 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1147 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1148 g_dbus_message_get_serial (dbus_msg),
1149 g_variant_new ("(as)", builder),
1151 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1153 g_variant_builder_unref (builder);
1154 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd.offset);
1163 * g_kdbus_ListQueuedOwners_handler:
1164 * Returns: TRUE on success.
1167 g_kdbus_ListQueuedOwners_handler (GDBusWorker *worker,
1169 GDBusMessage *dbus_msg)
1171 GDBusMessage *reply;
1172 GString *unique_name;
1173 GVariantBuilder *builder;
1174 struct kdbus_cmd_name_list cmd = {};
1175 struct kdbus_name_list *name_list;
1176 struct kdbus_cmd_name *name;
1177 const gchar *service;
1180 /* read and validate message */
1181 GVariant *body = g_dbus_message_get_body (dbus_msg);
1183 if (!g_kdbus_check_signature (worker, dbus_msg, "ListQueuedOwners", body, G_VARIANT_TYPE("(s)")))
1186 g_variant_get (body, "(&s)", &service);
1188 if (!g_kdbus_check_name (worker, dbus_msg, service))
1191 if (!g_kdbus_NameHasOwner (kdbus, service))
1193 GString *error_name = g_string_new (NULL);
1194 g_string_printf (error_name, "Could not get owners of name \'%s\': no such name", service);
1195 g_kdbus_generate_local_error (worker,
1197 g_variant_new ("(s)",error_name->str),
1198 G_DBUS_ERROR_NAME_HAS_NO_OWNER);
1199 g_string_free (error_name,TRUE);
1203 /* get queued name list */
1204 cmd.flags = KDBUS_NAME_LIST_QUEUED;
1206 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1210 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1212 unique_name = g_string_new (NULL);
1213 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1214 KDBUS_ITEM_FOREACH(name, name_list, names)
1216 if (name->size <= sizeof(*name))
1219 if (strcmp(name->name, service))
1222 g_string_printf (unique_name, ":1.%llu", name->owner_id);
1223 g_variant_builder_add (builder, "s", unique_name);
1227 /* generate reply */
1228 reply = g_kdbus_generate_local_reply (dbus_msg,
1229 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1230 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1231 g_dbus_message_get_serial (dbus_msg),
1232 g_variant_new ("(as)", builder),
1234 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1236 g_variant_builder_unref (builder);
1237 g_string_free (unique_name,TRUE);
1239 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd.offset);
1248 * g_kdbus_GetOwner_handler:
1249 * Returns: TRUE on success.
1252 g_kdbus_GetOwner_handler (GDBusWorker *worker,
1254 GDBusMessage *dbus_msg,
1257 GVariant *result = NULL;
1258 GDBusMessage *reply;
1259 struct kdbus_cmd_conn_info *cmd;
1260 struct kdbus_conn_info *conn_info;
1261 struct kdbus_item *item;
1266 /* read and validate message */
1267 GVariant *body = g_dbus_message_get_body (dbus_msg);
1269 if (!g_kdbus_check_signature (worker, dbus_msg, "GetOwner", body, G_VARIANT_TYPE("(s)")))
1272 g_variant_get (body, "(&s)", &name);
1274 if (!g_kdbus_check_name (worker, dbus_msg, name))
1277 /* setup kmsg for ioctl */
1278 if (g_dbus_is_unique_name(name))
1280 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name);
1281 cmd = g_alloca0 (size);
1282 cmd->id = g_ascii_strtoull (name+3,NULL,10);
1286 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
1287 cmd = g_alloca0 (size);
1288 strcpy(cmd->name, name);
1291 cmd->flags = KDBUS_ATTACH_NAMES;
1294 /* get info about connection */
1295 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1298 GString *error_name = g_string_new (NULL);
1299 g_string_printf (error_name, "Could not get owners of name \'%s\': no such name", name);
1300 g_kdbus_generate_local_error (worker,
1302 g_variant_new ("(s)",error_name->str),
1303 G_DBUS_ERROR_NAME_HAS_NO_OWNER);
1304 g_string_free (error_name, TRUE);
1308 conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1310 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1313 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1315 GString *unique_name = g_string_new (NULL);
1317 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1319 result = g_variant_new ("(s)", unique_name);
1320 g_string_free (unique_name,TRUE);
1324 /* read creds info */
1325 KDBUS_ITEM_FOREACH(item, conn_info, items)
1331 case KDBUS_ITEM_CREDS:
1333 if (flag == G_BUS_CREDS_PID)
1335 guint pid = item->creds.pid;
1336 result = g_variant_new ("(u)", pid);
1340 if (flag == G_BUS_CREDS_UID)
1342 guint uid = item->creds.uid;
1343 result = g_variant_new ("(u)", uid);
1347 case KDBUS_ITEM_SECLABEL:
1348 if (flag == G_BUS_CREDS_SELINUX_CONTEXT)
1352 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
1354 label = g_strdup (item->str);
1358 for (counter = 0 ; counter < strlen (label) ; counter++)
1360 g_variant_builder_add (builder, "y", label);
1364 result = g_variant_new ("(ay)", builder);
1365 g_variant_builder_unref (builder);
1372 case KDBUS_ITEM_PID_COMM:
1373 case KDBUS_ITEM_TID_COMM:
1374 case KDBUS_ITEM_EXE:
1375 case KDBUS_ITEM_CMDLINE:
1376 case KDBUS_ITEM_CGROUP:
1377 case KDBUS_ITEM_CAPS:
1378 case KDBUS_ITEM_NAME:
1379 case KDBUS_ITEM_AUDIT:
1389 /* generate local reply */
1390 reply = g_kdbus_generate_local_reply (dbus_msg,
1391 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1392 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1393 g_dbus_message_get_serial (dbus_msg),
1396 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1399 ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd->offset);
1406 * g_kdbus_NameHasOwner_handler:
1407 * Returns: TRUE on success.
1410 g_kdbus_NameHasOwner_handler (GDBusWorker *worker,
1412 GDBusMessage *dbus_msg)
1414 GDBusMessage *reply;
1415 GVariant *result = NULL;
1418 /* read and validate message */
1419 GVariant *body = g_dbus_message_get_body (dbus_msg);
1421 if (!g_kdbus_check_signature (worker, dbus_msg, "NameHasOwner", body, G_VARIANT_TYPE("(s)")))
1424 g_variant_get (body, "(&s)", &name);
1426 if (!g_kdbus_check_name (worker, dbus_msg, name))
1429 /* check whether name has owner */
1430 if (!g_kdbus_NameHasOwner (kdbus, name))
1431 result = g_variant_new ("(b)", FALSE);
1433 result = g_variant_new ("(b)", TRUE);
1435 /* generate local reply */
1436 reply = g_kdbus_generate_local_reply (dbus_msg,
1437 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1438 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1439 g_dbus_message_get_serial (dbus_msg),
1442 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1448 * g_kdbus_GetId_handler:
1449 * Returns: TRUE on success.
1452 g_kdbus_GetId_handler (GDBusWorker *worker,
1454 GDBusMessage *dbus_msg)
1456 GDBusMessage *reply;
1457 GString *result = g_string_new (NULL);
1460 for (i=0; i<16; i++)
1461 g_string_append_printf (result, "%02x", kdbus->priv->bus_id[i]);
1463 /* generate local reply */
1464 reply = g_kdbus_generate_local_reply (dbus_msg,
1465 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1466 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1467 g_dbus_message_get_serial (dbus_msg),
1468 g_variant_new ("(s)", result->str),
1470 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1472 g_string_free (result,TRUE);
1478 * g_kdbus_StartServiceByName_handler:
1479 * Returns: TRUE on success.
1483 g_kdbus_StartServiceByName_handler (GDBusWorker *worker,
1485 GDBusMessage *dbus_msg)
1487 GDBusMessage *reply;
1492 body = g_dbus_message_get_body (dbus_msg);
1494 if (!g_kdbus_check_signature (worker, dbus_msg, "StartServiceByName", body, G_VARIANT_TYPE("(su)")))
1497 g_variant_get (body, "(&su)", &name, &flags);
1499 if (!g_kdbus_check_name (worker, dbus_msg, name))
1502 if (g_kdbus_NameHasOwner (kdbus, name))
1504 reply = g_kdbus_generate_local_reply (dbus_msg,
1505 G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1506 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1507 g_dbus_message_get_serial (dbus_msg),
1508 g_variant_new ("(u)", G_BUS_START_REPLY_ALREADY_RUNNING),
1510 _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1515 g_error ("[KDBUS] StartServiceByName method is not implemented yet");
1522 * g_kdbus_AddMatch_handler:
1523 * Returns: TRUE on success.
1527 g_kdbus_AddMatch_handler (GDBusWorker *worker,
1529 GDBusMessage *dbus_msg)
1534 body = g_dbus_message_get_body (dbus_msg);
1536 if (!g_kdbus_check_signature (worker, dbus_msg, "AddMatch", body, G_VARIANT_TYPE("(s)")))
1539 g_variant_get (body, "(&s)", &rule);
1542 g_error ("[KDBUS] AddMatch method is not implemented yet");
1549 * g_kdbus_RemoveMatch_handler:
1550 * Returns: TRUE on success.
1554 g_kdbus_RemoveMatch_handler (GDBusWorker *worker,
1556 GDBusMessage *dbus_msg)
1561 body = g_dbus_message_get_body (dbus_msg);
1563 if (!g_kdbus_check_signature (worker, dbus_msg, "RemoveMatch", body, G_VARIANT_TYPE("(s)")))
1566 g_variant_get (body, "(&s)", &rule);
1569 g_error ("[KDBUS] RemoveMatch method is not implemented yet");
1576 * g_kdbus_UnsupportedMethod_handler:
1577 * Returns: TRUE on success.
1580 g_kdbus_UnsupportedMethod_handler (GDBusWorker *worker,
1582 GDBusMessage *dbus_msg,
1583 const gchar *method_name)
1585 GString *error_name = g_string_new (NULL);
1586 g_string_printf (error_name, "Method \"%s\" is not supported", method_name);
1587 g_kdbus_generate_local_error (worker,
1589 g_variant_new ("(s)",error_name->str),
1590 G_DBUS_ERROR_UNKNOWN_METHOD);
1591 g_string_free (error_name,TRUE);
1597 * g_kdbus_bus_driver:
1601 g_kdbus_bus_driver (GDBusWorker *worker,
1603 GDBusMessage *dbus_msg)
1605 gboolean ret = FALSE;
1608 if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "Hello") == 0)
1610 g_kdbus_take_fd (kdbus);
1611 ret = g_kdbus_Hello_reply (worker, kdbus, dbus_msg);
1614 /* RequestName and ReleaseName */
1615 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "RequestName") == 0)
1616 ret = g_kdbus_RequestName_handler (worker, kdbus, dbus_msg);
1617 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ReleaseName") == 0)
1618 ret = g_kdbus_ReleaseName_handler (worker, kdbus, dbus_msg);
1620 /* All List* Methods */
1621 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListNames") == 0)
1622 ret = g_kdbus_ListNames_handler (worker, kdbus, dbus_msg, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES);
1623 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListActivatableNames") == 0)
1624 ret = g_kdbus_ListNames_handler (worker, kdbus, dbus_msg, KDBUS_NAME_LIST_ACTIVATORS);
1625 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListQueuedOwners") == 0)
1626 ret = g_kdbus_ListQueuedOwners_handler (worker, kdbus, dbus_msg);
1628 /* All Get* Methods */
1629 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetNameOwner") == 0)
1630 ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_UNIQUE_NAME);
1631 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionUnixProcessID") == 0)
1632 ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_PID);
1633 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionUnixUser") == 0)
1634 ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_UID);
1635 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionSELinuxSecurityContext") == 0)
1636 ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_SELINUX_CONTEXT);
1637 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetId") == 0)
1638 ret = g_kdbus_GetId_handler (worker, kdbus, dbus_msg);
1640 /* NameHasOwner nad StartServiceByName methods */
1641 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "NameHasOwner") == 0)
1642 ret = g_kdbus_NameHasOwner_handler (worker, kdbus, dbus_msg);
1643 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "StartServiceByName") == 0)
1644 ret = g_kdbus_StartServiceByName_handler (worker, kdbus, dbus_msg);
1646 /* AddMatch and RemoveMatch */
1647 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "AddMatch") == 0)
1648 ret = g_kdbus_AddMatch_handler (worker, kdbus, dbus_msg);
1649 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "RemoveMatch") == 0)
1650 ret = g_kdbus_RemoveMatch_handler (worker, kdbus, dbus_msg);
1652 /* Unsupported Methods */
1653 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ReloadConfig") == 0)
1654 ret = g_kdbus_UnsupportedMethod_handler (worker, kdbus, dbus_msg, "ReloadConfig");
1655 else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "UpdateActivationEnvironment") == 0)
1656 ret = g_kdbus_UnsupportedMethod_handler (worker, kdbus, dbus_msg, "UpdateActivationEnvironment");
1660 GString *error_name;
1662 error_name = g_string_new (NULL);
1663 g_string_printf (error_name, "org.freedesktop.DBus does not understand message %s", g_dbus_message_get_member(dbus_msg));
1665 g_kdbus_generate_local_error (worker,
1667 g_variant_new ("(s)",error_name->str),
1668 G_DBUS_ERROR_UNKNOWN_METHOD);
1669 g_string_free (error_name,TRUE);
1677 * g_kdbus_alloc_memfd:
1681 g_kdbus_alloc_memfd (GKdbus *kdbus)
1683 struct kdbus_cmd_memfd_make *memfd;
1684 struct kdbus_item *item;
1686 gchar *name = "gdbus-memfd";
1688 size = ALIGN8(G_STRUCT_OFFSET(struct kdbus_cmd_memfd_make, items)) +
1689 ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, str)) +
1692 memfd = g_alloca0 (size);
1695 item = memfd->items;
1696 item->size = ALIGN8(offsetof(struct kdbus_item, str)) + strlen(name) + 1;
1697 item->type = KDBUS_ITEM_MEMFD_NAME;
1698 memcpy(item->str, name, strlen(name) + 1);
1700 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MEMFD_NEW, memfd) < 0)
1703 kdbus->priv->memfd = memfd->fd;
1710 * _g_kdbus_release_msg:
1711 * Release memory occupied by kdbus_msg.
1712 * Use after DBUS message is extracted.
1715 _g_kdbus_release_kmsg (GKdbus *kdbus)
1717 struct kdbus_item *item = NULL;
1718 GSList *iterator = NULL;
1721 offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
1722 ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
1724 for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
1725 g_free ((msg_part*)iterator->data);
1727 g_slist_free (kdbus->priv->kdbus_msg_items);
1728 kdbus->priv->kdbus_msg_items = NULL;
1730 KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
1732 if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1733 close(item->memfd.fd);
1734 else if (item->type == KDBUS_ITEM_FDS)
1737 gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
1739 for (i = 0; i < num_fds; i++)
1740 close(item->fds[i]);
1747 * g_kdbus_append_payload_vec:
1751 g_kdbus_append_payload_vec (struct kdbus_item **item,
1752 const void *data_ptr,
1755 *item = ALIGN8_PTR(*item);
1756 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
1757 (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
1758 (*item)->vec.address = (guint64)((guintptr)data_ptr);
1759 (*item)->vec.size = size;
1760 *item = KDBUS_ITEM_NEXT(*item);
1765 * g_kdbus_append_payload_memfd:
1769 g_kdbus_append_payload_memfd (struct kdbus_item **item,
1773 *item = ALIGN8_PTR(*item);
1774 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
1775 (*item)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
1776 (*item)->memfd.fd = fd;
1777 (*item)->memfd.size = size;
1778 *item = KDBUS_ITEM_NEXT(*item);
1783 * g_kdbus_append_payload_destiantion:
1787 g_kdbus_append_destination (struct kdbus_item **item,
1788 const gchar *destination,
1791 *item = ALIGN8_PTR(*item);
1792 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
1793 (*item)->type = KDBUS_ITEM_DST_NAME;
1794 memcpy ((*item)->str, destination, size+1);
1795 *item = KDBUS_ITEM_NEXT(*item);
1800 * g_kdbus_append_payload_bloom:
1803 static struct kdbus_bloom_filter *
1804 g_kdbus_append_bloom (struct kdbus_item **item,
1807 struct kdbus_item *bloom_item;
1809 bloom_item = ALIGN8_PTR(*item);
1810 bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1811 G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1814 bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1816 *item = KDBUS_ITEM_NEXT(bloom_item);
1817 return &bloom_item->bloom_filter;
1822 * g_kdbus_append_fds:
1826 g_kdbus_append_fds (struct kdbus_item **item,
1827 GUnixFDList *fd_list)
1829 *item = ALIGN8_PTR(*item);
1830 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list);
1831 (*item)->type = KDBUS_ITEM_FDS;
1832 memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) * g_unix_fd_list_get_length(fd_list));
1834 *item = KDBUS_ITEM_NEXT(*item);
1839 * _g_kdbus_attach_fds_to_msg:
1843 _g_kdbus_attach_fds_to_msg (GKdbus *kdbus,
1844 GUnixFDList **fd_list)
1846 if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
1850 if (*fd_list == NULL)
1851 *fd_list = g_unix_fd_list_new();
1853 for (n = 0; n < kdbus->priv->num_fds; n++)
1855 g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
1856 (void) g_close (kdbus->priv->fds[n], NULL);
1859 g_free (kdbus->priv->fds);
1860 kdbus->priv->fds = NULL;
1861 kdbus->priv->num_fds = 0;
1867 * g_kdbus_bloom_add_data:
1868 * Based on bus-bloom.c from systemd
1869 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1872 g_kdbus_bloom_add_data (GKdbus *kdbus,
1873 guint64 bloom_data [],
1879 guint bytes_num = 0;
1885 bit_num = kdbus->priv->bloom_size * 8;
1888 bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1890 for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1892 for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1896 g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1900 p = (p << 8ULL) | (guint64) hash[8 - c];
1905 bloom_data[p >> 6] |= 1ULL << (p & 63);
1911 * g_kdbus_bloom_add_pair:
1915 g_kdbus_bloom_add_pair (GKdbus *kdbus,
1916 guint64 bloom_data [],
1917 const gchar *parameter,
1920 GString *data = g_string_new (NULL);
1922 g_string_printf (data,"%s:%s",parameter,value);
1923 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1924 g_string_free (data, TRUE);
1929 * g_kdbus_bloom_add_prefixes:
1933 g_kdbus_bloom_add_prefixes (GKdbus *kdbus,
1934 guint64 bloom_data [],
1935 const gchar *parameter,
1939 GString *data = g_string_new (NULL);
1941 g_string_printf (data,"%s:%s",parameter,value);
1946 last_sep = strrchr(data->str, separator);
1947 if (!last_sep || last_sep == data->str)
1951 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1953 g_string_free (data, TRUE);
1958 * g_kdbus_setup_bloom:
1959 * Based on bus-bloom.c from systemd
1960 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1963 g_kdbus_setup_bloom (GKdbus *kdbus,
1964 GDBusMessage *dbus_msg,
1965 struct kdbus_bloom_filter *bloom_filter)
1971 const gchar *message_type;
1972 const gchar *interface;
1973 const gchar *member;
1979 body = g_dbus_message_get_body (dbus_msg);
1980 message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1981 interface = g_dbus_message_get_interface (dbus_msg);
1982 member = g_dbus_message_get_member (dbus_msg);
1983 path = g_dbus_message_get_path (dbus_msg);
1985 bloom_data = bloom_filter->data;
1986 memset (bloom_data, 0, kdbus->priv->bloom_size);
1987 bloom_filter->generation = 0;
1989 g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1992 g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1995 g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1999 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
2000 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
2001 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
2006 g_variant_iter_init (&iter, body);
2007 while ((child = g_variant_iter_next_value (&iter)))
2009 gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
2010 gchar *child_string;
2013 /* Is it necessary? */
2014 //if (g_variant_is_container (child))
2015 // iterate_container_recursive (child);
2017 if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
2018 !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
2019 !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
2022 child_string = g_variant_dup_string (child, NULL);
2024 e = stpcpy(buf, "arg");
2026 *(e++) = '0' + (char) cnt;
2029 *(e++) = '0' + (char) (cnt / 10);
2030 *(e++) = '0' + (char) (cnt % 10);
2034 g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
2036 strcpy(e, "-dot-prefix");
2037 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
2039 strcpy(e, "-slash-prefix");
2040 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
2042 g_free (child_string);
2043 g_variant_unref (child);
2051 * g_kdbus_NameOwnerChanged_generate:
2052 * TODO: Not tesed yet
2055 g_kdbus_NameOwnerChanged_generate (GKdbus *kdbus,
2056 struct kdbus_item *item)
2058 GVariant *result = NULL;
2059 GDBusMessage *reply;
2062 gssize reply_size = 0;
2069 if (item->type == KDBUS_ITEM_ID_ADD || item->type == KDBUS_ITEM_ID_REMOVE)
2073 if (item->type == KDBUS_ITEM_ID_ADD)
2086 if (item->type == KDBUS_ITEM_NAME_ADD ||
2087 item->type == KDBUS_ITEM_NAME_REMOVE ||
2088 item->type == KDBUS_ITEM_NAME_CHANGE )
2090 g_error ("[KDBUS] 'NameChange' is not implemented yet");
2093 result = g_variant_new ("(sss)", owner, old_owner, new_owner);
2094 reply = g_kdbus_generate_local_reply (NULL,
2095 G_DBUS_MESSAGE_TYPE_SIGNAL,
2096 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
2101 //_g_dbus_message_set_protocol_ver (reply,2);
2102 blob = g_dbus_message_to_blob (reply, (gsize*) &reply_size, 0, &error);
2105 g_error ("[KDBUS] NameOwnerChanged: %s\n",error->message);
2107 ((guint32 *) blob)[2] = GUINT32_TO_LE (-1);
2108 g_kdbus_add_msg_part (kdbus, (gchar*)blob, reply_size);
2116 * g_kdbus_KernelMethodError_generate:
2120 g_kdbus_KernelMethodError_generate (GKdbus *kdbus,
2121 struct kdbus_item *item)
2123 GVariant *error_name;
2124 GDBusMessage *reply;
2127 gssize reply_size = 0;
2129 if (item->type == KDBUS_ITEM_REPLY_TIMEOUT)
2130 error_name = g_variant_new ("(s)", "Method call timed out");
2132 error_name = g_variant_new ("(s)", "Method call peer died");
2135 reply = g_kdbus_generate_local_reply (NULL,
2136 G_DBUS_MESSAGE_TYPE_ERROR,
2137 G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
2140 "org.freedesktop.DBus.Error.NoReply");
2142 //_g_dbus_message_set_protocol_ver (reply,2);
2143 blob = g_dbus_message_to_blob (reply, (gsize*) &reply_size, 0, &error);
2146 g_error ("[KDBUS] KernelMethodError: %s\n",error->message);
2148 ((guint32 *) blob)[2] = GUINT32_TO_LE (-1);
2149 g_kdbus_add_msg_part (kdbus, (gchar*)blob, reply_size);
2156 * g_kdbus_decode_kernel_msg:
2160 g_kdbus_decode_kernel_msg (GKdbus *kdbus)
2162 struct kdbus_item *item = NULL;
2165 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
2169 case KDBUS_ITEM_ID_ADD:
2170 case KDBUS_ITEM_ID_REMOVE:
2171 case KDBUS_ITEM_NAME_ADD:
2172 case KDBUS_ITEM_NAME_REMOVE:
2173 case KDBUS_ITEM_NAME_CHANGE:
2174 size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
2177 case KDBUS_ITEM_REPLY_TIMEOUT:
2178 case KDBUS_ITEM_REPLY_DEAD:
2179 size = g_kdbus_KernelMethodError_generate (kdbus, item);
2183 g_error ("[KDBUS] KERNEL: Unknown filed - %lld", item->type);
2187 /* Override information from the user header with data from the kernel */
2188 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2190 /* for destination */
2191 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2192 /* for broadcast messages we don't have to set destination */
2194 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2195 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2197 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2205 * g_kdbus_decode_dbus_msg:
2209 g_kdbus_decode_dbus_msg (GKdbus *kdbus)
2211 struct kdbus_item *item;
2213 gssize ret_size = 0;
2214 gssize data_size = 0;
2215 const gchar *destination = NULL;
2217 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
2219 if (item->size <= KDBUS_ITEM_HEADER_SIZE)
2220 g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
2222 data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
2227 /* KDBUS_ITEM_DST_NAME */
2228 case KDBUS_ITEM_DST_NAME:
2229 destination = item->str;
2232 /* KDBUS_ITEM_PALOAD_OFF */
2233 case KDBUS_ITEM_PAYLOAD_OFF:
2235 msg_ptr = (gchar*) kdbus->priv->kmsg + item->vec.offset;
2236 g_kdbus_add_msg_part (kdbus, msg_ptr, item->vec.size);
2237 ret_size += item->vec.size;
2241 /* KDBUS_ITEM_PAYLOAD_MEMFD */
2242 case KDBUS_ITEM_PAYLOAD_MEMFD:
2244 msg_ptr = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
2246 if (msg_ptr == MAP_FAILED)
2248 g_print ("mmap() fd=%i failed:%m", item->memfd.fd);
2252 g_kdbus_add_msg_part (kdbus, msg_ptr, item->memfd.size);
2253 ret_size += item->memfd.size;
2257 /* KDBUS_ITEM_FDS */
2258 case KDBUS_ITEM_FDS:
2260 kdbus->priv->num_fds = data_size / sizeof(int);
2261 kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
2262 memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
2266 /* All of the following items, like CMDLINE,
2267 CGROUP, etc. need some GDBUS API extensions and
2268 should be implemented in the future */
2269 case KDBUS_ITEM_CREDS:
2270 case KDBUS_ITEM_TIMESTAMP:
2271 case KDBUS_ITEM_PID_COMM:
2272 case KDBUS_ITEM_TID_COMM:
2273 case KDBUS_ITEM_EXE:
2274 case KDBUS_ITEM_CMDLINE:
2275 case KDBUS_ITEM_CGROUP:
2276 case KDBUS_ITEM_AUDIT:
2277 case KDBUS_ITEM_CAPS:
2278 case KDBUS_ITEM_SECLABEL:
2279 case KDBUS_ITEM_CONN_NAME:
2280 case KDBUS_ITEM_NAME:
2284 g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
2289 /* Override information from the user header with data from the kernel */
2291 if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
2292 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2294 g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
2297 g_string_printf (kdbus->priv->msg_destination, "%s", destination);
2298 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2299 /* for broadcast messages we don't have to set destination */
2301 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2302 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2304 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2315 _g_kdbus_receive (GKdbus *kdbus,
2316 GCancellable *cancellable,
2319 struct kdbus_cmd_recv recv = {};
2322 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2326 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
2328 if (errno == EINTR || errno == EAGAIN)
2331 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno),_("Error receiving message - KDBUS_CMD_MSG_RECV error"));
2335 kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
2337 if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
2338 size = g_kdbus_decode_dbus_msg (kdbus);
2339 else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
2340 size = g_kdbus_decode_kernel_msg (kdbus);
2342 g_error ("[KDBUS] Unknown payload type: %llu", kdbus->priv->kmsg->payload_type);
2350 * Returns: size of data sent or -1 when error
2353 _g_kdbus_send (GDBusWorker *worker,
2355 GDBusMessage *dbus_msg,
2358 GUnixFDList *fd_list,
2359 GCancellable *cancellable,
2362 struct kdbus_msg* kmsg;
2363 struct kdbus_item *item;
2364 guint64 kmsg_size = 0;
2366 gboolean use_memfd = FALSE;
2367 guint64 dst_id = KDBUS_DST_ID_BROADCAST;
2369 g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2371 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2376 * If systemd-bus-driverd from systemd isn't available
2377 * try to process the bus driver messages locally
2379 #ifndef SYSTEMD_BUS_DRIVERD
2380 if (g_strcmp0(g_dbus_message_get_destination(dbus_msg), "org.freedesktop.DBus") == 0)
2382 if (g_kdbus_bus_driver (worker, kdbus, dbus_msg))
2388 if ((g_strcmp0(g_dbus_message_get_destination(dbus_msg), "org.freedesktop.DBus") == 0) &&
2389 (g_strcmp0(g_dbus_message_get_member(dbus_msg), "Hello") == 0))
2391 g_kdbus_take_fd (kdbus);
2399 if ((name = g_dbus_message_get_destination(dbus_msg)))
2401 dst_id = KDBUS_DST_ID_NAME;
2402 if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
2404 dst_id = strtoull(&name[3], NULL, 10);
2411 * check whether we should use memfd transport (for messages > 512K)
2413 if (name && (blob_size > 524288))
2418 * check and set message size
2420 kmsg_size = sizeof(struct kdbus_msg);
2423 kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); /* header */
2424 kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); /* body */
2427 kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); /* header + body */
2429 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2430 kmsg_size += ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list));
2433 kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
2434 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2435 kmsg_size += ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
2436 G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
2437 kdbus->priv->bloom_size);
2439 kmsg = malloc(kmsg_size);
2441 g_error ("[KDBUS] kmsg malloc error");
2445 * set message header
2447 memset(kmsg, 0, kmsg_size);
2448 kmsg->size = kmsg_size;
2449 kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
2450 kmsg->dst_id = name ? 0 : dst_id;
2451 kmsg->src_id = kdbus->priv->unique_id;
2452 kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
2459 kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2460 ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2462 if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2463 kmsg->timeout_ns = 2000000000;
2465 kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
2476 if (!g_kdbus_alloc_memfd (kdbus))
2477 g_error ("Can't alloc memfd");
2479 /* split blob to header and body */
2480 memcpy (&body_size, blob+4, 4);
2481 body_size = GINT32_FROM_LE (body_size);
2484 * write blob and seal
2485 * We should build up whole messsage directly in memfd object without
2486 * making copy but memfd will be completly reworked soon [1],
2487 * so we're still waiting for this:
2489 * [1] https://code.google.com/p/d-bus/source/browse/TODO
2492 if (write(kdbus->priv->memfd, blob + (blob_size-body_size), body_size) <= 0)
2493 g_error ("Can't write data to memfd object");
2495 if (ioctl(kdbus->priv->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0)
2496 g_error ("Can't seal memfd object");
2498 /* message header in its entirety must be contained in a single PAYLOAD_VEC item */
2499 g_kdbus_append_payload_vec (&item, blob, blob_size - body_size);
2500 /* send body as as PAYLOAD_MEMFD item */
2501 g_kdbus_append_payload_memfd (&item, kdbus->priv->memfd, body_size);
2505 /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
2506 g_kdbus_append_payload_vec (&item, blob, blob_size);
2511 * append destination or bloom filters
2514 g_kdbus_append_destination (&item, name, strlen(name));
2515 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2517 struct kdbus_bloom_filter *bloom_filter;
2519 bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2520 g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
2527 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2528 g_kdbus_append_fds (&item, fd_list);
2535 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
2537 GString *error_name;
2538 error_name = g_string_new (NULL);
2542 g_string_free (error_name,TRUE);
2545 else if (errno == ENXIO)
2547 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2548 g_kdbus_generate_local_error (worker,
2550 g_variant_new ("(s)",error_name->str),
2551 G_DBUS_ERROR_SERVICE_UNKNOWN);
2552 g_string_free (error_name,TRUE);
2555 else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2557 if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2559 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2560 g_kdbus_generate_local_error (worker,
2562 g_variant_new ("(s)",error_name->str),
2563 G_DBUS_ERROR_SERVICE_UNKNOWN);
2564 g_string_free (error_name,TRUE);
2569 g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2570 g_kdbus_generate_local_error (worker,
2572 g_variant_new ("(s)",error_name->str),
2573 G_DBUS_ERROR_SERVICE_UNKNOWN);
2574 g_string_free (error_name,TRUE);
2579 g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2580 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2584 if (kdbus->priv->memfd >= 0)
2585 close(kdbus->priv->memfd);