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>
26 #include "glib-unix.h"
29 #include "gkdbusconnection.h"
35 #include <sys/ioctl.h>
38 #ifdef HAVE_SYS_FILIO_H
39 # include <sys/filio.h>
46 #define KDBUS_POOL_SIZE (16 * 1024LU * 1024LU)
47 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
48 #define KDBUS_ALIGN8_PTR(p) ((void*) (uintptr_t)(p))
50 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
51 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
53 #define KDBUS_ITEM_NEXT(item) \
54 (typeof(item))(((guint8 *)item) + KDBUS_ALIGN8((item)->size))
55 #define KDBUS_ITEM_FOREACH(item, head, first) \
56 for (item = (head)->first; \
57 (guint8 *)(item) < (guint8 *)(head) + (head)->size; \
58 item = KDBUS_ITEM_NEXT(item))
60 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
62 static void g_kdbus_initable_iface_init (GInitableIface *iface);
63 static gboolean g_kdbus_initable_init (GInitable *initable,
64 GCancellable *cancellable,
67 #define g_kdbus_get_type _g_kdbus_get_type
68 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
69 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
70 g_kdbus_initable_iface_init));
72 /* GBusCredentialsFlags */
77 G_BUS_CREDS_UNIQUE_NAME = 3,
78 G_BUS_CREDS_SELINUX_CONTEXT = 4
79 } GBusCredentialsFlags;
81 /* GBusNameOwnerReturnFlags */
84 G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1, /* Caller is now the primary owner of the name, replacing any previous owner */
85 G_BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2, /* The name already had an owner, the application will be placed in a queue */
86 G_BUS_REQUEST_NAME_REPLY_EXISTS = 3, /* The name already has an owner */
87 G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4 /* The application trying to request ownership of a name is already the owner of it */
88 } GBusNameOwnerReturnFlags;
90 /* GBusReleaseNameReturnFlags */
93 G_BUS_RELEASE_NAME_REPLY_RELEASED = 1, /* The caller has released his claim on the given name */
94 G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT = 2, /* The given name does not exist on this bus*/
95 G_BUS_RELEASE_NAME_REPLY_NOT_OWNER = 3 /* The caller not waiting in the queue to own this name*/
96 } GBusReleaseNameReturnFlags;
98 /* GKdbusPrivate struct */
104 struct kdbus_msg *kmsg;
110 guint64 attach_flags;
120 /* GKdbusSource struct */
125 GIOCondition condition;
126 GCancellable *cancellable;
127 GPollFD cancel_pollfd;
132 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
133 GIOCondition condition,
141 g_kdbus_finalize (GObject *object)
143 GKdbus *kdbus = G_KDBUS (object);
145 if (kdbus->priv->kdbus_buffer != NULL)
146 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
148 kdbus->priv->kdbus_buffer = NULL;
150 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
151 _g_kdbus_close (kdbus, NULL);
153 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
154 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
159 * g_kdbus_class_init:
163 g_kdbus_class_init (GKdbusClass *klass)
165 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
167 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
168 gobject_class->finalize = g_kdbus_finalize;
173 * g_kdbus_initable_iface_init:
177 g_kdbus_initable_iface_init (GInitableIface *iface)
179 iface->init = g_kdbus_initable_init;
188 g_kdbus_init (GKdbus *kdbus)
190 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
192 kdbus->priv->fd = -1;
194 kdbus->priv->unique_id = -1;
195 kdbus->priv->unique_name = NULL;
197 kdbus->priv->kdbus_buffer = NULL;
199 kdbus->priv->hello_flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
200 kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
205 * g_kdbus_initable_init:
209 g_kdbus_initable_init (GInitable *initable,
210 GCancellable *cancellable,
215 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
217 kdbus = G_KDBUS (initable);
219 if (cancellable != NULL)
221 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
222 _("Cancellable initialization not supported"));
226 kdbus->priv->inited = TRUE;
233 * kdbus_source_prepare:
237 kdbus_source_prepare (GSource *source,
240 GKdbusSource *kdbus_source = (GKdbusSource *)source;
242 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
245 if (kdbus_source->timeout_time)
249 now = g_source_get_time (source);
251 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
254 kdbus_source->kdbus->priv->timed_out = TRUE;
262 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
270 * kdbus_source_check:
274 kdbus_source_check (GSource *source)
278 return kdbus_source_prepare (source, &timeout);
283 * kdbus_source_dispatch
287 kdbus_source_dispatch (GSource *source,
288 GSourceFunc callback,
291 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
292 GKdbusSource *kdbus_source = (GKdbusSource *)source;
293 GKdbus *kdbus = kdbus_source->kdbus;
296 if (kdbus_source->kdbus->priv->timed_out)
297 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
299 ret = (*func) (kdbus,
300 kdbus_source->pollfd.revents & kdbus_source->condition,
303 if (kdbus->priv->timeout)
304 kdbus_source->timeout_time = g_get_monotonic_time ()
305 + kdbus->priv->timeout * 1000000;
308 kdbus_source->timeout_time = 0;
315 * kdbus_source_finalize
319 kdbus_source_finalize (GSource *source)
321 GKdbusSource *kdbus_source = (GKdbusSource *)source;
324 kdbus = kdbus_source->kdbus;
326 g_object_unref (kdbus);
328 if (kdbus_source->cancellable)
330 g_cancellable_release_fd (kdbus_source->cancellable);
331 g_object_unref (kdbus_source->cancellable);
337 * kdbus_source_closure_callback:
341 kdbus_source_closure_callback (GKdbus *kdbus,
342 GIOCondition condition,
345 GClosure *closure = data;
346 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
347 GValue result_value = G_VALUE_INIT;
350 g_value_init (&result_value, G_TYPE_BOOLEAN);
352 g_value_init (¶ms[0], G_TYPE_KDBUS);
353 g_value_set_object (¶ms[0], kdbus);
354 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
355 g_value_set_flags (¶ms[1], condition);
357 g_closure_invoke (closure, &result_value, 2, params, NULL);
359 result = g_value_get_boolean (&result_value);
360 g_value_unset (&result_value);
361 g_value_unset (¶ms[0]);
362 g_value_unset (¶ms[1]);
368 static GSourceFuncs kdbus_source_funcs =
370 kdbus_source_prepare,
372 kdbus_source_dispatch,
373 kdbus_source_finalize,
374 (GSourceFunc)kdbus_source_closure_callback,
383 kdbus_source_new (GKdbus *kdbus,
384 GIOCondition condition,
385 GCancellable *cancellable)
388 GKdbusSource *kdbus_source;
390 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
391 g_source_set_name (source, "GKdbus");
392 kdbus_source = (GKdbusSource *)source;
394 kdbus_source->kdbus = g_object_ref (kdbus);
395 kdbus_source->condition = condition;
397 if (g_cancellable_make_pollfd (cancellable,
398 &kdbus_source->cancel_pollfd))
400 kdbus_source->cancellable = g_object_ref (cancellable);
401 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
404 kdbus_source->pollfd.fd = kdbus->priv->fd;
405 kdbus_source->pollfd.events = condition;
406 kdbus_source->pollfd.revents = 0;
407 g_source_add_poll (source, &kdbus_source->pollfd);
409 if (kdbus->priv->timeout)
410 kdbus_source->timeout_time = g_get_monotonic_time ()
411 + kdbus->priv->timeout * 1000000;
413 kdbus_source->timeout_time = 0;
420 * _g_kdbus_create_source:
424 _g_kdbus_create_source (GKdbus *kdbus,
425 GIOCondition condition,
426 GCancellable *cancellable)
428 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
430 return kdbus_source_new (kdbus, condition, cancellable);
439 _g_kdbus_open (GKdbus *kdbus,
440 const gchar *address,
443 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
445 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
446 if (kdbus->priv->fd<0)
448 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
452 kdbus->priv->closed = FALSE;
463 g_kdbus_free_data (GKdbus *kdbus,
466 struct kdbus_cmd_free cmd;
472 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
481 * g_kdbus_translate_nameowner_flags:
485 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
486 guint64 *kdbus_flags)
492 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
493 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
495 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
496 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
498 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
499 new_flags |= KDBUS_NAME_QUEUE;
501 *kdbus_flags = new_flags;
510 _g_kdbus_close (GKdbus *kdbus,
515 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
517 if (kdbus->priv->closed)
522 res = close (kdbus->priv->fd);
529 g_set_error (error, G_IO_ERROR,
530 g_io_error_from_errno (errno),
531 _("Error closing kdbus fd: %s"),
538 kdbus->priv->closed = TRUE;
539 kdbus->priv->fd = -1;
546 * _g_kdbus_is_closed:
550 _g_kdbus_is_closed (GKdbus *kdbus)
552 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
554 return kdbus->priv->closed;
563 _g_kdbus_Hello (GIOStream *stream,
567 struct kdbus_cmd_hello *hello;
568 struct kdbus_item *item;
571 size_t size, conn_name_size;
573 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
575 conn_name = "gdbus-kdbus";
576 conn_name_size = strlen (conn_name);
578 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
579 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
581 hello = g_alloca0 (size);
582 hello->conn_flags = kdbus->priv->hello_flags;
583 hello->attach_flags = kdbus->priv->attach_flags;
585 hello->pool_size = KDBUS_POOL_SIZE;
588 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
589 item->type = KDBUS_ITEM_CONN_NAME;
590 memcpy (item->str, conn_name, conn_name_size+1);
591 item = KDBUS_ITEM_NEXT (item);
593 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
595 g_set_error (error, G_IO_ERROR,
596 g_io_error_from_errno (errno),
597 _("Failed to send HELLO: %s"),
602 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
603 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
605 g_set_error (error, G_IO_ERROR,
606 g_io_error_from_errno (errno),
612 if (hello->bus_flags > 0xFFFFFFFFULL)
614 g_set_error_literal (error,
617 _("Incompatible HELLO flags"));
621 memcpy (kdbus->priv->bus_id, hello->id128, 16);
623 kdbus->priv->unique_id = hello->id;
624 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
626 return g_variant_new ("(s)", kdbus->priv->unique_name);
631 * _g_kdbus_RequestName:
635 _g_kdbus_RequestName (GDBusConnection *connection,
637 GBusNameOwnerFlags flags,
642 struct kdbus_cmd_name *kdbus_name;
647 status = G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
649 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
652 g_set_error_literal (error,
654 G_DBUS_ERROR_IO_ERROR,
655 _("The connection is closed"));
659 if (!g_dbus_is_name (name))
663 G_DBUS_ERROR_INVALID_ARGS,
664 "Given bus name \"%s\" is not valid", name);
672 G_DBUS_ERROR_INVALID_ARGS,
673 "Cannot acquire a service starting with ':' such as \"%s\"", name);
677 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
679 len = strlen(name) + 1;
680 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
681 kdbus_name = g_alloca0 (size);
682 kdbus_name->size = size;
683 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
684 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
685 kdbus_name->flags = kdbus_flags;
686 memcpy (kdbus_name->items[0].str, name, len);
688 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
692 status = G_BUS_REQUEST_NAME_REPLY_EXISTS;
693 else if (errno == EALREADY)
694 status = G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
697 g_set_error (error, G_IO_ERROR,
698 g_io_error_from_errno (errno),
699 _("Error while acquiring name: %s"),
705 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
706 status = G_BUS_REQUEST_NAME_REPLY_IN_QUEUE;
708 result = g_variant_new ("(u)", status);
715 * _g_kdbus_ReleaseName:
719 _g_kdbus_ReleaseName (GDBusConnection *connection,
725 struct kdbus_cmd_name *kdbus_name;
729 status = G_BUS_RELEASE_NAME_REPLY_RELEASED;
731 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
734 g_set_error_literal (error,
736 G_DBUS_ERROR_IO_ERROR,
737 _("The connection is closed"));
741 if (!g_dbus_is_name (name))
745 G_DBUS_ERROR_INVALID_ARGS,
746 "Given bus name \"%s\" is not valid", name);
754 G_DBUS_ERROR_INVALID_ARGS,
755 "Cannot release a service starting with ':' such as \"%s\"", name);
759 len = strlen(name) + 1;
760 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
761 kdbus_name = g_alloca0 (size);
762 kdbus_name->size = size;
763 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
764 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
765 memcpy (kdbus_name->items[0].str, name, len);
767 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
771 status = G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT;
772 else if (errno == EADDRINUSE)
773 status = G_BUS_RELEASE_NAME_REPLY_NOT_OWNER;
776 g_set_error (error, G_IO_ERROR,
777 g_io_error_from_errno (errno),
778 _("Error while releasing name: %s"),
784 result = g_variant_new ("(u)", status);
795 _g_kdbus_GetBusId (GDBusConnection *connection,
803 result_str = g_string_new (NULL);
804 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
807 g_set_error_literal (error,
809 G_DBUS_ERROR_IO_ERROR,
810 _("The connection is closed"));
811 g_string_free (result_str, TRUE);
815 for (cnt=0; cnt<16; cnt++)
816 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
818 result = g_variant_new ("(s)", result_str->str);
819 g_string_free (result_str, TRUE);
826 * _g_kdbus_GetListNames:
830 _g_kdbus_GetListNames (GDBusConnection *connection,
831 guint list_name_type,
836 GVariantBuilder *builder;
838 struct kdbus_cmd_name_list cmd = {};
839 struct kdbus_name_list *name_list;
840 struct kdbus_cmd_name *name;
846 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
849 g_set_error_literal (error,
851 G_DBUS_ERROR_IO_ERROR,
852 _("The connection is closed"));
857 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
859 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
861 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
867 _("Error listing names"));
871 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
872 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
874 KDBUS_ITEM_FOREACH(name, name_list, names)
876 struct kdbus_item *item;
877 const gchar *item_name = "";
879 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
881 GString *unique_name;
883 unique_name = g_string_new (NULL);
884 g_string_printf (unique_name, ":1.%llu", name->owner_id);
885 g_variant_builder_add (builder, "s", unique_name->str);
886 g_string_free (unique_name,TRUE);
887 prev_id = name->owner_id;
890 KDBUS_ITEM_FOREACH(item, name, items)
891 if (item->type == KDBUS_ITEM_NAME)
892 item_name = item->str;
894 if (g_dbus_is_name (item_name))
895 g_variant_builder_add (builder, "s", item_name);
898 result = g_variant_new ("(as)", builder);
899 g_variant_builder_unref (builder);
901 g_kdbus_free_data (kdbus, cmd.offset);
907 * _g_kdbus_NameHasOwner_internal:
911 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
915 struct kdbus_cmd_conn_info *cmd;
919 if (g_dbus_is_unique_name(name))
921 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
922 cmd = g_alloca0 (size);
923 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
927 len = strlen(name) + 1;
928 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
929 cmd = g_alloca0 (size);
930 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
931 cmd->items[0].type = KDBUS_ITEM_NAME;
932 memcpy (cmd->items[0].str, name, len);
936 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
937 g_kdbus_free_data (kdbus, cmd->offset);
947 * _g_kdbus_GetListQueuedOwners:
951 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
957 GVariantBuilder *builder;
958 GString *unique_name;
961 struct kdbus_cmd_name_list cmd = {};
962 struct kdbus_name_list *name_list;
963 struct kdbus_cmd_name *kname;
965 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
968 g_set_error_literal (error,
970 G_DBUS_ERROR_IO_ERROR,
971 _("The connection is closed"));
975 if (!g_dbus_is_name (name))
979 G_DBUS_ERROR_INVALID_ARGS,
980 "Given bus name \"%s\" is not valid", name);
984 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
988 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
989 "Could not get owner of name '%s': no such name", name);
993 cmd.flags = KDBUS_NAME_LIST_QUEUED;
994 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1000 _("Error listing names"));
1004 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1006 unique_name = g_string_new (NULL);
1007 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1008 KDBUS_ITEM_FOREACH(kname, name_list, names)
1010 struct kdbus_item *item;
1011 const char *item_name = "";
1013 KDBUS_ITEM_FOREACH(item, kname, items)
1014 if (item->type == KDBUS_ITEM_NAME)
1015 item_name = item->str;
1017 if (strcmp(item_name, name))
1020 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1021 g_variant_builder_add (builder, "s", item_name);
1024 result = g_variant_new ("(as)", builder);
1025 g_variant_builder_unref (builder);
1026 g_string_free (unique_name,TRUE);
1028 g_kdbus_free_data (kdbus, cmd.offset);
1034 * _g_kdbus_NameHasOwner:
1038 _g_kdbus_NameHasOwner (GDBusConnection *connection,
1045 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1048 g_set_error_literal (error,
1050 G_DBUS_ERROR_IO_ERROR,
1051 _("The connection is closed"));
1055 if (!g_dbus_is_name (name))
1059 G_DBUS_ERROR_INVALID_ARGS,
1060 "Given bus name \"%s\" is not valid", name);
1064 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1065 result = g_variant_new ("(b)", FALSE);
1067 result = g_variant_new ("(b)", TRUE);
1074 * g_kdbus_GetConnInfo_internal:
1078 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
1086 struct kdbus_cmd_conn_info *cmd;
1087 struct kdbus_conn_info *conn_info;
1088 struct kdbus_item *item;
1093 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1096 g_set_error_literal (error,
1098 G_DBUS_ERROR_IO_ERROR,
1099 _("The connection is closed"));
1103 if (!g_dbus_is_name (name))
1107 G_DBUS_ERROR_INVALID_ARGS,
1108 "Given bus name \"%s\" is not valid", name);
1112 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1116 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1117 "Could not get owner of name '%s': no such name", name);
1121 if (g_dbus_is_unique_name(name))
1123 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
1124 cmd = g_alloca0 (size);
1125 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1129 len = strlen(name) + 1;
1130 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
1131 cmd = g_alloca0 (size);
1132 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1133 cmd->items[0].type = KDBUS_ITEM_NAME;
1134 memcpy (cmd->items[0].str, name, len);
1137 cmd->flags = KDBUS_ATTACH_NAMES;
1140 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1145 G_DBUS_ERROR_FAILED,
1146 _("Could not get connection info"));
1150 conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1153 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1157 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1159 GString *unique_name;
1161 unique_name = g_string_new (NULL);
1162 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1163 result = g_variant_new ("(s)", unique_name->str);
1164 g_string_free (unique_name,TRUE);
1168 KDBUS_ITEM_FOREACH(item, conn_info, items)
1172 case KDBUS_ITEM_CREDS:
1174 if (flag == G_BUS_CREDS_PID)
1176 guint pid = item->creds.pid;
1177 result = g_variant_new ("(u)", pid);
1181 if (flag == G_BUS_CREDS_UID)
1183 guint uid = item->creds.uid;
1184 result = g_variant_new ("(u)", uid);
1188 case KDBUS_ITEM_SECLABEL:
1189 case KDBUS_ITEM_PID_COMM:
1190 case KDBUS_ITEM_TID_COMM:
1191 case KDBUS_ITEM_EXE:
1192 case KDBUS_ITEM_CMDLINE:
1193 case KDBUS_ITEM_CGROUP:
1194 case KDBUS_ITEM_CAPS:
1195 case KDBUS_ITEM_NAME:
1196 case KDBUS_ITEM_AUDIT:
1202 g_kdbus_free_data (kdbus, cmd->offset);
1208 * _g_kdbus_GetNameOwner:
1212 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1216 return g_kdbus_GetConnInfo_internal (connection,
1218 G_BUS_CREDS_UNIQUE_NAME,
1224 * _g_kdbus_GetConnectionUnixProcessID:
1228 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1232 return g_kdbus_GetConnInfo_internal (connection,
1240 * _g_kdbus_GetConnectionUnixUser:
1244 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1248 return g_kdbus_GetConnInfo_internal (connection,
1256 * _g_kdbus_subscribe_name_acquired:
1260 _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
1262 const gchar *old_name,
1263 const gchar *new_name,
1267 struct kdbus_item *item;
1268 struct kdbus_cmd_match *cmd_match;
1272 guint64 new_id = KDBUS_MATCH_ID_ANY;
1274 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1276 len = strlen(name) + 1;
1277 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1278 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1279 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1281 cmd_match = g_alloca0 (size);
1282 cmd_match->size = size;
1283 cmd_match->cookie = cookie;
1284 item = cmd_match->items;
1286 if (old_name[0] == 0)
1288 old_id = KDBUS_MATCH_ID_ANY;
1292 if (g_dbus_is_unique_name(old_name))
1298 if (new_name[0] == 0)
1300 new_id = KDBUS_MATCH_ID_ANY;
1304 if (g_dbus_is_unique_name(new_name))
1310 cmd_match = g_alloca0 (size);
1311 cmd_match->size = size;
1312 cmd_match->cookie = cookie;
1313 item = cmd_match->items;
1315 /* KDBUS_ITEM_NAME_CHANGE */
1316 item->type = KDBUS_ITEM_NAME_CHANGE;
1317 item->name_change.old_id.id = old_id;
1318 item->name_change.new_id.id = new_id;
1319 memcpy(item->name_change.name, name, len);
1320 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1321 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1322 item = KDBUS_ITEM_NEXT(item);
1324 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1326 g_warning ("ERROR - %d\n", (int) errno);
1331 * _g_kdbus_subscribe_name_acquired:
1335 _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
1339 struct kdbus_item *item;
1340 struct kdbus_cmd_match *cmd_match;
1345 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1347 len = strlen(name) + 1;
1348 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1349 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1350 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1352 cookie = 0xbeefbeefbeefbeef;
1353 cmd_match = g_alloca0 (size);
1354 cmd_match->size = size;
1355 cmd_match->cookie = cookie;
1356 item = cmd_match->items;
1358 /* KDBUS_ITEM_NAME_ADD */
1359 item->type = KDBUS_ITEM_NAME_ADD;
1360 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1361 item->name_change.new_id.id = kdbus->priv->unique_id;
1362 memcpy(item->name_change.name, name, len);
1363 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1364 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1365 item = KDBUS_ITEM_NEXT(item);
1367 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1369 g_warning ("ERROR - %d\n", (int) errno);
1371 _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1376 * _g_kdbus_subscribe_name_lost:
1380 _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
1384 struct kdbus_item *item;
1385 struct kdbus_cmd_match *cmd_match;
1390 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1392 len = strlen(name) + 1;
1393 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1394 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1395 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1397 cookie = 0xdeafdeafdeafdeaf;
1398 cmd_match = g_alloca0 (size);
1399 cmd_match->size = size;
1400 cmd_match->cookie = cookie;
1401 item = cmd_match->items;
1403 /* KDBUS_ITEM_NAME_REMOVE */
1404 item->type = KDBUS_ITEM_NAME_REMOVE;
1405 item->name_change.old_id.id = kdbus->priv->unique_id;
1406 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1407 memcpy(item->name_change.name, name, len);
1408 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1409 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1410 item = KDBUS_ITEM_NEXT(item);
1412 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1414 g_warning ("ERROR - %d\n", (int) errno);
1416 _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1421 * g_kdbus_decode_kernel_msg:
1425 g_kdbus_decode_kernel_msg (GKdbus *kdbus)
1427 struct kdbus_item *item = NULL;
1430 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1434 case KDBUS_ITEM_ID_ADD:
1435 case KDBUS_ITEM_ID_REMOVE:
1436 case KDBUS_ITEM_NAME_ADD:
1437 case KDBUS_ITEM_NAME_REMOVE:
1438 case KDBUS_ITEM_NAME_CHANGE:
1439 //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1440 g_error ("'NameOwnerChanged'");
1443 case KDBUS_ITEM_REPLY_TIMEOUT:
1444 case KDBUS_ITEM_REPLY_DEAD:
1445 //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1446 g_error ("'KernelMethodError'");
1450 g_warning ("Unknown field in kernel message - %lld", item->type);
1455 /* Override information from the user header with data from the kernel */
1456 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1458 /* for destination */
1459 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1460 /* for broadcast messages we don't have to set destination */
1462 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1463 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1465 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1477 _g_kdbus_receive (GKdbus *kdbus,
1478 GCancellable *cancellable,
1481 struct kdbus_cmd_recv recv = {};
1484 if (g_cancellable_set_error_if_cancelled (cancellable, error))
1488 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1490 if (errno == EINTR || errno == EAGAIN)
1493 g_set_error (error, G_IO_ERROR,
1494 g_io_error_from_errno (errno),
1495 _("Error while receiving message: %s"),
1496 g_strerror (errno));
1500 kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
1502 if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
1503 g_error ("Received standard dbus message - not supported yet");
1504 else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
1505 size = g_kdbus_decode_kernel_msg (kdbus);
1510 G_DBUS_ERROR_FAILED,
1511 _("Received unknown payload type"));