[glib/tizen/kdbus-dev] kdbus stuff
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/tizen/kdbus-dev] kdbus stuff
- Date: Wed, 6 Nov 2013 20:06:30 +0000 (UTC)
commit f826363e4bdb9ffc90903a1b5a4d7ce47177aada
Author: Ryan Lortie <desrt desrt ca>
Date: Wed Nov 6 14:53:47 2013 -0500
kdbus stuff
configure.ac | 10 +
gio/Makefile.am | 4 +
gio/gdbusaddress.c | 71 +++-
gio/gdbusconnection.c | 95 ++++--
gio/gdbusprivate.c | 425 +++++++++++++++++-------
gio/gdbusprivate.h | 4 +-
gio/gdbusserver.c | 16 +
gio/gdesktopappinfo.c | 2 +
gio/giotypes.h | 33 ++
gio/gkdbus.c | 887 ++++++++++++++++++++++++++++++++++++++++++++++++
gio/gkdbus.h | 113 ++++++
gio/gkdbusconnection.c | 206 +++++++++++
gio/gkdbusconnection.h | 91 +++++
gio/kdbus.h | 445 ++++++++++++++++++++++++
glib/gmain.c | 9 +-
15 files changed, 2233 insertions(+), 178 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index e61fd9e..6a268e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,10 @@ AC_ARG_ENABLE(gc_friendly,
[AS_HELP_STRING([--enable-gc-friendly],
[turn on garbage collector friendliness [default=no]])],,
[enable_gc_friendly=no])
+AC_ARG_ENABLE(kdbus_transport,
+ [AS_HELP_STRING([--enable-kdbus-transport],
+ [enable kdbus transport [default=no]])],,
+ [enable_kdbus_transport=no])
AC_ARG_ENABLE(mem_pools,
[AS_HELP_STRING([--disable-mem-pools],
[disable all glib memory pools])],,
@@ -255,6 +259,12 @@ AS_IF([test "x$enable_gc_friendly" = "xyes"], [
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no]) ])
+AC_MSG_CHECKING([kdbus transport])
+AS_IF([test "x$enable_kdbus_transport" = "xyes"], [
+ AC_MSG_RESULT([yes])
+ CFLAGS="$CFLAGS -DKDBUS_TRANSPORT"
+], [ AC_MSG_RESULT([no]) ])
+
AC_MSG_CHECKING([whether to disable memory pools])
AS_IF([test "x$disable_mem_pools" = "xno"], [
AC_MSG_RESULT([no])
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 94d7f59..bd18e3a 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -384,6 +384,8 @@ libgio_2_0_la_SOURCES = \
giomodule-priv.h \
gioscheduler.c \
giostream.c \
+ gkdbus.c \
+ gkdbusconnection.c \
gloadableicon.c \
gmount.c \
gmemoryinputstream.c \
@@ -555,6 +557,8 @@ gio_headers = \
giomodule.h \
gioscheduler.h \
giostream.h \
+ gkdbus.h \
+ gkdbusconnection.h \
gloadableicon.h \
gmount.h \
gmemoryinputstream.h \
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index cc9703c..970b36f 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -44,6 +44,9 @@
#ifdef G_OS_UNIX
#include <gio/gunixsocketaddress.h>
+#ifdef KDBUS_TRANSPORT
+#include <gio/gkdbusconnection.h>
+#endif
#endif
#ifdef G_OS_WIN32
@@ -401,7 +404,11 @@ g_dbus_is_supported_address (const gchar *string,
goto out;
supported = FALSE;
- if (g_strcmp0 (transport_name, "unix") == 0)
+ if ((g_strcmp0 (transport_name, "unix") == 0)
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ || (g_strcmp0 (transport_name, "kdbus") == 0)
+#endif
+ )
supported = is_valid_unix (a[n], key_value_pairs, error);
else if (g_strcmp0 (transport_name, "tcp") == 0)
supported = is_valid_tcp (a[n], key_value_pairs, error);
@@ -553,7 +560,11 @@ g_dbus_address_connect (const gchar *address_entry,
{
}
#ifdef G_OS_UNIX
- else if (g_strcmp0 (transport_name, "unix") == 0)
+ else if ((g_strcmp0 (transport_name, "unix") == 0)
+#ifdef KDBUS_TRANSPORT
+ || (g_strcmp0 (transport_name, "kdbus") == 0)
+#endif
+ )
{
const gchar *path;
const gchar *abstract;
@@ -664,21 +675,47 @@ g_dbus_address_connect (const gchar *address_entry,
if (connectable != NULL)
{
- GSocketClient *client;
- GSocketConnection *connection;
-
- g_assert (ret == NULL);
- client = g_socket_client_new ();
- connection = g_socket_client_connect (client,
- connectable,
- cancellable,
- error);
- g_object_unref (connectable);
- g_object_unref (client);
- if (connection == NULL)
- goto out;
-
- ret = G_IO_STREAM (connection);
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (g_strcmp0 (transport_name, "kdbus") == 0)
+ {
+ GKdbusConnection *connection;
+
+ const gchar *path;
+ path = g_hash_table_lookup (key_value_pairs, "path");
+
+ g_assert (ret == NULL);
+ connection = g_kdbus_connection_new ();
+ g_kdbus_connection_connect (connection,
+ path,
+ cancellable,
+ error);
+ g_object_unref (connectable);
+ if (connection == NULL)
+ goto out;
+
+ ret = G_IO_STREAM (connection);
+ }
+ else
+ {
+#endif
+ GSocketClient *client;
+ GSocketConnection *connection;
+
+ g_assert (ret == NULL);
+ client = g_socket_client_new ();
+ connection = g_socket_client_connect (client,
+ connectable,
+ cancellable,
+ error);
+ g_object_unref (connectable);
+ g_object_unref (client);
+ if (connection == NULL)
+ goto out;
+
+ ret = G_IO_STREAM (connection);
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ }
+#endif
if (nonce_file != NULL)
{
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index f4c63a9..13f5493 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -128,6 +128,9 @@
#include "gsimpleasyncresult.h"
#ifdef G_OS_UNIX
+#ifdef KDBUS_TRANSPORT
+#include "gkdbusconnection.h"
+#endif
#include "gunixconnection.h"
#include "gunixfdmessage.h"
#endif
@@ -1647,6 +1650,18 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
error))
goto out;
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (connection->stream)){
+ if ((connection->bus_unique_name) != NULL)
+ {
+ g_dbus_message_set_sender(message, connection->bus_unique_name);
+ #ifdef KDBUS_TRANSPORT_DEBUG
+ g_print (" KDBUS_TRANSPORT_DEBUG: (%s()): set_sender ok!\n",__FUNCTION__);
+ #endif
+ }
+ }
+#endif
+
blob = g_dbus_message_to_blob (message,
&blob_size,
connection->capabilities,
@@ -2578,45 +2593,51 @@ initable_init (GInitable *initable,
{
g_assert_not_reached ();
}
-
- /* Authenticate the connection */
- if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER)
- {
- g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT));
- g_assert (connection->guid != NULL);
- connection->auth = _g_dbus_auth_new (connection->stream);
- if (!_g_dbus_auth_run_server (connection->auth,
- connection->authentication_observer,
- connection->guid,
- (connection->flags &
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS),
- get_offered_capabilities_max (connection),
- &connection->capabilities,
- &connection->credentials,
- cancellable,
- &connection->initialization_error))
- goto out;
- }
- else if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT)
- {
- g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER));
- g_assert (connection->guid == NULL);
- connection->auth = _g_dbus_auth_new (connection->stream);
- connection->guid = _g_dbus_auth_run_client (connection->auth,
- connection->authentication_observer,
- get_offered_capabilities_max (connection),
- &connection->capabilities,
- cancellable,
- &connection->initialization_error);
- if (connection->guid == NULL)
- goto out;
- }
-
- if (connection->authentication_observer != NULL)
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ /* TODO: [KDBUS] Our kdbus daemon doesn't support connection authentication */
+ if (!G_IS_KDBUS_CONNECTION (connection->stream))
{
- g_object_unref (connection->authentication_observer);
- connection->authentication_observer = NULL;
- }
+#endif
+ /* Authenticate the connection */
+ if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER)
+ {
+ g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT));
+ g_assert (connection->guid != NULL);
+ connection->auth = _g_dbus_auth_new (connection->stream);
+ if (!_g_dbus_auth_run_server (connection->auth,
+ connection->authentication_observer,
+ connection->guid,
+ (connection->flags &
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS),
+ get_offered_capabilities_max (connection),
+ &connection->capabilities,
+ &connection->credentials,
+ cancellable,
+ &connection->initialization_error))
+ goto out;
+ }
+ else if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT)
+ {
+ g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER));
+ g_assert (connection->guid == NULL);
+ connection->auth = _g_dbus_auth_new (connection->stream);
+ connection->guid = _g_dbus_auth_run_client (connection->auth,
+ connection->authentication_observer,
+ get_offered_capabilities_max (connection),
+ &connection->capabilities,
+ cancellable,
+ &connection->initialization_error);
+ if (connection->guid == NULL)
+ goto out;
+ }
+ if (connection->authentication_observer != NULL)
+ {
+ g_object_unref (connection->authentication_observer);
+ connection->authentication_observer = NULL;
+ }
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ }
+#endif
//g_output_stream_flush (G_SOCKET_CONNECTION (connection->stream)
//g_debug ("haz unix fd passing powers: %d", connection->capabilities &
G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 0e5bef2..c01de77 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -45,6 +45,9 @@
#include "gsocketoutputstream.h"
#ifdef G_OS_UNIX
+#ifdef KDBUS_TRANSPORT
+#include "gkdbusconnection.h"
+#endif
#include "gunixfdmessage.h"
#include "gunixconnection.h"
#include "gunixcredentialsmessage.h"
@@ -117,6 +120,63 @@ typedef struct
gboolean from_mainloop;
} ReadWithControlData;
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+typedef struct
+{
+ GKdbus *kdbus;
+ GCancellable *cancellable;
+
+ void *buffer;
+ gsize count;
+
+ GSimpleAsyncResult *simple;
+
+ gboolean from_mainloop;
+} ReadKdbusData;
+
+static void
+read_kdbus_data_free (ReadKdbusData *data)
+{
+ g_object_unref (data->kdbus);
+ if (data->cancellable != NULL)
+ g_object_unref (data->cancellable);
+ g_object_unref (data->simple);
+ g_free (data);
+}
+
+static gboolean
+_g_kdbus_read_ready (GKdbus *kdbus,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ ReadKdbusData *data = user_data;
+ GError *error;
+ gssize result;
+
+ error = NULL;
+
+ result = g_kdbus_receive (data->kdbus,
+ data->buffer,
+ &error);
+ if (result >= 0)
+ {
+ g_simple_async_result_set_op_res_gssize (data->simple, result);
+ }
+ else
+ {
+ g_assert (error != NULL);
+ g_simple_async_result_take_error (data->simple, error);
+ }
+
+ if (data->from_mainloop)
+ g_simple_async_result_complete (data->simple);
+ else
+ g_simple_async_result_complete_in_idle (data->simple);
+
+ return FALSE;
+}
+#endif
+
static void
read_with_control_data_free (ReadWithControlData *data)
{
@@ -167,6 +227,43 @@ _g_socket_read_with_control_messages_ready (GSocket *socket,
return FALSE;
}
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+static void
+_g_kdbus_read (GKdbus *kdbus,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ReadKdbusData *data;
+ GSource *source;
+
+ data = g_new0 (ReadKdbusData, 1);
+ data->kdbus = g_object_ref (kdbus);
+ data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+ data->buffer = buffer;
+ data->count = count;
+
+ data->simple = g_simple_async_result_new (G_OBJECT (kdbus),
+ callback,
+ user_data,
+ _g_kdbus_read);
+ g_simple_async_result_set_check_cancellable (data->simple, cancellable);
+
+ data->from_mainloop = TRUE;
+ source = g_kdbus_create_source (data->kdbus,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ cancellable);
+ g_source_set_callback (source,
+ (GSourceFunc) _g_kdbus_read_ready,
+ data,
+ (GDestroyNotify) read_kdbus_data_free);
+ g_source_attach (source, g_main_context_get_thread_default ());
+ g_source_unref (source);
+}
+#endif
+
static void
_g_socket_read_with_control_messages (GSocket *socket,
void *buffer,
@@ -215,6 +312,24 @@ _g_socket_read_with_control_messages (GSocket *socket,
}
}
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+static gssize
+_g_kdbus_read_finish (GKdbus *kdbus,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == _g_kdbus_read);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return -1;
+ else
+ return g_simple_async_result_get_op_res_gssize (simple);
+}
+#endif
+
static gssize
_g_socket_read_with_control_messages_finish (GSocket *socket,
GAsyncResult *result,
@@ -364,8 +479,11 @@ struct GDBusWorker
GDBusWorkerDisconnectedCallback disconnected_callback;
gpointer user_data;
- /* if not NULL, stream is GSocketConnection */
+ /* if GSocket and GKdbus are NULL, stream is GSocketConnection */
GSocket *socket;
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ GKdbus *kdbus;
+#endif
/* used for reading */
GMutex read_lock;
@@ -506,7 +624,7 @@ _g_dbus_worker_emit_message_about_to_be_sent (GDBusWorker *worker,
}
/* can only be called from private thread with read-lock held - takes ownership of @message */
-static void
+void
_g_dbus_worker_queue_or_deliver_received_message (GDBusWorker *worker,
GDBusMessage *message)
{
@@ -584,7 +702,16 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
goto out;
error = NULL;
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ {
+ bytes_read = _g_kdbus_read_finish (worker->kdbus,
+ res,
+ &error);
+ } else if (worker->socket == NULL)
+#else
if (worker->socket == NULL)
+#endif
bytes_read = g_input_stream_read_finish (g_io_stream_get_input_stream (worker->stream),
res,
&error);
@@ -722,6 +849,13 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
read_message_print_transport_debug (bytes_read, worker);
worker->read_buffer_cur_size += bytes_read;
+
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ /* For KDBUS transport we don't have to read message header */
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ worker->read_buffer_bytes_wanted = worker->read_buffer_cur_size;
+#endif
+
if (worker->read_buffer_bytes_wanted == worker->read_buffer_cur_size)
{
/* OK, got what we asked for! */
@@ -841,12 +975,38 @@ _g_dbus_worker_do_read_unlocked (GDBusWorker *worker)
/* ensure we have a (big enough) buffer */
if (worker->read_buffer == NULL || worker->read_buffer_bytes_wanted > worker->read_buffer_allocated_size)
{
- /* TODO: 4096 is randomly chosen; might want a better chosen default minimum */
- worker->read_buffer_allocated_size = MAX (worker->read_buffer_bytes_wanted, 4096);
- worker->read_buffer = g_realloc (worker->read_buffer, worker->read_buffer_allocated_size);
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ {
+ /* For KDBUS transport we have to alloc buffer only once - DBUS_MAXIMUM_MESSAGE_LENGTH=2^27 */
+ worker->read_buffer_allocated_size = MAX (worker->read_buffer_bytes_wanted, 134217728);
+ worker->read_buffer = g_realloc (worker->read_buffer, worker->read_buffer_allocated_size);
+ }
+ else
+ {
+#endif
+ /* TODO: 4096 is randomly chosen; might want a better chosen default minimum */
+ worker->read_buffer_allocated_size = MAX (worker->read_buffer_bytes_wanted, 4096);
+ worker->read_buffer = g_realloc (worker->read_buffer, worker->read_buffer_allocated_size);
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ }
+#endif
}
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ {
+ _g_kdbus_read(worker->kdbus,
+ worker->read_buffer,
+ worker->read_buffer_bytes_wanted,
+ worker->cancellable,
+ (GAsyncReadyCallback) _g_dbus_worker_do_read_cb,
+ _g_dbus_worker_ref (worker));
+
+ } else if (worker->socket == NULL)
+#else
if (worker->socket == NULL)
+#endif
g_input_stream_read_async (g_io_stream_get_input_stream (worker->stream),
worker->read_buffer + worker->read_buffer_cur_size,
worker->read_buffer_bytes_wanted - worker->read_buffer_cur_size,
@@ -986,131 +1146,144 @@ write_message_continue_writing (MessageToWriteData *data)
{
GOutputStream *ostream;
#ifdef G_OS_UNIX
- GSimpleAsyncResult *simple;
GUnixFDList *fd_list;
-#endif
-
-#ifdef G_OS_UNIX
- /* Note: we can't access data->simple after calling g_async_result_complete () because the
- * callback can free @data and we're not completing in idle. So use a copy of the pointer.
- */
+ GSimpleAsyncResult *simple;
simple = data->simple;
#endif
- ostream = g_io_stream_get_output_stream (data->worker->stream);
-#ifdef G_OS_UNIX
- fd_list = g_dbus_message_get_unix_fd_list (data->message);
-#endif
-
- g_assert (!g_output_stream_has_pending (ostream));
- g_assert_cmpint (data->total_written, <, data->blob_size);
-
- if (FALSE)
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (data->worker->stream))
{
+ GError *error;
+ error = NULL;
+ data->total_written = g_kdbus_send_message(data->worker, data->worker->kdbus, data->message,
data->blob, data->blob_size, &error);
+
+ write_message_print_transport_debug (data->total_written, data);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
}
-#ifdef G_OS_UNIX
- else if (G_IS_SOCKET_OUTPUT_STREAM (ostream) && data->total_written == 0)
+ else
{
- GOutputVector vector;
- GSocketControlMessage *control_message;
- gssize bytes_written;
- GError *error;
-
- vector.buffer = data->blob;
- vector.size = data->blob_size;
+#endif
+ ostream = g_io_stream_get_output_stream (data->worker->stream);
+#ifdef G_OS_UNIX
+ fd_list = g_dbus_message_get_unix_fd_list (data->message);
+#endif
- control_message = NULL;
- if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
- {
- if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING))
- {
- g_simple_async_result_set_error (simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Tried sending a file descriptor but remote peer does not
support this capability");
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
- control_message = g_unix_fd_message_new_with_fd_list (fd_list);
- }
+ g_assert (!g_output_stream_has_pending (ostream));
+ g_assert_cmpint (data->total_written, <, data->blob_size);
- error = NULL;
- bytes_written = g_socket_send_message (data->worker->socket,
- NULL, /* address */
- &vector,
- 1,
- control_message != NULL ? &control_message : NULL,
- control_message != NULL ? 1 : 0,
- G_SOCKET_MSG_NONE,
- data->worker->cancellable,
- &error);
- if (control_message != NULL)
- g_object_unref (control_message);
-
- if (bytes_written == -1)
+ if (FALSE)
{
- /* Handle WOULD_BLOCK by waiting until there's room in the buffer */
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
- {
- GSource *source;
- source = g_socket_create_source (data->worker->socket,
- G_IO_OUT | G_IO_HUP | G_IO_ERR,
- data->worker->cancellable);
- g_source_set_callback (source,
- (GSourceFunc) on_socket_ready,
- data,
- NULL); /* GDestroyNotify */
- g_source_attach (source, g_main_context_get_thread_default ());
- g_source_unref (source);
- g_error_free (error);
- goto out;
- }
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
}
- g_assert (bytes_written > 0); /* zero is never returned */
-
- write_message_print_transport_debug (bytes_written, data);
-
- data->total_written += bytes_written;
- g_assert (data->total_written <= data->blob_size);
- if (data->total_written == data->blob_size)
+#ifdef G_OS_UNIX
+ else if (G_IS_SOCKET_OUTPUT_STREAM (ostream) && data->total_written == 0)
{
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
-
- write_message_continue_writing (data);
- }
+ GOutputVector vector;
+ GSocketControlMessage *control_message;
+ gssize bytes_written;
+ GError *error;
+
+ vector.buffer = data->blob;
+ vector.size = data->blob_size;
+
+ control_message = NULL;
+ if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
+ {
+ if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING))
+ {
+ g_simple_async_result_set_error (simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Tried sending a file descriptor but remote peer does
not support this capability");
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
+ }
+ control_message = g_unix_fd_message_new_with_fd_list (fd_list);
+ }
+
+ error = NULL;
+ bytes_written = g_socket_send_message (data->worker->socket,
+ NULL, /* address */
+ &vector,
+ 1,
+ control_message != NULL ? &control_message : NULL,
+ control_message != NULL ? 1 : 0,
+ G_SOCKET_MSG_NONE,
+ data->worker->cancellable,
+ &error);
+ if (control_message != NULL)
+ g_object_unref (control_message);
+
+ if (bytes_written == -1)
+ {
+ /* Handle WOULD_BLOCK by waiting until there's room in the buffer */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+ {
+ GSource *source;
+ source = g_socket_create_source (data->worker->socket,
+ G_IO_OUT | G_IO_HUP | G_IO_ERR,
+ data->worker->cancellable);
+ g_source_set_callback (source,
+ (GSourceFunc) on_socket_ready,
+ data,
+ NULL); /* GDestroyNotify */
+ g_source_attach (source, g_main_context_get_thread_default ());
+ g_source_unref (source);
+ g_error_free (error);
+ goto out;
+ }
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
+ }
+ g_assert (bytes_written > 0); /* zero is never returned */
+
+ write_message_print_transport_debug (bytes_written, data);
+
+ data->total_written += bytes_written;
+ g_assert (data->total_written <= data->blob_size);
+ if (data->total_written == data->blob_size)
+ {
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
+ }
+
+ write_message_continue_writing (data);
+ }
#endif
- else
- {
+ else
+ {
#ifdef G_OS_UNIX
- if (fd_list != NULL)
- {
- g_simple_async_result_set_error (simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Tried sending a file descriptor on unsupported stream of type
%s",
- g_type_name (G_TYPE_FROM_INSTANCE (ostream)));
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
+ if (fd_list != NULL)
+ {
+ g_simple_async_result_set_error (simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Tried sending a file descriptor on unsupported stream of
type %s",
+ g_type_name (G_TYPE_FROM_INSTANCE (ostream)));
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
+ }
#endif
- g_output_stream_write_async (ostream,
- (const gchar *) data->blob + data->total_written,
- data->blob_size - data->total_written,
- G_PRIORITY_DEFAULT,
- data->worker->cancellable,
- write_message_async_cb,
- data);
+ g_output_stream_write_async (ostream,
+ (const gchar *) data->blob + data->total_written,
+ data->blob_size - data->total_written,
+ G_PRIORITY_DEFAULT,
+ data->worker->cancellable,
+ write_message_async_cb,
+ data);
+ }
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
}
+#endif
+
#ifdef G_OS_UNIX
out:
#endif
@@ -1452,9 +1625,14 @@ continue_writing (GDBusWorker *worker)
worker->close_expected = TRUE;
worker->output_pending = PENDING_CLOSE;
- g_io_stream_close_async (worker->stream, G_PRIORITY_DEFAULT,
- NULL, iostream_close_cb,
- _g_dbus_worker_ref (worker));
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ g_kdbus_connection_close (worker->stream, NULL, NULL);
+ else
+#endif
+ g_io_stream_close_async (worker->stream, G_PRIORITY_DEFAULT,
+ NULL, iostream_close_cb,
+ _g_dbus_worker_ref (worker));
}
else
{
@@ -1677,6 +1855,11 @@ _g_dbus_worker_new (GIOStream *stream,
if (G_IS_SOCKET_CONNECTION (worker->stream))
worker->socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (worker->stream));
+#if defined (G_OS_UNIX) && (KDBUS_TRANSPORT)
+ if (G_IS_KDBUS_CONNECTION (worker->stream))
+ worker->kdbus = g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (worker->stream));
+#endif
+
worker->shared_thread_data = _g_dbus_shared_thread_ref ();
/* begin reading */
@@ -2156,12 +2339,11 @@ write_message_print_transport_debug (gssize bytes_written,
g_print ("========================================================================\n"
"GDBus-debug:Transport:\n"
" >>>> WROTE %" G_GSIZE_FORMAT " bytes of message with serial %d and\n"
- " size %" G_GSIZE_FORMAT " from offset %" G_GSIZE_FORMAT " on a %s\n",
+ " size %" G_GSIZE_FORMAT " from offset %" G_GSIZE_FORMAT "\n",
bytes_written,
g_dbus_message_get_serial (data->message),
data->blob_size,
- data->total_written,
- g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_output_stream (data->worker->stream))));
+ data->total_written);
_g_dbus_debug_print_unlock ();
out:
;
@@ -2207,12 +2389,11 @@ read_message_print_transport_debug (gssize bytes_read,
g_print ("========================================================================\n"
"GDBus-debug:Transport:\n"
" <<<< READ %" G_GSIZE_FORMAT " bytes of message with serial %d and\n"
- " size %d to offset %" G_GSIZE_FORMAT " from a %s\n",
+ " size %d to offset %" G_GSIZE_FORMAT "\n",
bytes_read,
serial,
message_length,
- worker->read_buffer_cur_size,
- g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_input_stream (worker->stream))));
+ worker->read_buffer_cur_size);
_g_dbus_debug_print_unlock ();
out:
;
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
index 3a62867..e1e7231 100644
--- a/gio/gdbusprivate.h
+++ b/gio/gdbusprivate.h
@@ -80,7 +80,9 @@ gboolean _g_dbus_worker_flush_sync (GDBusWorker *worker,
void _g_dbus_worker_close (GDBusWorker *worker,
GCancellable *cancellable,
GSimpleAsyncResult *result);
-
+/* Samsung change */
+void _g_dbus_worker_queue_or_deliver_received_message (GDBusWorker *worker,
+ GDBusMessage *message);
/* ---------------------------------------------------------------------------------------------------- */
void _g_dbus_initialize (void);
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 02508e6..48ceb73 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -634,6 +634,18 @@ random_ascii (void)
return ret;
}
+#ifdef KDBUS_TRANSPORT
+static gboolean
+try_kdbus (GDBusServer *server,
+ const gchar *address_entry,
+ GHashTable *key_value_pairs,
+ GError **error)
+{
+ g_print ("GDBusServer - KDBUS\n");
+ return TRUE;
+}
+#endif
+
/* note that address_entry has already been validated => exactly one of path, tmpdir or abstract keys are
set */
static gboolean
try_unix (GDBusServer *server,
@@ -1071,6 +1083,10 @@ initable_init (GInitable *initable,
#ifdef G_OS_UNIX
else if (g_strcmp0 (transport_name, "unix") == 0)
ret = try_unix (server, address_entry, key_value_pairs, &this_error);
+#ifdef KDBUS_TRANSPORT
+ else if (g_strcmp0 (transport_name, "kdbus") == 0)
+ ret = try_kdbus (server, address_entry, key_value_pairs, &this_error);
+#endif
#endif
else if (g_strcmp0 (transport_name, "tcp") == 0)
ret = try_tcp (server, address_entry, key_value_pairs, FALSE, &this_error);
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index a76ecf3..faf9ac8 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -424,6 +424,8 @@ g_desktop_app_info_load_file (GDesktopAppInfo *self)
g_return_val_if_fail (self->filename != NULL, FALSE);
+ self->desktop_id = g_path_get_basename (self->filename);
+
key_file = g_key_file_new ();
if (g_key_file_load_from_file (key_file,
diff --git a/gio/giotypes.h b/gio/giotypes.h
index 2696091..671e2e3 100644
--- a/gio/giotypes.h
+++ b/gio/giotypes.h
@@ -250,6 +250,23 @@ typedef struct _GVolume GVolume; /* Dummy typedef */
typedef struct _GVolumeMonitor GVolumeMonitor;
/**
+ * GKdbus:
+ *
+ * A lowlevel kdbus object.
+ *
+ **/
+
+typedef struct _GKdbus GKdbus;
+
+/**
+ * GKdbusConnection:
+ *
+ * A kdbus connection GIOStream object.
+ *
+ **/
+typedef struct _GKdbusConnection GKdbusConnection;
+
+/**
* GAsyncReadyCallback:
* @source_object: the object the asynchronous operation was started with.
* @res: a #GAsyncResult.
@@ -343,6 +360,22 @@ typedef gboolean (*GSocketSourceFunc) (GSocket *socket,
gpointer user_data);
/**
+ * GKdbusSourceFunc:
+ * @socket: the #GKdbus
+ * @condition: the current condition at the source fired.
+ * @user_data: data passed in by the user.
+ *
+ * This is the function type of the callback used for the #GSource
+ * returned by g_kdbus_create_source().
+ *
+ * Returns: it should return %FALSE if the source should be removed.
+ *
+ */
+typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
+ GIOCondition condition,
+ gpointer user_data);
+
+/**
* GInputVector:
* @buffer: Pointer to a buffer where data will be written.
* @size: the available size in @buffer.
diff --git a/gio/gkdbus.c b/gio/gkdbus.c
new file mode 100644
index 0000000..aa7ce7d
--- /dev/null
+++ b/gio/gkdbus.c
@@ -0,0 +1,887 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Samsung
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Michal Eljasiewicz <m eljasiewic samsung com>
+ * Authors: Lukasz Skalski <l skalski partner samsung com>
+ */
+
+#include "config.h"
+
+#include "gkdbus.h"
+#include "glib-unix.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#include "gcancellable.h"
+#include "gioenumtypes.h"
+#include "ginitable.h"
+#include "gioerror.h"
+#include "gioenums.h"
+#include "gioerror.h"
+#include "glibintl.h"
+#include "kdbus.h"
+#include "gdbusmessage.h"
+#include "gdbusconnection.h"
+
+#define KDBUS_PART_FOREACH(part, head, first) \
+ for (part = (head)->first; \
+ (guint8 *)(part) < (guint8 *)(head) + (head)->size; \
+ part = KDBUS_PART_NEXT(part))
+#define RECEIVE_POOL_SIZE (10 * 1024LU * 1024LU)
+
+#define MSG_ITEM_BUILD_VEC(data, datasize) \
+ item->type = KDBUS_MSG_PAYLOAD_VEC; \
+ item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec); \
+ item->vec.address = (unsigned long) data; \
+ item->vec.size = datasize;
+
+#define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
+#define KDBUS_PART_NEXT(part) \
+ (typeof(part))(((guint8 *)part) + KDBUS_ALIGN8((part)->size))
+#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE)
+
+/*
+ * SECTION:gkdbus
+ * @short_description: Low-level kdbus object
+ * @include: gio/gio.h
+ */
+
+static void g_kdbus_initable_iface_init (GInitableIface *iface);
+static gboolean g_kdbus_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error);
+
+G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ g_kdbus_initable_iface_init));
+
+enum
+{
+ PROP_0,
+ PROP_FD,
+ PROP_TIMEOUT,
+ PROP_PEER_ID
+};
+
+struct _GKdbusPrivate
+{
+ gint fd;
+ gchar *path;
+ gchar *buffer_ptr;
+ gchar *sender;
+ gint peer_id;
+ guint64 bloom_size;
+ guint registered : 1;
+ guint closed : 1;
+ guint inited : 1;
+ guint timeout;
+ guint timed_out : 1;
+};
+
+/*
+ * g_kdbus_get_property:
+ *
+ */
+static void
+g_kdbus_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GKdbus *kdbus = G_KDBUS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FD:
+ g_value_set_int (value, kdbus->priv->fd);
+ break;
+
+ case PROP_TIMEOUT:
+ g_value_set_int (value, kdbus->priv->timeout);
+ break;
+
+ case PROP_PEER_ID:
+ g_value_set_int (value, kdbus->priv->peer_id);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+/*
+ * g_kdbus_set_property:
+ *
+ */
+static void
+g_kdbus_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GKdbus *kdbus = G_KDBUS (object);
+
+ switch (prop_id)
+ {
+ case PROP_TIMEOUT:
+ kdbus->priv->timeout = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+/*
+ * g_kdbus_finalize:
+ * TODO: Compare with gsocket
+ */
+static void
+g_kdbus_finalize (GObject *object)
+{
+ GKdbus *kdbus = G_KDBUS (object);
+
+ if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
+ g_kdbus_close (kdbus, NULL);
+
+ if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
+
+}
+
+/*
+ * g_kdbus_class_init:
+ *
+ */
+static void
+g_kdbus_class_init (GKdbusClass *klass)
+{
+ GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GKdbusPrivate));
+
+ gobject_class->finalize = g_kdbus_finalize;
+ gobject_class->set_property = g_kdbus_set_property;
+ gobject_class->get_property = g_kdbus_get_property;
+/*
+ g_object_class_install_property (gobject_class, PROP_FD,
+ g_param_spec_int ("fd",
+ P_("File descriptor"),
+ P_("The kdbus file descriptor"),
+ G_MININT,
+ G_MAXINT,
+ -1,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_TIMEOUT,
+ g_param_spec_uint ("timeout",
+ P_("Timeout"),
+ P_("The timeout in seconds on kdbus I/O"),
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_PEER_ID,
+ g_param_spec_uint ("Peer ID",
+ P_("kdbus peer ID"),
+ P_("The kdbus peer ID"),
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+*/
+}
+
+
+/*
+ * g_kdbus_initable_iface_init:
+ *
+ */
+static void
+g_kdbus_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = g_kdbus_initable_init;
+}
+
+/*
+ * g_kdbus_init:
+ *
+ */
+static void
+g_kdbus_init (GKdbus *kdbus)
+{
+ kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
+
+ kdbus->priv->fd = -1;
+ kdbus->priv->peer_id = -1;
+ kdbus->priv->bloom_size = 0;
+ kdbus->priv->path = NULL;
+ kdbus->priv->buffer_ptr = NULL;
+ kdbus->priv->sender = NULL;
+}
+
+/*
+ * g_kdbus_initable_init:
+ *
+ */
+static gboolean
+g_kdbus_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GKdbus *kdbus;
+
+ g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
+
+ kdbus = G_KDBUS (initable);
+
+ if (cancellable != NULL)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Cancellable initialization not supported"));
+ return FALSE;
+ }
+
+ kdbus->priv->inited = TRUE;
+
+ return TRUE;
+}
+
+/*
+ * g_kdbus_get_fd: returns the file descriptor of the kdbus
+ *
+ */
+
+gint
+g_kdbus_get_fd (GKdbus *kdbus)
+{
+ g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
+
+ return kdbus->priv->fd;
+}
+
+/*
+ * g_kdbus_open:
+ *
+ */
+gboolean
+g_kdbus_open (GKdbus *kdbus,
+ const gchar *address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
+ kdbus->priv->fd = open(address, O_RDWR|O_CLOEXEC|O_NONBLOCK);
+
+ if (kdbus->priv->fd<0)
+ {
+ g_error(" KDBUS_DEBUG: (%s()): error when mmap: %m, %d",__FUNCTION__,errno);
+ return FALSE;
+ }
+
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: (%s()): kdbus endpoint opened\n",__FUNCTION__);
+ #endif
+
+ kdbus->priv->closed = FALSE;
+ return TRUE;
+}
+
+/*
+ * g_kdbus_close:
+ *
+ */
+gboolean
+g_kdbus_close (GKdbus *kdbus,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
+ close(kdbus->priv->fd);
+
+ kdbus->priv->closed = TRUE;
+ kdbus->priv->fd = -1;
+ kdbus->priv->registered = FALSE;
+
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: (%s()): kdbus endpoint closed\n",__FUNCTION__);
+ #endif
+
+ return TRUE;
+}
+
+/*
+ * g_kdbus_is_closed: checks whether a kdbus is closed.
+ *
+ */
+gboolean
+g_kdbus_is_closed (GKdbus *kdbus)
+{
+ g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
+
+ return kdbus->priv->closed;
+}
+
+/*
+ * g_kdbus_register: hello message + unique name + mapping memory for incoming messages
+ * TODO:
+ */
+gboolean g_kdbus_register(GKdbus *kdbus)
+{
+ struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
+
+ hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
+ KDBUS_HELLO_ATTACH_COMM |
+ KDBUS_HELLO_ATTACH_EXE |
+ KDBUS_HELLO_ATTACH_CMDLINE |
+ KDBUS_HELLO_ATTACH_CAPS |
+ KDBUS_HELLO_ATTACH_CGROUP |
+ KDBUS_HELLO_ATTACH_SECLABEL|
+ KDBUS_HELLO_ATTACH_AUDIT*/;
+ hello.size = sizeof(struct kdbus_cmd_hello);
+ hello.pool_size = RECEIVE_POOL_SIZE;
+
+ if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, &hello))
+ {
+ g_error(" KDBUS_DEBUG: (%s()): fd=%d failed to send hello: %m, %d",__FUNCTION__,kdbus->priv->fd,errno);
+ return FALSE;
+ }
+
+ kdbus->priv->registered = TRUE;
+ kdbus->priv->peer_id = hello.id;
+
+ #ifdef KDBUS_DEBUG
+ g_print(" KDBUS_DEBUG: (%s()): Our peer ID=%llu\n",__FUNCTION__,hello.id);
+ #endif
+
+ kdbus->priv->bloom_size = hello.bloom_size;
+ kdbus->priv->buffer_ptr = mmap(NULL, RECEIVE_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
+
+ if (kdbus->priv->buffer_ptr == MAP_FAILED)
+ {
+ g_error(" KDBUS_DEBUG: (%s()): error when mmap: %m, %d",__FUNCTION__,errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * g_kdbus_decode_msg: kdbus message received into buffer
+ * TODO:
+ */
+static int
+g_kdbus_decode_msg(GKdbus *kdbus,
+ struct kdbus_msg *msg,
+ char *data)
+{
+ const struct kdbus_item *item;
+ int ret_size = 0;
+
+ KDBUS_PART_FOREACH(item, msg, items)
+ {
+ if (item->size <= KDBUS_PART_HEADER_SIZE)
+ {
+ g_error(" KDBUS_DEBUG: (%s()): %llu bytes - invalid data record\n",__FUNCTION__,item->size);
+ break; //TODO: continue (because dbus will find error) or break
+ }
+
+ switch (item->type)
+ {
+ case KDBUS_MSG_PAYLOAD_OFF:
+ memcpy(data, (char *)kdbus->priv->buffer_ptr + item->vec.offset, item->vec.size);
+ data += item->vec.size;
+ ret_size += item->vec.size;
+
+ #ifdef KDBUS_DEBUG
+ g_print(" KDBUS_DEBUG: (%s()): KDBUS_MSG_PAYLOAD: %llu bytes, off=%llu,
size=%llu\n",__FUNCTION__,item->size,
+ (unsigned long long)item->vec.offset,
+ (unsigned long long)item->vec.size);
+ #endif
+ break;
+
+ case KDBUS_MSG_REPLY_TIMEOUT:
+
+ #ifdef KDBUS_DEBUG
+ g_print(" KDBUS_DEBUG: (%s()): KDBUS_MSG_REPLY_TIMEOUT: %llu bytes,
cookie=%llu\n",__FUNCTION__,item->size, msg->cookie_reply);
+ #endif
+
+ /* TODO
+ message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
+ if(message == NULL)
+ {
+ ret_size = -1;
+ goto out;
+ }
+
+ ret_size = put_message_into_data(message, data);
+ */
+ break;
+
+ case KDBUS_MSG_REPLY_DEAD:
+ g_print(" KDBUS_DEBUG: (%s()): KDBUS_MSG_REPLY_DEAD: %llu bytes,
cookie=%llu\n",__FUNCTION__,item->size, msg->cookie_reply);
+
+ /* TODO
+ message = generate_local_error_message(msg->cookie_reply,
DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
+ if(message == NULL)
+ {
+ ret_size = -1;
+ goto out;
+ }
+
+ ret_size = put_message_into_data(message, data);
+ */
+ break;
+ }
+ }
+
+ return ret_size;
+}
+
+typedef struct {
+ GSource source;
+ GPollFD pollfd;
+ GKdbus *kdbus;
+ GIOCondition condition;
+ GCancellable *cancellable;
+ GPollFD cancel_pollfd;
+ gint64 timeout_time;
+} GKdbusSource;
+
+/*
+ * kdbus_source_prepare:
+ *
+ */
+static gboolean
+kdbus_source_prepare (GSource *source,
+ gint *timeout)
+{
+ GKdbusSource *kdbus_source = (GKdbusSource *)source;
+
+ if (g_cancellable_is_cancelled (kdbus_source->cancellable))
+ return TRUE;
+
+ if (kdbus_source->timeout_time)
+ {
+ gint64 now;
+
+ now = g_source_get_time (source);
+ /* Round up to ensure that we don't try again too early */
+ *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
+ if (*timeout < 0)
+ {
+ kdbus_source->kdbus->priv->timed_out = TRUE;
+ *timeout = 0;
+ return TRUE;
+ }
+ }
+ else
+ *timeout = -1;
+
+ if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * kdbus_source_check:
+ *
+ */
+static gboolean
+kdbus_source_check (GSource *source)
+{
+ int timeout;
+
+ return kdbus_source_prepare (source, &timeout);
+}
+
+/*
+ * kdbus_source_dispatch
+ *
+ */
+static gboolean
+kdbus_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
+ GKdbusSource *kdbus_source = (GKdbusSource *)source;
+ GKdbus *kdbus = kdbus_source->kdbus;
+ gboolean ret;
+
+ if (kdbus_source->kdbus->priv->timed_out)
+ kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
+
+ ret = (*func) (kdbus,
+ kdbus_source->pollfd.revents & kdbus_source->condition,
+ user_data);
+
+ if (kdbus->priv->timeout)
+ kdbus_source->timeout_time = g_get_monotonic_time () +
+ kdbus->priv->timeout * 1000000;
+
+ else
+ kdbus_source->timeout_time = 0;
+
+ return ret;
+}
+
+/*
+ * kdbus_source_finalize
+ *
+ */
+static void
+kdbus_source_finalize (GSource *source)
+{
+ GKdbusSource *kdbus_source = (GKdbusSource *)source;
+ GKdbus *kdbus;
+
+ kdbus = kdbus_source->kdbus;
+
+ g_object_unref (kdbus);
+
+ if (kdbus_source->cancellable)
+ {
+ g_cancellable_release_fd (kdbus_source->cancellable);
+ g_object_unref (kdbus_source->cancellable);
+ }
+}
+
+/*
+ * kdbus_source_closure_callback:
+ *
+ */
+static gboolean
+kdbus_source_closure_callback (GKdbus *kdbus,
+ GIOCondition condition,
+ gpointer data)
+{
+ GClosure *closure = data;
+ GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
+ GValue result_value = G_VALUE_INIT;
+ gboolean result;
+
+ g_value_init (&result_value, G_TYPE_BOOLEAN);
+
+ g_value_init (¶ms[0], G_TYPE_KDBUS);
+ g_value_set_object (¶ms[0], kdbus);
+ g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
+ g_value_set_flags (¶ms[1], condition);
+
+ g_closure_invoke (closure, &result_value, 2, params, NULL);
+
+ result = g_value_get_boolean (&result_value);
+ g_value_unset (&result_value);
+ g_value_unset (¶ms[0]);
+ g_value_unset (¶ms[1]);
+
+ return result;
+}
+
+static GSourceFuncs kdbus_source_funcs =
+{
+ kdbus_source_prepare,
+ kdbus_source_check,
+ kdbus_source_dispatch,
+ kdbus_source_finalize,
+ (GSourceFunc)kdbus_source_closure_callback,
+};
+
+/*
+ * kdbus_source_new:
+ *
+ */
+static GSource *
+kdbus_source_new (GKdbus *kdbus,
+ GIOCondition condition,
+ GCancellable *cancellable)
+{
+ GSource *source;
+ GKdbusSource *kdbus_source;
+
+ condition |= G_IO_HUP | G_IO_ERR;
+
+ source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
+ g_source_set_name (source, "GKdbus");
+ kdbus_source = (GKdbusSource *)source;
+
+ kdbus_source->kdbus = g_object_ref (kdbus);
+ kdbus_source->condition = condition;
+
+ if (g_cancellable_make_pollfd (cancellable,
+ &kdbus_source->cancel_pollfd))
+ {
+ kdbus_source->cancellable = g_object_ref (cancellable);
+ g_source_add_poll (source, &kdbus_source->cancel_pollfd);
+ }
+
+ kdbus_source->pollfd.fd = kdbus->priv->fd;
+ kdbus_source->pollfd.events = condition;
+ kdbus_source->pollfd.revents = 0;
+ g_source_add_poll (source, &kdbus_source->pollfd);
+
+ if (kdbus->priv->timeout)
+ kdbus_source->timeout_time = g_get_monotonic_time () +
+ kdbus->priv->timeout * 1000000;
+
+ else
+ kdbus_source->timeout_time = 0;
+
+ return source;
+}
+
+/*
+ * g_kdbus_create_source:
+ *
+ */
+GSource *
+g_kdbus_create_source (GKdbus *kdbus,
+ GIOCondition condition,
+ GCancellable *cancellable)
+{
+ g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
+
+ return kdbus_source_new (kdbus, condition, cancellable);
+}
+
+/*
+ * g_kdbus_receive:
+ * TODO: Handle errors
+ */
+gssize
+g_kdbus_receive (GKdbus *kdbus,
+ char *data,
+ GError **error)
+{
+ int ret_size = 0;
+ guint64 __attribute__ ((__aligned__(8))) offset;
+ struct kdbus_msg *msg;
+
+ /* TODO: Temporary hack */
+ if (kdbus->priv->closed == TRUE)
+ return 1;
+
+ //get memory offset of msg
+ again:
+ if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
+ {
+ if(errno == EINTR)
+ goto again;
+
+ /* TODO: Temporary hack */
+ if (errno == EAGAIN)
+ return 1;
+
+ g_error (" KDBUS_DEBUG: (%s()): ioctl MSG_RECV failed! %d (%m)\n",__FUNCTION__,errno);
+ return 1;
+ }
+
+ msg = (struct kdbus_msg *)((char*)kdbus->priv->buffer_ptr + offset);
+ ret_size = g_kdbus_decode_msg(kdbus, msg, (char*)data);
+
+ //release memory occupied by msg
+ again_2:
+ if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
+ {
+ if(errno == EINTR)
+ goto again_2;
+ g_print (" KDBUS_DEBUG: (%s()): ioctl MSG_RELEASE failed!\n",__FUNCTION__);
+ return -1;
+ }
+
+ return ret_size;
+}
+
+/*
+ * g_kdbus_send_reply:
+ * TODO: Handle errors,remove unused variables
+ */
+static gboolean
+g_kdbus_send_reply (GDBusWorker *worker,
+ GKdbus *kdbus,
+ GDBusMessage *dbus_msg)
+{
+ GDBusMessage *reply = NULL;
+ char *unique_name = NULL;
+ char *sender = NULL;
+
+ reply = g_dbus_message_new_method_reply(dbus_msg);
+ g_dbus_message_set_sender(reply, "org.freedesktop.DBus");
+
+ unique_name = malloc(30); //TODO: should allow for Kdbus peer ID max value?
+ sprintf(unique_name, "%i", kdbus->priv->peer_id);
+
+ sender = malloc (strlen(unique_name) + 4);
+ if(!sender)
+ {
+ //TODO: Handle error
+ g_error (" KDBUS_DEBUG: (%s()): sender malloc error\n",__FUNCTION__);
+ return -1;
+ }
+
+ sprintf(sender, ":1.%s", unique_name);
+ kdbus->priv->sender = sender;
+
+ #ifdef KDBUS_DEBUG
+ g_print ("g_kdbus_send_reply: sender set to:%s! \n", kdbus->priv->sender);
+ #endif
+
+ //g_dbus_message_set_body(reply, g_variant_new ("(s)", unique_name));
+ g_dbus_message_set_body (reply, g_variant_new ("(s)",sender));
+ _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
+
+ g_free (unique_name);
+ g_free (sender);
+ return TRUE;
+}
+
+/*
+ * g_kdbus_send_message:
+ * TODO: Handle errors
+ */
+gssize
+g_kdbus_send_message (GDBusWorker *worker,
+ GKdbus *kdbus,
+ GDBusMessage *dbus_msg,
+ gchar *blob,
+ gsize blob_size,
+ GError **error)
+{
+ struct kdbus_msg* kmsg;
+ struct kdbus_item *item;
+ guint64 kmsg_size = 0;
+ const gchar *name;
+ guint64 dst_id = KDBUS_DST_ID_BROADCAST;
+
+ if (kdbus->priv->registered == FALSE)
+ {
+ if (!g_kdbus_register(kdbus))
+ {
+ g_error (" KDBUS_DEBUG: (%s()): registering failed!\n",__FUNCTION__);
+ return -1;
+ }
+
+ if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "Hello") == 0)
+ {
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: (%s()): sending \"Hello\" message!\n",__FUNCTION__);
+ #endif
+
+ g_kdbus_send_reply(worker, kdbus, dbus_msg);
+ goto out;
+ }
+ }
+
+ if ((name = g_dbus_message_get_destination(dbus_msg)))
+ {
+ dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
+ if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
+ {
+ dst_id = strtoull(&name[3], NULL, 10);
+ name=NULL;
+ }
+ }
+
+ kmsg_size = sizeof(struct kdbus_msg);
+ kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); //vector for blob
+
+ if (name)
+ kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
+ else if (dst_id == KDBUS_DST_ID_BROADCAST)
+ kmsg_size += KDBUS_PART_HEADER_SIZE + kdbus->priv->bloom_size;
+
+ kmsg = malloc(kmsg_size);
+ if (!kmsg)
+ {
+ //TODO: Handle error
+ g_error (" KDBUS_DEBUG: (%s()): kmsg malloc error\n",__FUNCTION__);
+ return -1;
+ }
+
+ memset(kmsg, 0, kmsg_size);
+ kmsg->size = kmsg_size;
+ kmsg->payload_type = KDBUS_PAYLOAD_DBUS1;
+ kmsg->dst_id = name ? 0 : dst_id;
+ kmsg->src_id = kdbus->priv->peer_id;
+ kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
+
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: (%s()): destination name: %s\n",__FUNCTION__,name);
+ g_print (" KDBUS_DEBUG: (%s()): blob size: %d\n",__FUNCTION__,(gint)blob_size);
+ g_print (" KDBUS_DEBUG: (%s()): serial: %i\n",__FUNCTION__,kmsg->cookie);
+ g_print (" KDBUS_DEBUG: (%s()): src_id/peer_id: %i\n",__FUNCTION__,kdbus->priv->peer_id);
+ #endif
+
+ //build message contents
+ item = kmsg->items;
+ MSG_ITEM_BUILD_VEC(blob, blob_size);
+
+ if (name)
+ {
+ item = KDBUS_PART_NEXT(item);
+ item->type = KDBUS_MSG_DST_NAME;
+ item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
+ strcpy(item->str, name);
+ }
+ else if (dst_id == KDBUS_DST_ID_BROADCAST)
+ {
+ item = KDBUS_PART_NEXT(item);
+ item->type = KDBUS_MSG_BLOOM;
+ item->size = KDBUS_PART_HEADER_SIZE + kdbus->priv->bloom_size;
+ strncpy(item->data,g_dbus_message_get_interface(dbus_msg),kdbus->priv->bloom_size);
+ }
+
+again:
+ if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
+ {
+ if(errno == EINTR)
+ goto again;
+ else
+ g_error (" KDBUS_DEBUG: (%s()): ioctl error sending kdbus message:%d (%m)\n",__FUNCTION__,errno);
+ }
+
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: (%s()): ioctl(CMD_MSG_SEND) sent successfully\n",__FUNCTION__);
+ #endif
+
+ free(kmsg);
+
+out:
+ return blob_size;
+}
+
diff --git a/gio/gkdbus.h b/gio/gkdbus.h
new file mode 100644
index 0000000..1e6a25d
--- /dev/null
+++ b/gio/gkdbus.h
@@ -0,0 +1,113 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Samsung
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Michal Eljasiewicz <m eljasiewic samsung com>
+ * Authors: Lukasz Skalski <l skalski partner samsung com>
+ */
+
+#ifndef __G_KDBUS_H__
+#define __G_KDBUS_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+#include "gdbusprivate.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_KDBUS (g_kdbus_get_type ())
+#define G_KDBUS(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst),
\
+ G_TYPE_KDBUS, GKdbus))
+#define G_KDBUS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class),
\
+ G_TYPE_KDBUS, GKdbusClass))
+#define G_IS_KDBUS(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst),
\
+ G_TYPE_KDBUS))
+#define G_IS_KDBUS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class),
\
+ G_TYPE_KDBUS))
+#define G_KDBUS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst),
\
+ G_TYPE_KDBUS, GKdbusClass))
+
+typedef struct _GKdbusPrivate GKdbusPrivate;
+typedef struct _GKdbusClass GKdbusClass;
+
+struct _GKdbusClass
+{
+ GObjectClass parent_class;
+
+ /*< private >*/
+
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+ void (*_g_reserved6) (void);
+ void (*_g_reserved7) (void);
+ void (*_g_reserved8) (void);
+ void (*_g_reserved9) (void);
+ void (*_g_reserved10) (void);
+};
+
+struct _GKdbus
+{
+ GObject parent_instance;
+ GKdbusPrivate *priv;
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType g_kdbus_get_type (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+gint g_kdbus_get_fd (GKdbus
*kdbus);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_open (GKdbus
*kdbus,
+ const gchar
*address,
+ GCancellable
*cancellable,
+ GError
**error);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_close (GKdbus
*kdbus,
+ GError
**error);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_is_closed (GKdbus
*kdbus);
+GLIB_AVAILABLE_IN_ALL
+gssize g_kdbus_receive (GKdbus
*kdbus,
+ char
*data,
+ GError
**error);
+GLIB_AVAILABLE_IN_ALL
+gssize g_kdbus_send_message (GDBusWorker *worker,
+ GKdbus
*kdbus,
+ GDBusMessage
*dbus_msg,
+ gchar
*blob,
+ gsize
blob_size,
+ GError
**error);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_register (GKdbus
*kdbus);
+GLIB_AVAILABLE_IN_ALL
+GSource * g_kdbus_create_source (GKdbus *kdbus,
+ GIOCondition
condition,
+ GCancellable
*cancellable);
+GLIB_AVAILABLE_IN_ALL
+GIOCondition g_kdbus_condition_check (GKdbus *kdbus,
+ GIOCondition
condition);
+
+G_END_DECLS
+
+#endif /* __G_KDBUS_H__ */
diff --git a/gio/gkdbusconnection.c b/gio/gkdbusconnection.c
new file mode 100644
index 0000000..c4ec1a0
--- /dev/null
+++ b/gio/gkdbusconnection.c
@@ -0,0 +1,206 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Samsung
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Michal Eljasiewicz <m eljasiewic samsung com>
+ * Authors: Lukasz Skalski <l skalski partner samsung com>
+ */
+
+#include <fcntl.h>
+#include "config.h"
+
+#include <gio/gtask.h>
+
+#include "gkdbusconnection.h"
+#include "gunixconnection.h"
+
+
+/**
+ * SECTION:gkdbusconnection
+ * @short_description: A kdbus connection
+ * @include: gio/gio.h
+ * @see_also: #GIOStream, #GKdbusClient
+ *
+ * #GKdbusConnection is a #GIOStream for a connected kdbus bus.
+ */
+
+G_DEFINE_TYPE (GKdbusConnection, g_kdbus_connection, G_TYPE_IO_STREAM);
+
+struct _GKdbusConnectionPrivate
+{
+ GKdbus *kdbus;
+ gboolean in_dispose;
+};
+
+/*
+ * g_kdbus_connection_new:
+ *
+ */
+GKdbusConnection *
+g_kdbus_connection_new (void)
+{
+ return g_object_new(G_TYPE_KDBUS_CONNECTION,NULL);
+}
+
+/*
+ * g_kdbus_connection_connect:
+ *
+ */
+gboolean
+g_kdbus_connection_connect (GKdbusConnection *connection,
+ const gchar *address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_KDBUS_CONNECTION (connection), FALSE);
+
+ return g_kdbus_open (connection->priv->kdbus,address,cancellable,error);
+}
+
+/*
+ * g_kdbus_connection_is_connected:
+ *
+ */
+gboolean
+g_kdbus_connection_is_connected (GKdbusConnection *connection)
+{
+ return (!g_kdbus_is_closed (connection->priv->kdbus));
+}
+
+/*
+ * g_kdbus_connection_get_property:
+ *
+ */
+static void
+g_kdbus_connection_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ //GKdbusConnection *connection = G_KDBUS_CONNECTION (object);
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+/*
+ * g_kdbus_connection_set_property
+ *
+ */
+static void
+g_kdbus_connection_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ //GKdbusConnection *connection = G_KDBUS_CONNECTION (object);
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+// TODO
+static void
+g_kdbus_connection_dispose (GObject *object)
+{
+ GKdbusConnection *connection = G_KDBUS_CONNECTION (object);
+
+ connection->priv->in_dispose = TRUE;
+
+ G_OBJECT_CLASS (g_kdbus_connection_parent_class)
+ ->dispose (object);
+
+ connection->priv->in_dispose = FALSE;
+}
+
+/*
+ * g_kdbus_connection_finalize:
+ *
+ */
+static void
+g_kdbus_connection_finalize (GObject *object)
+{
+ //GKdbusConnection *connection = G_KDBUS_CONNECTION (object);
+ G_OBJECT_CLASS (g_kdbus_connection_parent_class)
+ ->finalize (object);
+}
+
+/*
+ * g_kdbus_connection_close
+ *
+ */
+gboolean
+g_kdbus_connection_close (GIOStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GKdbusConnection *connection = G_KDBUS_CONNECTION (stream);
+
+ if (connection->priv->in_dispose)
+ return TRUE;
+
+ return g_kdbus_close (connection->priv->kdbus, error);
+ return TRUE;
+}
+
+/*
+ * g_kdbus_connection_class_init:
+ *
+ */
+static void
+g_kdbus_connection_class_init (GKdbusConnectionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GKdbusConnectionPrivate));
+
+ gobject_class->set_property = g_kdbus_connection_set_property;
+ gobject_class->get_property = g_kdbus_connection_get_property;
+ gobject_class->finalize = g_kdbus_connection_finalize;
+ gobject_class->dispose = g_kdbus_connection_dispose;
+}
+
+/*
+ * g_kdbus_connection_init:
+ *
+ */
+static void
+g_kdbus_connection_init (GKdbusConnection *connection)
+{
+ connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection,
+ G_TYPE_KDBUS_CONNECTION,
+ GKdbusConnectionPrivate);
+ connection->priv->kdbus = g_object_new(G_TYPE_KDBUS,NULL);
+}
+
+/*
+ * g_kdbus_connection_get_kdbus: gets the underlying #GKdbus object of the connection.
+ *
+ */
+GKdbus *
+g_kdbus_connection_get_kdbus (GKdbusConnection *connection)
+{
+ g_return_val_if_fail (G_IS_KDBUS_CONNECTION (connection), NULL);
+
+ return connection->priv->kdbus;
+}
+
diff --git a/gio/gkdbusconnection.h b/gio/gkdbusconnection.h
new file mode 100644
index 0000000..716c9bc
--- /dev/null
+++ b/gio/gkdbusconnection.h
@@ -0,0 +1,91 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Samsung
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Michal Eljasiewicz <m eljasiewic samsung com>
+ * Authors: Lukasz Skalski <l skalski partner samsung com>
+ */
+
+#ifndef __G_KDBUS_CONNECTION_H__
+#define __G_KDBUS_CONNECTION_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+#include <gio/gkdbus.h>
+#include <gio/giostream.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_KDBUS_CONNECTION (g_kdbus_connection_get_type ())
+#define G_KDBUS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst),
\
+ G_TYPE_KDBUS_CONNECTION, GKdbusConnection))
+#define G_KDBUS_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class),
\
+ G_TYPE_KDBUS_CONNECTION, GKdbusConnectionClass))
+#define G_IS_KDBUS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst),
\
+ G_TYPE_KDBUS_CONNECTION))
+#define G_IS_KDBUS_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class),
\
+ G_TYPE_KDBUS_CONNECTION))
+#define G_KDBUS_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst),
\
+ G_TYPE_KDBUS_CONNECTION, GKdbusConnectionClass))
+
+typedef struct _GKdbusConnectionPrivate GKdbusConnectionPrivate;
+typedef struct _GKdbusConnectionClass GKdbusConnectionClass;
+
+struct _GKdbusConnectionClass
+{
+ GIOStreamClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+ void (*_g_reserved6) (void);
+};
+
+struct _GKdbusConnection
+{
+ GIOStream parent_instance;
+ GKdbusConnectionPrivate *priv;
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType g_kdbus_connection_get_type (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GKdbusConnection *g_kdbus_connection_new (void);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_connection_is_connected (GKdbusConnection *connection);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_connection_connect (GKdbusConnection *connection,
+ const gchar *address,
+ GCancellable *cancellable,
+ GError **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_kdbus_connection_close (GIOStream *stream,
+ GCancellable *cancellable,
+ GError **error);
+GLIB_AVAILABLE_IN_ALL
+GKdbus *g_kdbus_connection_get_kdbus (GKdbusConnection *connection);
+
+G_END_DECLS
+
+#endif /* __G_KDBUS_CONNECTION_H__ */
diff --git a/gio/kdbus.h b/gio/kdbus.h
new file mode 100644
index 0000000..fe46101
--- /dev/null
+++ b/gio/kdbus.h
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2013 Kay Sievers
+ * Copyright (C) 2013 Greg Kroah-Hartman <gregkh linuxfoundation org>
+ * Copyright (C) 2013 Linux Foundation
+ * Copyright (C) 2013 Lennart Poettering
+ * Copyright (C) 2013 Daniel Mack <daniel zonque org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _KDBUS_H_
+#define _KDBUS_H_
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+
+/* todo #define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE SZ_8M - maximum size of message header and items
+ * taken from internal.h of kdbus
+ * finally it should be placed higher - e.g. kdbus.h of kdbus kernel module
+ */
+#define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE 0x00800000 /* maximum size of message header and
items */
+
+#define KDBUS_IOC_MAGIC 0x95
+#define KDBUS_SRC_ID_KERNEL (0)
+#define KDBUS_DST_ID_WELL_KNOWN_NAME (0)
+#define KDBUS_MATCH_SRC_ID_ANY (~0ULL)
+#define KDBUS_DST_ID_BROADCAST (~0ULL)
+
+/* Common first elements in a structure which are used to iterate over
+ * a list of elements. */
+#define KDBUS_PART_HEADER \
+ struct { \
+ __u64 size; \
+ __u64 type; \
+ }
+
+#define KDBUS_PART_HEADER_SIZE offsetof(struct kdbus_item, data)
+
+/* Message sent from kernel to userspace, when the owner or starter of
+ * a well-known name changes */
+struct kdbus_manager_msg_name_change {
+ __u64 old_id;
+ __u64 new_id;
+ __u64 flags; /* 0 or (possibly?) KDBUS_NAME_IN_QUEUE */
+ char name[0];
+};
+
+struct kdbus_manager_msg_id_change {
+ __u64 id;
+ __u64 flags; /* The kernel flags field from KDBUS_HELLO */
+};
+
+struct kdbus_creds {
+ __u64 uid;
+ __u64 gid;
+ __u64 pid;
+ __u64 tid;
+
+ /* The starttime of the process PID. This is useful to detect
+ PID overruns from the client side. i.e. if you use the PID to
+ look something up in /proc/$PID/ you can afterwards check the
+ starttime field of it to ensure you didn't run into a PID
+ ovretun. */
+ __u64 starttime;
+};
+
+struct kdbus_audit {
+ __u64 sessionid;
+ __u64 loginuid;
+};
+
+struct kdbus_timestamp {
+ __u64 monotonic_ns;
+ __u64 realtime_ns;
+};
+
+struct kdbus_vec {
+ __u64 size;
+ union {
+ __u64 address;
+ __u64 offset;
+ };
+};
+
+struct kdbus_memfd {
+ __u64 size;
+ int fd;
+ __u32 __pad;
+};
+
+/* Message Item Types */
+enum {
+ _KDBUS_MSG_NULL,
+
+ /* Filled in by userspace */
+ KDBUS_MSG_PAYLOAD_VEC, /* .data_vec, reference to memory area */
+ KDBUS_MSG_PAYLOAD_OFF, /* .data_vec, reference to memory area */
+ KDBUS_MSG_PAYLOAD_MEMFD, /* file descriptor of a special data file */
+ KDBUS_MSG_FDS, /* .data_fds of file descriptors */
+ KDBUS_MSG_BLOOM, /* for broadcasts, carries bloom filter blob in .data */
+ KDBUS_MSG_DST_NAME, /* destination's well-known name, in .str */
+ KDBUS_MSG_PRIORITY, /* queue priority for message */
+
+ /* Filled in by kernelspace */
+ KDBUS_MSG_SRC_NAMES = 0x400,/* NUL separated string list with well-known names of source */
+ KDBUS_MSG_TIMESTAMP, /* .timestamp */
+ KDBUS_MSG_SRC_CREDS, /* .creds */
+ KDBUS_MSG_SRC_PID_COMM, /* optional, in .str */
+ KDBUS_MSG_SRC_TID_COMM, /* optional, in .str */
+ KDBUS_MSG_SRC_EXE, /* optional, in .str */
+ KDBUS_MSG_SRC_CMDLINE, /* optional, in .str (a chain of NUL str) */
+ KDBUS_MSG_SRC_CGROUP, /* optional, in .str */
+ KDBUS_MSG_SRC_CAPS, /* caps data blob, in .data */
+ KDBUS_MSG_SRC_SECLABEL, /* NUL terminated string, in .str */
+ KDBUS_MSG_SRC_AUDIT, /* .audit */
+
+ /* Special messages from kernel, consisting of one and only one of these data blocks */
+ KDBUS_MSG_NAME_ADD = 0x800,/* .name_change */
+ KDBUS_MSG_NAME_REMOVE, /* .name_change */
+ KDBUS_MSG_NAME_CHANGE, /* .name_change */
+ KDBUS_MSG_ID_ADD, /* .id_change */
+ KDBUS_MSG_ID_REMOVE, /* .id_change */
+ KDBUS_MSG_REPLY_TIMEOUT, /* empty, but .reply_cookie in .kdbus_msg is filled in */
+ KDBUS_MSG_REPLY_DEAD, /* dito */
+};
+
+/**
+ * struct kdbus_item - chain of data blocks
+ *
+ * size: overall data record size
+ * type: kdbus_item type of data
+ */
+struct kdbus_item {
+ KDBUS_PART_HEADER;
+ union {
+ /* inline data */
+ __u8 data[0];
+ __u32 data32[0];
+ __u64 data64[0];
+ char str[0];
+
+ /* connection */
+ __u64 id;
+
+ /* data vector */
+ struct kdbus_vec vec;
+
+ /* process credentials and properties*/
+ struct kdbus_creds creds;
+ struct kdbus_audit audit;
+ struct kdbus_timestamp timestamp;
+
+ /* specific fields */
+ struct kdbus_memfd memfd;
+ int fds[0];
+ struct kdbus_manager_msg_name_change name_change;
+ struct kdbus_manager_msg_id_change id_change;
+ };
+};
+
+enum {
+ KDBUS_MSG_FLAGS_EXPECT_REPLY = 1 << 0,
+ KDBUS_MSG_FLAGS_NO_AUTO_START = 1 << 1,
+};
+
+enum {
+ KDBUS_PAYLOAD_KERNEL,
+ KDBUS_PAYLOAD_DBUS1 = 0x4442757356657231ULL, /* 'DBusVer1' */
+ KDBUS_PAYLOAD_GVARIANT = 0x4756617269616e74ULL, /* 'GVariant' */
+};
+
+/**
+ * struct kdbus_msg
+ *
+ * set by userspace:
+ * dst_id: destination id
+ * flags: KDBUS_MSG_FLAGS_*
+ * items: data records
+ *
+ * set by kernel:
+ * src_id: who sent the message
+ */
+struct kdbus_msg {
+ __u64 size;
+ __u64 flags;
+ __u64 dst_id; /* connection, 0 == name in data, ~0 broadcast */
+ __u64 src_id; /* connection, 0 == kernel */
+ __u64 payload_type; /* 'DBusVer1', 'GVariant', ... */
+ __u64 cookie; /* userspace-supplied cookie */
+ union {
+ __u64 cookie_reply; /* cookie we reply to */
+ __u64 timeout_ns; /* timespan to wait for reply */
+ };
+ struct kdbus_item items[0];
+};
+
+enum {
+ _KDBUS_POLICY_NULL,
+ KDBUS_POLICY_NAME,
+ KDBUS_POLICY_ACCESS,
+};
+
+enum {
+ _KDBUS_POLICY_ACCESS_NULL,
+ KDBUS_POLICY_ACCESS_USER,
+ KDBUS_POLICY_ACCESS_GROUP,
+ KDBUS_POLICY_ACCESS_WORLD,
+};
+
+enum {
+ KDBUS_POLICY_RECV = 1 << 2,
+ KDBUS_POLICY_SEND = 1 << 1,
+ KDBUS_POLICY_OWN = 1 << 0,
+};
+
+struct kdbus_policy_access {
+ __u64 type; /* USER, GROUP, WORLD */
+ __u64 bits; /* RECV, SEND, OWN */
+ __u64 id; /* uid, gid, 0 */
+};
+
+//FIXME: convert access to access[]
+struct kdbus_policy {
+ KDBUS_PART_HEADER;
+ union {
+ char name[0];
+ struct kdbus_policy_access access;
+ };
+};
+
+/* A series of KDBUS_POLICY_NAME, plus one or more KDBUS_POLICY_ACCESS */
+struct kdbus_cmd_policy {
+ __u64 size;
+ struct kdbus_policy policies[0];
+};
+
+/* Flags for struct kdbus_cmd_hello */
+enum {
+ KDBUS_HELLO_STARTER = 1 << 0,
+ KDBUS_HELLO_ACCEPT_FD = 1 << 1,
+
+ /* The following have an effect on directed messages only --
+ * not for broadcasts */
+ KDBUS_HELLO_ATTACH_COMM = 1 << 10,
+ KDBUS_HELLO_ATTACH_EXE = 1 << 11,
+ KDBUS_HELLO_ATTACH_CMDLINE = 1 << 12,
+ KDBUS_HELLO_ATTACH_CGROUP = 1 << 13,
+ KDBUS_HELLO_ATTACH_CAPS = 1 << 14,
+ KDBUS_HELLO_ATTACH_SECLABEL = 1 << 15,
+ KDBUS_HELLO_ATTACH_AUDIT = 1 << 16,
+};
+
+struct kdbus_cmd_hello {
+ __u64 size;
+
+ /* userspace → kernel, kernel → userspace */
+ __u64 conn_flags; /* userspace specifies its
+ * capabilities and more, kernel
+ * returns its capabilites and
+ * more. Kernel might refuse client's
+ * capabilities by returning an error
+ * from KDBUS_HELLO */
+
+ /* kernel → userspace */
+ __u64 bus_flags; /* this is .flags copied verbatim from
+ * from original KDBUS_CMD_BUS_MAKE
+ * ioctl. It's intended to be useful
+ * to do negotiation of features of
+ * the payload that is transfreted. */
+ __u64 id; /* id assigned to this connection */
+ __u64 bloom_size; /* The bloom filter size chosen by the
+ * bus owner */
+ __u64 pool_size; /* maximum size of pool buffer */
+ struct kdbus_item items[0];
+};
+
+/* Flags for kdbus_cmd_{bus,ep,ns}_make */
+enum {
+ KDBUS_MAKE_ACCESS_GROUP = 1 << 0,
+ KDBUS_MAKE_ACCESS_WORLD = 1 << 1,
+ KDBUS_MAKE_POLICY_OPEN = 1 << 2,
+};
+
+/* Items to append to kdbus_cmd_{bus,ep,ns}_make */
+enum {
+ _KDBUS_MAKE_NULL,
+ KDBUS_MAKE_NAME,
+ KDBUS_MAKE_CGROUP, /* the cgroup hierarchy ID for which to attach
+ * cgroup membership paths to messages.
+ * FIXME: remove, use *the* hierarchy */
+ KDBUS_MAKE_CRED, /* allow translator services which connect
+ * to the bus on behalf of somebody else,
+ * allow specifiying the credentials of the
+ * client to connect on behalf on. Needs
+ * privileges */
+};
+
+struct kdbus_cmd_bus_make {
+ __u64 size;
+ __u64 flags; /* userspace → kernel, kernel → userspace
+ * When creating a bus feature
+ * kernel negotiation. */
+ __u64 bus_flags; /* userspace → kernel
+ * When a bus is created this value is
+ * copied verbatim into the bus
+ * structure and returned from
+ * KDBUS_CMD_HELLO, later */
+ __u64 bloom_size; /* size of the bloom filter for this bus */
+ struct kdbus_item items[0];
+};
+
+struct kdbus_cmd_ep_make {
+ __u64 size;
+ __u64 flags; /* userspace → kernel, kernel → userspace
+ * When creating an entry point
+ * feature kernel negotiation done the
+ * same way as for
+ * KDBUS_CMD_BUS_MAKE. Unused for
+ * now. */
+ struct kdbus_item items[0];
+};
+
+struct kdbus_cmd_ns_make {
+ __u64 size;
+ __u64 flags; /* userspace → kernel, kernel → userspace
+ * When creating an entry point
+ * feature kernel negotiation done the
+ * same way as for
+ * KDBUS_CMD_BUS_MAKE. Unused for
+ * now. */
+ struct kdbus_item items[0];
+};
+
+enum {
+ /* userspace → kernel */
+ KDBUS_NAME_REPLACE_EXISTING = 1 << 0,
+ KDBUS_NAME_QUEUE = 1 << 1,
+ KDBUS_NAME_ALLOW_REPLACEMENT = 1 << 2,
+
+ /* kernel → userspace */
+ KDBUS_NAME_IN_QUEUE = 1 << 16,
+};
+
+/* We allow (de)regestration of names of other peers */
+struct kdbus_cmd_name {
+ __u64 size;
+ __u64 flags;
+ __u64 id;
+ __u64 conn_flags;
+ char name[0];
+};
+
+struct kdbus_cmd_names {
+ __u64 size;
+ struct kdbus_cmd_name names[0];
+};
+
+enum {
+ _KDBUS_NAME_INFO_ITEM_NULL,
+ KDBUS_NAME_INFO_ITEM_NAME, /* userspace → kernel */
+ KDBUS_NAME_INFO_ITEM_SECLABEL, /* kernel → userspace */
+ KDBUS_NAME_INFO_ITEM_AUDIT, /* kernel → userspace */
+};
+
+struct kdbus_cmd_name_info {
+ __u64 size; /* overall size of info */
+ __u64 flags;
+ __u64 id; /* either ID, or 0 and _ITEM_NAME follows */
+ struct kdbus_creds creds;
+ struct kdbus_item items[0]; /* list of item records */
+};
+
+enum {
+ _KDBUS_MATCH_NULL,
+ KDBUS_MATCH_BLOOM, /* Matches a mask blob against KDBUS_MSG_BLOOM */
+ KDBUS_MATCH_SRC_NAME, /* Matches a name string against KDBUS_MSG_SRC_NAMES */
+ KDBUS_MATCH_NAME_ADD, /* Matches a name string against KDBUS_MSG_NAME_ADD */
+ KDBUS_MATCH_NAME_REMOVE, /* Matches a name string against KDBUS_MSG_NAME_REMOVE */
+ KDBUS_MATCH_NAME_CHANGE, /* Matches a name string against KDBUS_MSG_NAME_CHANGE */
+ KDBUS_MATCH_ID_ADD, /* Matches an ID against KDBUS_MSG_ID_ADD */
+ KDBUS_MATCH_ID_REMOVE, /* Matches an ID against KDBUS_MSG_ID_REMOVE */
+};
+
+struct kdbus_cmd_match {
+ __u64 size;
+ __u64 id; /* We allow registration/deregestration of matches for other peers */
+ __u64 cookie; /* userspace supplied cookie; when removing; kernel deletes everything with same
cookie */
+ __u64 src_id; /* ~0: any. other: exact unique match */
+ struct kdbus_item items[0];
+};
+
+struct kdbus_cmd_monitor {
+ __u64 id; /* We allow setting the monitor flag of other peers */
+ unsigned int enable; /* A boolean to enable/disable monitoring */
+ __u32 __pad;
+};
+
+/* FD states:
+ * control nodes: unset
+ * bus owner (via KDBUS_CMD_BUS_MAKE)
+ * ns owner (via KDBUS_CMD_NS_MAKE)
+ *
+ * ep nodes: unset
+ * connected (via KDBUS_CMD_HELLO)
+ * starter (via KDBUS_CMD_HELLO with KDBUS_CMD_HELLO_STARTER)
+ * ep owner (via KDBUS_CMD_EP_MAKE)
+ */
+enum {
+ /* kdbus control node commands: require unset state */
+ KDBUS_CMD_BUS_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make),
+ KDBUS_CMD_NS_MAKE = _IOR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make),
+
+ /* kdbus ep node commands: require unset state */
+ KDBUS_CMD_EP_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make),
+ KDBUS_CMD_HELLO = _IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello),
+
+ /* kdbus ep node commands: require connected state */
+ KDBUS_CMD_MSG_SEND = _IOW(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg),
+ KDBUS_CMD_MSG_RECV = _IOR(KDBUS_IOC_MAGIC, 0x41, __u64 *),
+ KDBUS_CMD_MSG_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *),
+
+ KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name),
+ KDBUS_CMD_NAME_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name),
+ KDBUS_CMD_NAME_LIST = _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_names),
+ KDBUS_CMD_NAME_QUERY = _IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info),
+
+ KDBUS_CMD_MATCH_ADD = _IOW(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match),
+ KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match),
+ KDBUS_CMD_MONITOR = _IOW(KDBUS_IOC_MAGIC, 0x62, struct kdbus_cmd_monitor),
+
+ /* kdbus ep node commands: require ep owner state */
+ KDBUS_CMD_EP_POLICY_SET = _IOW(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy),
+
+ /* kdbus memfd commands: */
+ KDBUS_CMD_MEMFD_NEW = _IOR(KDBUS_IOC_MAGIC, 0x80, int *),
+ KDBUS_CMD_MEMFD_SIZE_GET = _IOR(KDBUS_IOC_MAGIC, 0x81, __u64 *),
+ KDBUS_CMD_MEMFD_SIZE_SET = _IOW(KDBUS_IOC_MAGIC, 0x82, __u64 *),
+ KDBUS_CMD_MEMFD_SEAL_GET = _IOR(KDBUS_IOC_MAGIC, 0x83, int *),
+ KDBUS_CMD_MEMFD_SEAL_SET = _IO(KDBUS_IOC_MAGIC, 0x84),
+};
+#endif
diff --git a/glib/gmain.c b/glib/gmain.c
index 68a7f8e..1746762 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -3692,7 +3692,14 @@ g_main_context_iterate (GMainContext *context,
if (!block)
timeout = 0;
-
+
+ #ifdef KDBUS_DEBUG
+ g_print (" KDBUS_DEBUG: nfds=%d\n",nfds);
+ g_print (" KDBUS_DEBUG: fd[0]=%d\n",fds[0].fd);
+ g_print (" KDBUS_DEBUG: fd[1]=%d\n",fds[1].fd);
+ g_print (" KDBUS_DEBUG: fd[2]=%d\n",fds[2].fd);
+ #endif
+
g_main_context_poll (context, timeout, max_priority, fds, nfds);
some_ready = g_main_context_check (context, max_priority, fds, nfds);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]