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 /* GKdbusPrivate struct */
87 struct kdbus_msg *kmsg;
103 /* GKdbusSource struct */
108 GIOCondition condition;
109 GCancellable *cancellable;
110 GPollFD cancel_pollfd;
115 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
116 GIOCondition condition,
124 g_kdbus_finalize (GObject *object)
126 GKdbus *kdbus = G_KDBUS (object);
128 if (kdbus->priv->kdbus_buffer != NULL)
129 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
131 kdbus->priv->kdbus_buffer = NULL;
133 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
134 _g_kdbus_close (kdbus, NULL);
136 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
137 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
142 * g_kdbus_class_init:
146 g_kdbus_class_init (GKdbusClass *klass)
148 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
150 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
151 gobject_class->finalize = g_kdbus_finalize;
156 * g_kdbus_initable_iface_init:
160 g_kdbus_initable_iface_init (GInitableIface *iface)
162 iface->init = g_kdbus_initable_init;
171 g_kdbus_init (GKdbus *kdbus)
173 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
175 kdbus->priv->fd = -1;
177 kdbus->priv->unique_id = -1;
178 kdbus->priv->unique_name = NULL;
180 kdbus->priv->kdbus_buffer = NULL;
182 kdbus->priv->hello_flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
183 kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
188 * g_kdbus_initable_init:
192 g_kdbus_initable_init (GInitable *initable,
193 GCancellable *cancellable,
198 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
200 kdbus = G_KDBUS (initable);
202 if (cancellable != NULL)
204 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
205 _("Cancellable initialization not supported"));
209 kdbus->priv->inited = TRUE;
216 * kdbus_source_prepare:
220 kdbus_source_prepare (GSource *source,
223 GKdbusSource *kdbus_source = (GKdbusSource *)source;
225 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
228 if (kdbus_source->timeout_time)
232 now = g_source_get_time (source);
234 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
237 kdbus_source->kdbus->priv->timed_out = TRUE;
245 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
253 * kdbus_source_check:
257 kdbus_source_check (GSource *source)
261 return kdbus_source_prepare (source, &timeout);
266 * kdbus_source_dispatch
270 kdbus_source_dispatch (GSource *source,
271 GSourceFunc callback,
274 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
275 GKdbusSource *kdbus_source = (GKdbusSource *)source;
276 GKdbus *kdbus = kdbus_source->kdbus;
279 if (kdbus_source->kdbus->priv->timed_out)
280 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
282 ret = (*func) (kdbus,
283 kdbus_source->pollfd.revents & kdbus_source->condition,
286 if (kdbus->priv->timeout)
287 kdbus_source->timeout_time = g_get_monotonic_time ()
288 + kdbus->priv->timeout * 1000000;
291 kdbus_source->timeout_time = 0;
298 * kdbus_source_finalize
302 kdbus_source_finalize (GSource *source)
304 GKdbusSource *kdbus_source = (GKdbusSource *)source;
307 kdbus = kdbus_source->kdbus;
309 g_object_unref (kdbus);
311 if (kdbus_source->cancellable)
313 g_cancellable_release_fd (kdbus_source->cancellable);
314 g_object_unref (kdbus_source->cancellable);
320 * kdbus_source_closure_callback:
324 kdbus_source_closure_callback (GKdbus *kdbus,
325 GIOCondition condition,
328 GClosure *closure = data;
329 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
330 GValue result_value = G_VALUE_INIT;
333 g_value_init (&result_value, G_TYPE_BOOLEAN);
335 g_value_init (¶ms[0], G_TYPE_KDBUS);
336 g_value_set_object (¶ms[0], kdbus);
337 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
338 g_value_set_flags (¶ms[1], condition);
340 g_closure_invoke (closure, &result_value, 2, params, NULL);
342 result = g_value_get_boolean (&result_value);
343 g_value_unset (&result_value);
344 g_value_unset (¶ms[0]);
345 g_value_unset (¶ms[1]);
351 static GSourceFuncs kdbus_source_funcs =
353 kdbus_source_prepare,
355 kdbus_source_dispatch,
356 kdbus_source_finalize,
357 (GSourceFunc)kdbus_source_closure_callback,
366 kdbus_source_new (GKdbus *kdbus,
367 GIOCondition condition,
368 GCancellable *cancellable)
371 GKdbusSource *kdbus_source;
373 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
374 g_source_set_name (source, "GKdbus");
375 kdbus_source = (GKdbusSource *)source;
377 kdbus_source->kdbus = g_object_ref (kdbus);
378 kdbus_source->condition = condition;
380 if (g_cancellable_make_pollfd (cancellable,
381 &kdbus_source->cancel_pollfd))
383 kdbus_source->cancellable = g_object_ref (cancellable);
384 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
387 kdbus_source->pollfd.fd = kdbus->priv->fd;
388 kdbus_source->pollfd.events = condition;
389 kdbus_source->pollfd.revents = 0;
390 g_source_add_poll (source, &kdbus_source->pollfd);
392 if (kdbus->priv->timeout)
393 kdbus_source->timeout_time = g_get_monotonic_time ()
394 + kdbus->priv->timeout * 1000000;
396 kdbus_source->timeout_time = 0;
403 * _g_kdbus_create_source:
407 _g_kdbus_create_source (GKdbus *kdbus,
408 GIOCondition condition,
409 GCancellable *cancellable)
411 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
413 return kdbus_source_new (kdbus, condition, cancellable);
422 _g_kdbus_open (GKdbus *kdbus,
423 const gchar *address,
426 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
428 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
429 if (kdbus->priv->fd<0)
431 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
435 kdbus->priv->closed = FALSE;
446 g_kdbus_free_data (GKdbus *kdbus,
449 struct kdbus_cmd_free cmd;
455 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
464 * g_kdbus_translate_nameowner_flags:
468 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
469 guint64 *kdbus_flags)
475 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
476 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
478 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
479 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
481 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
482 new_flags |= KDBUS_NAME_QUEUE;
484 *kdbus_flags = new_flags;
493 _g_kdbus_close (GKdbus *kdbus,
498 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
500 if (kdbus->priv->closed)
505 res = close (kdbus->priv->fd);
512 g_set_error (error, G_IO_ERROR,
513 g_io_error_from_errno (errno),
514 _("Error closing kdbus fd: %s"),
521 kdbus->priv->closed = TRUE;
522 kdbus->priv->fd = -1;
529 * _g_kdbus_is_closed:
533 _g_kdbus_is_closed (GKdbus *kdbus)
535 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
537 return kdbus->priv->closed;
546 _g_kdbus_Hello (GIOStream *stream,
550 struct kdbus_cmd_hello *hello;
551 struct kdbus_item *item;
554 size_t size, conn_name_size;
556 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
558 conn_name = "gdbus-kdbus";
559 conn_name_size = strlen (conn_name);
561 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
562 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
564 hello = g_alloca0 (size);
565 hello->conn_flags = kdbus->priv->hello_flags;
566 hello->attach_flags = kdbus->priv->attach_flags;
568 hello->pool_size = KDBUS_POOL_SIZE;
571 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
572 item->type = KDBUS_ITEM_CONN_NAME;
573 memcpy (item->str, conn_name, conn_name_size+1);
574 item = KDBUS_ITEM_NEXT (item);
576 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
578 g_set_error (error, G_IO_ERROR,
579 g_io_error_from_errno (errno),
580 _("Failed to send HELLO: %s"),
585 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
586 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
588 g_set_error (error, G_IO_ERROR,
589 g_io_error_from_errno (errno),
595 if (hello->bus_flags > 0xFFFFFFFFULL)
597 g_set_error_literal (error,
600 _("Incompatible HELLO flags"));
604 memcpy (kdbus->priv->bus_id, hello->id128, 16);
606 kdbus->priv->unique_id = hello->id;
607 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
609 return g_variant_new ("(s)", kdbus->priv->unique_name);
614 * _g_kdbus_RequestName:
618 _g_kdbus_RequestName (GDBusConnection *connection,
620 GBusNameOwnerFlags flags,
625 struct kdbus_cmd_name *kdbus_name;
630 status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
632 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
635 g_set_error_literal (error,
637 G_DBUS_ERROR_IO_ERROR,
638 _("The connection is closed"));
642 if (!g_dbus_is_name (name))
646 G_DBUS_ERROR_INVALID_ARGS,
647 "Given bus name \"%s\" is not valid", name);
655 G_DBUS_ERROR_INVALID_ARGS,
656 "Cannot acquire a service starting with ':' such as \"%s\"", name);
660 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
662 len = strlen(name) + 1;
663 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
664 kdbus_name = g_alloca0 (size);
665 kdbus_name->size = size;
666 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
667 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
668 kdbus_name->flags = kdbus_flags;
669 memcpy (kdbus_name->items[0].str, name, len);
671 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
675 status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
676 else if (errno == EALREADY)
677 status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
680 g_set_error (error, G_IO_ERROR,
681 g_io_error_from_errno (errno),
682 _("Error while acquiring name: %s"),
688 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
689 status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
691 result = g_variant_new ("(u)", status);
698 * _g_kdbus_ReleaseName:
702 _g_kdbus_ReleaseName (GDBusConnection *connection,
708 struct kdbus_cmd_name *kdbus_name;
712 status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
714 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
717 g_set_error_literal (error,
719 G_DBUS_ERROR_IO_ERROR,
720 _("The connection is closed"));
724 if (!g_dbus_is_name (name))
728 G_DBUS_ERROR_INVALID_ARGS,
729 "Given bus name \"%s\" is not valid", name);
737 G_DBUS_ERROR_INVALID_ARGS,
738 "Cannot release a service starting with ':' such as \"%s\"", name);
742 len = strlen(name) + 1;
743 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
744 kdbus_name = g_alloca0 (size);
745 kdbus_name->size = size;
746 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
747 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
748 memcpy (kdbus_name->items[0].str, name, len);
750 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
754 status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
755 else if (errno == EADDRINUSE)
756 status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
759 g_set_error (error, G_IO_ERROR,
760 g_io_error_from_errno (errno),
761 _("Error while releasing name: %s"),
767 result = g_variant_new ("(u)", status);
778 _g_kdbus_GetBusId (GDBusConnection *connection,
786 result_str = g_string_new (NULL);
787 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
790 g_set_error_literal (error,
792 G_DBUS_ERROR_IO_ERROR,
793 _("The connection is closed"));
794 g_string_free (result_str, TRUE);
798 for (cnt=0; cnt<16; cnt++)
799 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
801 result = g_variant_new ("(s)", result_str->str);
802 g_string_free (result_str, TRUE);
809 * _g_kdbus_GetListNames:
813 _g_kdbus_GetListNames (GDBusConnection *connection,
814 guint list_name_type,
819 GVariantBuilder *builder;
821 struct kdbus_cmd_name_list cmd = {};
822 struct kdbus_name_list *name_list;
823 struct kdbus_cmd_name *name;
829 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
832 g_set_error_literal (error,
834 G_DBUS_ERROR_IO_ERROR,
835 _("The connection is closed"));
840 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
842 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
844 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
850 _("Error listing names"));
854 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
855 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
857 KDBUS_ITEM_FOREACH(name, name_list, names)
859 struct kdbus_item *item;
860 const gchar *item_name = "";
862 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
864 GString *unique_name;
866 unique_name = g_string_new (NULL);
867 g_string_printf (unique_name, ":1.%llu", name->owner_id);
868 g_variant_builder_add (builder, "s", unique_name->str);
869 g_string_free (unique_name,TRUE);
870 prev_id = name->owner_id;
873 KDBUS_ITEM_FOREACH(item, name, items)
874 if (item->type == KDBUS_ITEM_NAME)
875 item_name = item->str;
877 if (g_dbus_is_name (item_name))
878 g_variant_builder_add (builder, "s", item_name);
881 result = g_variant_new ("(as)", builder);
882 g_variant_builder_unref (builder);
884 g_kdbus_free_data (kdbus, cmd.offset);
890 * _g_kdbus_NameHasOwner_internal:
894 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
898 struct kdbus_cmd_conn_info *cmd;
902 if (g_dbus_is_unique_name(name))
904 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
905 cmd = g_alloca0 (size);
906 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
910 len = strlen(name) + 1;
911 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
912 cmd = g_alloca0 (size);
913 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
914 cmd->items[0].type = KDBUS_ITEM_NAME;
915 memcpy (cmd->items[0].str, name, len);
919 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
920 g_kdbus_free_data (kdbus, cmd->offset);
930 * _g_kdbus_GetListQueuedOwners:
934 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
940 GVariantBuilder *builder;
941 GString *unique_name;
944 struct kdbus_cmd_name_list cmd = {};
945 struct kdbus_name_list *name_list;
946 struct kdbus_cmd_name *kname;
948 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
951 g_set_error_literal (error,
953 G_DBUS_ERROR_IO_ERROR,
954 _("The connection is closed"));
958 if (!g_dbus_is_name (name))
962 G_DBUS_ERROR_INVALID_ARGS,
963 "Given bus name \"%s\" is not valid", name);
967 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
971 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
972 "Could not get owner of name '%s': no such name", name);
976 cmd.flags = KDBUS_NAME_LIST_QUEUED;
977 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
983 _("Error listing names"));
987 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
989 unique_name = g_string_new (NULL);
990 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
991 KDBUS_ITEM_FOREACH(kname, name_list, names)
993 struct kdbus_item *item;
994 const char *item_name = "";
996 KDBUS_ITEM_FOREACH(item, kname, items)
997 if (item->type == KDBUS_ITEM_NAME)
998 item_name = item->str;
1000 if (strcmp(item_name, name))
1003 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1004 g_variant_builder_add (builder, "s", item_name);
1007 result = g_variant_new ("(as)", builder);
1008 g_variant_builder_unref (builder);
1009 g_string_free (unique_name,TRUE);
1011 g_kdbus_free_data (kdbus, cmd.offset);
1017 * _g_kdbus_NameHasOwner:
1021 _g_kdbus_NameHasOwner (GDBusConnection *connection,
1028 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1031 g_set_error_literal (error,
1033 G_DBUS_ERROR_IO_ERROR,
1034 _("The connection is closed"));
1038 if (!g_dbus_is_name (name))
1042 G_DBUS_ERROR_INVALID_ARGS,
1043 "Given bus name \"%s\" is not valid", name);
1047 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1048 result = g_variant_new ("(b)", FALSE);
1050 result = g_variant_new ("(b)", TRUE);
1057 * g_kdbus_GetConnInfo_internal:
1061 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
1069 struct kdbus_cmd_conn_info *cmd;
1070 struct kdbus_conn_info *conn_info;
1071 struct kdbus_item *item;
1076 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1079 g_set_error_literal (error,
1081 G_DBUS_ERROR_IO_ERROR,
1082 _("The connection is closed"));
1086 if (!g_dbus_is_name (name))
1090 G_DBUS_ERROR_INVALID_ARGS,
1091 "Given bus name \"%s\" is not valid", name);
1095 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1099 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1100 "Could not get owner of name '%s': no such name", name);
1104 if (g_dbus_is_unique_name(name))
1106 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
1107 cmd = g_alloca0 (size);
1108 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1112 len = strlen(name) + 1;
1113 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
1114 cmd = g_alloca0 (size);
1115 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1116 cmd->items[0].type = KDBUS_ITEM_NAME;
1117 memcpy (cmd->items[0].str, name, len);
1120 cmd->flags = KDBUS_ATTACH_NAMES;
1123 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1128 G_DBUS_ERROR_FAILED,
1129 _("Could not get connection info"));
1133 conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1136 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1140 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1142 GString *unique_name;
1144 unique_name = g_string_new (NULL);
1145 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1146 result = g_variant_new ("(s)", unique_name->str);
1147 g_string_free (unique_name,TRUE);
1151 KDBUS_ITEM_FOREACH(item, conn_info, items)
1155 case KDBUS_ITEM_CREDS:
1157 if (flag == G_BUS_CREDS_PID)
1159 guint pid = item->creds.pid;
1160 result = g_variant_new ("(u)", pid);
1164 if (flag == G_BUS_CREDS_UID)
1166 guint uid = item->creds.uid;
1167 result = g_variant_new ("(u)", uid);
1171 case KDBUS_ITEM_SECLABEL:
1172 case KDBUS_ITEM_PID_COMM:
1173 case KDBUS_ITEM_TID_COMM:
1174 case KDBUS_ITEM_EXE:
1175 case KDBUS_ITEM_CMDLINE:
1176 case KDBUS_ITEM_CGROUP:
1177 case KDBUS_ITEM_CAPS:
1178 case KDBUS_ITEM_NAME:
1179 case KDBUS_ITEM_AUDIT:
1185 g_kdbus_free_data (kdbus, cmd->offset);
1191 * _g_kdbus_GetNameOwner:
1195 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1199 return g_kdbus_GetConnInfo_internal (connection,
1201 G_BUS_CREDS_UNIQUE_NAME,
1207 * _g_kdbus_GetConnectionUnixProcessID:
1211 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1215 return g_kdbus_GetConnInfo_internal (connection,
1223 * _g_kdbus_GetConnectionUnixUser:
1227 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1231 return g_kdbus_GetConnInfo_internal (connection,
1239 * _g_kdbus_subscribe_name_acquired:
1243 _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
1245 const gchar *old_name,
1246 const gchar *new_name,
1250 struct kdbus_item *item;
1251 struct kdbus_cmd_match *cmd_match;
1255 guint64 new_id = KDBUS_MATCH_ID_ANY;
1257 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1259 len = strlen(name) + 1;
1260 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1261 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1262 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1264 cmd_match = g_alloca0 (size);
1265 cmd_match->size = size;
1266 cmd_match->cookie = cookie;
1267 item = cmd_match->items;
1269 if (old_name[0] == 0)
1271 old_id = KDBUS_MATCH_ID_ANY;
1275 if (g_dbus_is_unique_name(old_name))
1281 if (new_name[0] == 0)
1283 new_id = KDBUS_MATCH_ID_ANY;
1287 if (g_dbus_is_unique_name(new_name))
1293 cmd_match = g_alloca0 (size);
1294 cmd_match->size = size;
1295 cmd_match->cookie = cookie;
1296 item = cmd_match->items;
1298 /* KDBUS_ITEM_NAME_CHANGE */
1299 item->type = KDBUS_ITEM_NAME_CHANGE;
1300 item->name_change.old_id.id = old_id;
1301 item->name_change.new_id.id = new_id;
1302 memcpy(item->name_change.name, name, len);
1303 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1304 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1305 item = KDBUS_ITEM_NEXT(item);
1307 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1309 g_warning ("ERROR - %d\n", (int) errno);
1314 * _g_kdbus_subscribe_name_acquired:
1318 _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
1322 struct kdbus_item *item;
1323 struct kdbus_cmd_match *cmd_match;
1328 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1330 len = strlen(name) + 1;
1331 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1332 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1333 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1335 cookie = 0xbeefbeefbeefbeef;
1336 cmd_match = g_alloca0 (size);
1337 cmd_match->size = size;
1338 cmd_match->cookie = cookie;
1339 item = cmd_match->items;
1341 /* KDBUS_ITEM_NAME_ADD */
1342 item->type = KDBUS_ITEM_NAME_ADD;
1343 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1344 item->name_change.new_id.id = kdbus->priv->unique_id;
1345 memcpy(item->name_change.name, name, len);
1346 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1347 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1348 item = KDBUS_ITEM_NEXT(item);
1350 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1352 g_warning ("ERROR - %d\n", (int) errno);
1354 _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1359 * _g_kdbus_subscribe_name_lost:
1363 _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
1367 struct kdbus_item *item;
1368 struct kdbus_cmd_match *cmd_match;
1373 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1375 len = strlen(name) + 1;
1376 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1377 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1378 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1380 cookie = 0xdeafdeafdeafdeaf;
1381 cmd_match = g_alloca0 (size);
1382 cmd_match->size = size;
1383 cmd_match->cookie = cookie;
1384 item = cmd_match->items;
1386 /* KDBUS_ITEM_NAME_REMOVE */
1387 item->type = KDBUS_ITEM_NAME_REMOVE;
1388 item->name_change.old_id.id = kdbus->priv->unique_id;
1389 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1390 memcpy(item->name_change.name, name, len);
1391 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1392 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1393 item = KDBUS_ITEM_NEXT(item);
1395 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1397 g_warning ("ERROR - %d\n", (int) errno);
1399 _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1404 * g_kdbus_decode_kernel_msg:
1408 g_kdbus_decode_kernel_msg (GKdbus *kdbus)
1410 struct kdbus_item *item = NULL;
1413 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1417 case KDBUS_ITEM_ID_ADD:
1418 case KDBUS_ITEM_ID_REMOVE:
1419 case KDBUS_ITEM_NAME_ADD:
1420 case KDBUS_ITEM_NAME_REMOVE:
1421 case KDBUS_ITEM_NAME_CHANGE:
1422 //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1423 g_error ("'NameOwnerChanged'");
1426 case KDBUS_ITEM_REPLY_TIMEOUT:
1427 case KDBUS_ITEM_REPLY_DEAD:
1428 //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1429 g_error ("'KernelMethodError'");
1433 g_warning ("Unknown field in kernel message - %lld", item->type);
1438 /* Override information from the user header with data from the kernel */
1439 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1441 /* for destination */
1442 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1443 /* for broadcast messages we don't have to set destination */
1445 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1446 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1448 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1460 _g_kdbus_receive (GKdbus *kdbus,
1461 GCancellable *cancellable,
1464 struct kdbus_cmd_recv recv = {};
1467 if (g_cancellable_set_error_if_cancelled (cancellable, error))
1471 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1473 if (errno == EINTR || errno == EAGAIN)
1476 g_set_error (error, G_IO_ERROR,
1477 g_io_error_from_errno (errno),
1478 _("Error while receiving message: %s"),
1479 g_strerror (errno));
1483 kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
1485 if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
1486 g_error ("Received standard dbus message - not supported yet");
1487 else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
1488 size = g_kdbus_decode_kernel_msg (kdbus);
1493 G_DBUS_ERROR_FAILED,
1494 _("Received unknown payload type"));