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 */
101 /* GKdbusSource struct */
106 GIOCondition condition;
107 GCancellable *cancellable;
108 GPollFD cancel_pollfd;
113 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
114 GIOCondition condition,
122 g_kdbus_finalize (GObject *object)
124 GKdbus *kdbus = G_KDBUS (object);
126 if (kdbus->priv->kdbus_buffer != NULL)
127 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
129 kdbus->priv->kdbus_buffer = NULL;
131 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
132 _g_kdbus_close (kdbus, NULL);
134 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
135 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
140 * g_kdbus_class_init:
144 g_kdbus_class_init (GKdbusClass *klass)
146 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
148 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
149 gobject_class->finalize = g_kdbus_finalize;
154 * g_kdbus_initable_iface_init:
158 g_kdbus_initable_iface_init (GInitableIface *iface)
160 iface->init = g_kdbus_initable_init;
169 g_kdbus_init (GKdbus *kdbus)
171 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
173 kdbus->priv->fd = -1;
175 kdbus->priv->unique_id = -1;
176 kdbus->priv->unique_name = NULL;
178 kdbus->priv->kdbus_buffer = NULL;
180 kdbus->priv->hello_flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
181 kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
186 * g_kdbus_initable_init:
190 g_kdbus_initable_init (GInitable *initable,
191 GCancellable *cancellable,
196 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
198 kdbus = G_KDBUS (initable);
200 if (cancellable != NULL)
202 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
203 _("Cancellable initialization not supported"));
207 kdbus->priv->inited = TRUE;
214 * kdbus_source_prepare:
218 kdbus_source_prepare (GSource *source,
221 GKdbusSource *kdbus_source = (GKdbusSource *)source;
223 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
226 if (kdbus_source->timeout_time)
230 now = g_source_get_time (source);
232 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
235 kdbus_source->kdbus->priv->timed_out = TRUE;
243 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
251 * kdbus_source_check:
255 kdbus_source_check (GSource *source)
259 return kdbus_source_prepare (source, &timeout);
264 * kdbus_source_dispatch
268 kdbus_source_dispatch (GSource *source,
269 GSourceFunc callback,
272 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
273 GKdbusSource *kdbus_source = (GKdbusSource *)source;
274 GKdbus *kdbus = kdbus_source->kdbus;
277 if (kdbus_source->kdbus->priv->timed_out)
278 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
280 ret = (*func) (kdbus,
281 kdbus_source->pollfd.revents & kdbus_source->condition,
284 if (kdbus->priv->timeout)
285 kdbus_source->timeout_time = g_get_monotonic_time ()
286 + kdbus->priv->timeout * 1000000;
289 kdbus_source->timeout_time = 0;
296 * kdbus_source_finalize
300 kdbus_source_finalize (GSource *source)
302 GKdbusSource *kdbus_source = (GKdbusSource *)source;
305 kdbus = kdbus_source->kdbus;
307 g_object_unref (kdbus);
309 if (kdbus_source->cancellable)
311 g_cancellable_release_fd (kdbus_source->cancellable);
312 g_object_unref (kdbus_source->cancellable);
318 * kdbus_source_closure_callback:
322 kdbus_source_closure_callback (GKdbus *kdbus,
323 GIOCondition condition,
326 GClosure *closure = data;
327 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
328 GValue result_value = G_VALUE_INIT;
331 g_value_init (&result_value, G_TYPE_BOOLEAN);
333 g_value_init (¶ms[0], G_TYPE_KDBUS);
334 g_value_set_object (¶ms[0], kdbus);
335 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
336 g_value_set_flags (¶ms[1], condition);
338 g_closure_invoke (closure, &result_value, 2, params, NULL);
340 result = g_value_get_boolean (&result_value);
341 g_value_unset (&result_value);
342 g_value_unset (¶ms[0]);
343 g_value_unset (¶ms[1]);
349 static GSourceFuncs kdbus_source_funcs =
351 kdbus_source_prepare,
353 kdbus_source_dispatch,
354 kdbus_source_finalize,
355 (GSourceFunc)kdbus_source_closure_callback,
364 kdbus_source_new (GKdbus *kdbus,
365 GIOCondition condition,
366 GCancellable *cancellable)
369 GKdbusSource *kdbus_source;
371 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
372 g_source_set_name (source, "GKdbus");
373 kdbus_source = (GKdbusSource *)source;
375 kdbus_source->kdbus = g_object_ref (kdbus);
376 kdbus_source->condition = condition;
378 if (g_cancellable_make_pollfd (cancellable,
379 &kdbus_source->cancel_pollfd))
381 kdbus_source->cancellable = g_object_ref (cancellable);
382 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
385 kdbus_source->pollfd.fd = kdbus->priv->fd;
386 kdbus_source->pollfd.events = condition;
387 kdbus_source->pollfd.revents = 0;
388 g_source_add_poll (source, &kdbus_source->pollfd);
390 if (kdbus->priv->timeout)
391 kdbus_source->timeout_time = g_get_monotonic_time ()
392 + kdbus->priv->timeout * 1000000;
394 kdbus_source->timeout_time = 0;
401 * _g_kdbus_create_source:
405 _g_kdbus_create_source (GKdbus *kdbus,
406 GIOCondition condition,
407 GCancellable *cancellable)
409 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
411 return kdbus_source_new (kdbus, condition, cancellable);
420 _g_kdbus_open (GKdbus *kdbus,
421 const gchar *address,
424 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
426 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
427 if (kdbus->priv->fd<0)
429 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
433 kdbus->priv->closed = FALSE;
440 * _g_kdbus_free_data:
444 g_kdbus_free_data (GKdbus *kdbus,
447 struct kdbus_cmd_free cmd;
453 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
466 _g_kdbus_close (GKdbus *kdbus,
471 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
473 if (kdbus->priv->closed)
478 res = close (kdbus->priv->fd);
485 g_set_error (error, G_IO_ERROR,
486 g_io_error_from_errno (errno),
487 _("Error closing kdbus fd: %s"),
494 kdbus->priv->closed = TRUE;
495 kdbus->priv->fd = -1;
502 * _g_kdbus_is_closed:
506 _g_kdbus_is_closed (GKdbus *kdbus)
508 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
510 return kdbus->priv->closed;
519 _g_kdbus_Hello (GIOStream *stream,
523 struct kdbus_cmd_hello *hello;
524 struct kdbus_item *item;
527 size_t size, conn_name_size;
529 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
531 conn_name = "gdbus-kdbus";
532 conn_name_size = strlen (conn_name);
534 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
535 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
537 hello = g_alloca0 (size);
538 hello->conn_flags = kdbus->priv->hello_flags;
539 hello->attach_flags = kdbus->priv->attach_flags;
541 hello->pool_size = KDBUS_POOL_SIZE;
544 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
545 item->type = KDBUS_ITEM_CONN_NAME;
546 memcpy (item->str, conn_name, conn_name_size+1);
547 item = KDBUS_ITEM_NEXT (item);
549 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
551 g_set_error (error, G_IO_ERROR,
552 g_io_error_from_errno (errno),
553 _("Failed to send HELLO: %s"),
558 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
559 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
561 g_set_error (error, G_IO_ERROR,
562 g_io_error_from_errno (errno),
568 if (hello->bus_flags > 0xFFFFFFFFULL)
570 g_set_error_literal (error,
573 _("Incompatible HELLO flags"));
577 memcpy (kdbus->priv->bus_id, hello->id128, 16);
579 kdbus->priv->unique_id = hello->id;
580 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
582 return g_variant_new ("(s)", kdbus->priv->unique_name);
591 _g_kdbus_GetBusId (GDBusConnection *connection,
599 result_str = g_string_new (NULL);
600 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
603 g_set_error_literal (error,
605 G_DBUS_ERROR_IO_ERROR,
606 _("The connection is closed"));
607 g_string_free (result_str, TRUE);
611 for (cnt=0; cnt<16; cnt++)
612 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
614 result = g_variant_new ("(s)", result_str->str);
615 g_string_free (result_str, TRUE);
622 * _g_kdbus_GetListNames:
626 _g_kdbus_GetListNames (GDBusConnection *connection,
627 guint list_name_type,
632 GVariantBuilder *builder;
634 struct kdbus_cmd_name_list cmd = {};
635 struct kdbus_name_list *name_list;
636 struct kdbus_cmd_name *name;
642 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
645 g_set_error_literal (error,
647 G_DBUS_ERROR_IO_ERROR,
648 _("The connection is closed"));
653 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
655 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
657 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
663 _("Error listing names"));
667 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
668 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
670 KDBUS_ITEM_FOREACH(name, name_list, names)
672 struct kdbus_item *item;
673 const gchar *item_name = "";
675 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
677 GString *unique_name;
679 unique_name = g_string_new (NULL);
680 g_string_printf (unique_name, ":1.%llu", name->owner_id);
681 g_variant_builder_add (builder, "s", unique_name->str);
682 g_string_free (unique_name,TRUE);
683 prev_id = name->owner_id;
686 KDBUS_ITEM_FOREACH(item, name, items)
687 if (item->type == KDBUS_ITEM_NAME)
688 item_name = item->str;
690 if (g_dbus_is_name (item_name))
691 g_variant_builder_add (builder, "s", item_name);
694 result = g_variant_new ("(as)", builder);
695 g_variant_builder_unref (builder);
697 g_kdbus_free_data (kdbus, cmd.offset);
703 * _g_kdbus_NameHasOwner_internal:
707 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
711 struct kdbus_cmd_conn_info *cmd;
715 if (g_dbus_is_unique_name(name))
717 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
718 cmd = g_alloca0 (size);
719 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
723 len = strlen(name) + 1;
724 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
725 cmd = g_alloca0 (size);
726 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
727 cmd->items[0].type = KDBUS_ITEM_NAME;
728 memcpy (cmd->items[0].str, name, len);
732 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
733 g_kdbus_free_data (kdbus, cmd->offset);
743 * _g_kdbus_GetListQueuedOwners:
747 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
753 GVariantBuilder *builder;
754 GString *unique_name;
757 struct kdbus_cmd_name_list cmd = {};
758 struct kdbus_name_list *name_list;
759 struct kdbus_cmd_name *kname;
761 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
764 g_set_error_literal (error,
766 G_DBUS_ERROR_IO_ERROR,
767 _("The connection is closed"));
771 if (!g_dbus_is_name (name))
775 G_DBUS_ERROR_INVALID_ARGS,
776 "Given bus name \"%s\" is not valid", name);
780 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
784 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
785 "Could not get owner of name '%s': no such name", name);
789 cmd.flags = KDBUS_NAME_LIST_QUEUED;
790 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
796 _("Error listing names"));
800 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
802 unique_name = g_string_new (NULL);
803 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
804 KDBUS_ITEM_FOREACH(kname, name_list, names)
806 struct kdbus_item *item;
807 const char *item_name = "";
809 KDBUS_ITEM_FOREACH(item, kname, items)
810 if (item->type == KDBUS_ITEM_NAME)
811 item_name = item->str;
813 if (strcmp(item_name, name))
816 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
817 g_variant_builder_add (builder, "s", item_name);
820 result = g_variant_new ("(as)", builder);
821 g_variant_builder_unref (builder);
822 g_string_free (unique_name,TRUE);
824 g_kdbus_free_data (kdbus, cmd.offset);
830 * _g_kdbus_NameHasOwner:
834 _g_kdbus_NameHasOwner (GDBusConnection *connection,
841 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
844 g_set_error_literal (error,
846 G_DBUS_ERROR_IO_ERROR,
847 _("The connection is closed"));
851 if (!g_dbus_is_name (name))
855 G_DBUS_ERROR_INVALID_ARGS,
856 "Given bus name \"%s\" is not valid", name);
860 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
861 result = g_variant_new ("(b)", FALSE);
863 result = g_variant_new ("(b)", TRUE);
870 * g_kdbus_GetConnInfo_internal:
874 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
882 struct kdbus_cmd_conn_info *cmd;
883 struct kdbus_conn_info *conn_info;
884 struct kdbus_item *item;
889 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
892 g_set_error_literal (error,
894 G_DBUS_ERROR_IO_ERROR,
895 _("The connection is closed"));
899 if (!g_dbus_is_name (name))
903 G_DBUS_ERROR_INVALID_ARGS,
904 "Given bus name \"%s\" is not valid", name);
908 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
912 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
913 "Could not get owner of name '%s': no such name", name);
917 if (g_dbus_is_unique_name(name))
919 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
920 cmd = g_alloca0 (size);
921 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
925 len = strlen(name) + 1;
926 size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
927 cmd = g_alloca0 (size);
928 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
929 cmd->items[0].type = KDBUS_ITEM_NAME;
930 memcpy (cmd->items[0].str, name, len);
933 cmd->flags = KDBUS_ATTACH_NAMES;
936 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
942 _("Could not get connection info"));
946 conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
949 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
953 if (flag == G_BUS_CREDS_UNIQUE_NAME)
955 GString *unique_name;
957 unique_name = g_string_new (NULL);
958 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
959 result = g_variant_new ("(s)", unique_name->str);
960 g_string_free (unique_name,TRUE);
964 KDBUS_ITEM_FOREACH(item, conn_info, items)
968 case KDBUS_ITEM_CREDS:
970 if (flag == G_BUS_CREDS_PID)
972 guint pid = item->creds.pid;
973 result = g_variant_new ("(u)", pid);
977 if (flag == G_BUS_CREDS_UID)
979 guint uid = item->creds.uid;
980 result = g_variant_new ("(u)", uid);
984 case KDBUS_ITEM_SECLABEL:
985 case KDBUS_ITEM_PID_COMM:
986 case KDBUS_ITEM_TID_COMM:
988 case KDBUS_ITEM_CMDLINE:
989 case KDBUS_ITEM_CGROUP:
990 case KDBUS_ITEM_CAPS:
991 case KDBUS_ITEM_NAME:
992 case KDBUS_ITEM_AUDIT:
998 g_kdbus_free_data (kdbus, cmd->offset);
1004 * _g_kdbus_GetNameOwner:
1008 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1012 return g_kdbus_GetConnInfo_internal (connection,
1014 G_BUS_CREDS_UNIQUE_NAME,
1020 * _g_kdbus_GetConnectionUnixProcessID:
1024 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1028 return g_kdbus_GetConnInfo_internal (connection,
1036 * _g_kdbus_GetConnectionUnixUser:
1040 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1044 return g_kdbus_GetConnInfo_internal (connection,