Beginning of kdbus support
authorRadoslaw Pajak <r.pajak@samsung.com>
Tue, 25 Jun 2013 11:34:15 +0000 (13:34 +0200)
committerRadoslaw Pajak <r.pajak@samsung.com>
Tue, 25 Jun 2013 11:34:15 +0000 (13:34 +0200)
Working:
- connecting to the bus
- bus registration (hello message)
Tested on the serverClient program made by L.Stempien
Not working:
- all the rest

dbus/.cproject [new file with mode: 0644]
dbus/.project [new file with mode: 0644]
dbus/Makefile.am
dbus/dbus-bus.c
dbus/dbus-bus.h
dbus/dbus-connection.c
dbus/dbus-transport-kdbus.c [new file with mode: 0644]
dbus/dbus-transport-kdbus.h [new file with mode: 0644]
dbus/dbus-transport.c
dbus/kdbus.h [new file with mode: 0644]

diff --git a/dbus/.cproject b/dbus/.cproject
new file mode 100644 (file)
index 0000000..d0b6568
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.456749915">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.456749915" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.456749915" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="cdt.managedbuild.toolchain.gnu.base.456749915.2116564601" name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.1084026941" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.483630444" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder buildPath="${workspace_loc:/libdbus}" id="cdt.managedbuild.target.gnu.builder.base.1295573544" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.933685167" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.426313899" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.553326917" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1587182930" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.870757898" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.2082327427" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1094477497" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1676617176" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.240122192" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.2060489052" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="libdbus.null.6942114" name="libdbus"/>
+       </storageModule>
+       <storageModule moduleId="refreshScope" versionNumber="1">
+               <resource resourceType="PROJECT" workspacePath="/libdbus"/>
+       </storageModule>
+</cproject>
diff --git a/dbus/.project b/dbus/.project
new file mode 100644 (file)
index 0000000..598740d
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>dbus</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                               <dictionary>
+                                       <key>?name?</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.append_environment</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildArguments</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildCommand</key>
+                                       <value>make</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildLocation</key>
+                                       <value>${workspace_loc:/libdbus}</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+                                       <value>clean</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.contents</key>
+                                       <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+                                       <value>false</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.stopOnError</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+                                       <value>true</value>
+                               </dictionary>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.nativecpp.apichecker.core.builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+               <nature>org.tizen.nativecpp.apichecker.core.tizenCppNature</nature>
+       </natures>
+</projectDescription>
index 90c2c90..7520382 100644 (file)
@@ -106,6 +106,8 @@ DBUS_SHARED_arch_sources =                  \
        dbus-sysdeps-pthread.c                  \
        dbus-transport-unix.c                   \
        dbus-transport-unix.h                   \
+       dbus-transport-kdbus.c                  \
+       dbus-transport-kdbus.h                  \
        dbus-userdb.c                           \
        dbus-userdb.h                           \
        sd-daemon.c                             \
index 7b5f09a..6622595 100644 (file)
@@ -31,6 +31,8 @@
 #include "dbus-threads-internal.h"
 #include "dbus-connection-internal.h"
 #include "dbus-string.h"
+#include "dbus-transport-kdbus.h"
+
 
 /**
  * @defgroup DBusBus Message bus APIs
@@ -485,6 +487,8 @@ internal_bus_get (DBusBusType  type,
       goto out;
     }
 
+  _dbus_verbose (" !!! dbus_connection_open finished successfully   !!!! \n");  //todo RP to be removed
+
   if (!dbus_bus_register (connection, error))
     {
       _dbus_connection_close_possibly_shared (connection);
@@ -598,6 +602,67 @@ dbus_bus_get_private (DBusBusType  type,
   return internal_bus_get (type, TRUE, error);
 }
 
+/* kdbus add-on [RP] - bus register for kdbus
+ * Function checks if the method is kdbus. If yes - it registers on the bus, if no - does nothing and returns TRUE
+ * Must be invoked before dbus_bus_register because in kdbus it's realized in different manner
+ * and dbus_bus_register can not be used for that.
+ * It does not collide with dbus_bus_register because dbus_bus_register at the beginning checks
+ * whether unique_name has already been assigned and doesn't try to do it again.
+ */
+dbus_bool_t dbus_bus_register_kdbus(DBusAddressEntry *entry, DBusConnection *connection, DBusError *error)
+{
+       dbus_bool_t retval = TRUE;
+       const char *method;
+
+       method = dbus_address_entry_get_method (entry);
+       _dbus_assert (method != NULL);
+
+       if (strcmp (method, "kdbus") == 0)
+    {
+               BusData *bd;
+
+               _dbus_return_val_if_fail (connection != NULL, FALSE);
+               _dbus_return_val_if_error_is_set (error, FALSE);
+
+               retval = FALSE;
+
+               if (!_DBUS_LOCK (bus_datas))
+               {
+                 _DBUS_SET_OOM (error);
+                 /* do not "goto out", that would try to unlock */
+                 return FALSE;
+               }
+
+               bd = ensure_bus_data (connection);
+               if (bd == NULL)
+               {
+                 _DBUS_SET_OOM (error);
+                 goto out;
+               }
+
+               if (bd->unique_name != NULL)
+               {
+                 _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
+                                                bd->unique_name);
+                 /* Success! */
+                 retval = TRUE;
+                 goto out;
+               }
+
+               if(!bus_register_kdbus(&bd->unique_name, connection, error))
+                       goto out;
+
+               retval = TRUE;
+
+               out:
+               _DBUS_UNLOCK (bus_datas);
+
+               if (!retval)
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+    }
+       return retval;
+}
+
 /**
  * Registers a connection with the bus. This must be the first
  * thing an application does when connecting to the message bus.
@@ -652,7 +717,7 @@ dbus_bus_register (DBusConnection *connection,
                    DBusError      *error)
 {
   DBusMessage *message, *reply;
-  char *name;
+  char name[18];
   BusData *bd;
   dbus_bool_t retval;
 
@@ -707,7 +772,7 @@ dbus_bus_register (DBusConnection *connection,
                                    DBUS_TYPE_STRING, &name,
                                    DBUS_TYPE_INVALID))
     goto out;
-  
+
   bd->unique_name = _dbus_strdup (name);
   if (bd->unique_name == NULL)
     {
index 02a9571..2e6a216 100644 (file)
@@ -28,6 +28,7 @@
 #define DBUS_BUS_H
 
 #include <dbus/dbus-connection.h>
+#include "dbus-address.h"
 
 DBUS_BEGIN_DECLS
 
@@ -47,6 +48,10 @@ DBUS_EXPORT
 dbus_bool_t     dbus_bus_register         (DBusConnection *connection,
                                           DBusError      *error);
 DBUS_EXPORT
+dbus_bool_t            dbus_bus_register_kdbus   (DBusAddressEntry *entry,
+                                               DBusConnection *connection,
+                                               DBusError *error);
+DBUS_EXPORT
 dbus_bool_t     dbus_bus_set_unique_name  (DBusConnection *connection,
                                           const char     *unique_name);
 DBUS_EXPORT
index 87cfeb0..bb51996 100644 (file)
@@ -44,6 +44,7 @@
 #include "dbus-threads-internal.h"
 #include "dbus-bus.h"
 #include "dbus-marshal-basic.h"
+#include "dbus-transport-kdbus.h"
 
 #ifdef DBUS_DISABLE_CHECKS
 #define TOOK_LOCK_CHECK(connection)
@@ -1843,6 +1844,22 @@ connection_try_from_address_entry (DBusAddressEntry *entry,
 #ifndef DBUS_DISABLE_CHECKS
   _dbus_assert (!connection->have_connection_lock);
 #endif
+
+  /* kdbus add-on [RP] - bus register for kdbus
+   * Function checks if the method is kdbus. If yes - it registers on the bus, if no - does nothing and returns TRUE
+   * Must be invoked before dbus_bus_register because in kdbus it's realized in different manner
+   * and dbus_bus_register can not be used for that.
+   * It does not collide with dbus_bus_register because dbus_bus_register at the beginning checks
+   * whether unique_name has already been assigned and doesn't try to do it again.
+   */
+
+  if(!dbus_bus_register_kdbus(entry, connection, error))
+  {
+         _dbus_connection_close_possibly_shared (connection);
+      dbus_connection_unref (connection);
+      connection = NULL;
+  }
+
   return connection;
 }
 
diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c
new file mode 100644 (file)
index 0000000..dfecc64
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * dbus-transport-kdbus.c
+ *
+ * Transport layer using kdbus
+ *
+ *  Created on: Jun 20, 2013
+ *      Author: r.pajak
+ *
+ *
+ */
+
+#include "dbus-transport.h"
+#include "dbus-transport-kdbus.h"
+#include <kdbus.h>
+#include "dbus-errors.h"
+#include <fcntl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+
+//todo poniższe do wywalenia po zaimplementowaniu vtable (_dbus_transport_new_for_socket)
+#include "dbus-transport-socket.h"
+
+int _dbus_connect_kdbus (const char *path, DBusError *error);
+DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error);
+
+
+/**
+ * Creates a connection to the kdbus bus
+  *
+ * This will set FD_CLOEXEC for the socket returned.
+ *
+ * @param path the path to UNIX domain socket
+ * @param error return location for error code
+ * @returns connection file descriptor or -1 on error
+ */
+int _dbus_connect_kdbus (const char *path, DBusError *error)
+{
+       int fd;
+
+       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+       _dbus_verbose ("connecting to kdbus bus %s\n", path);
+
+       fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
+       if (fd < 0)
+       {
+               dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
+               _DBUS_ASSERT_ERROR_IS_SET(error);
+               return -1;  //[RP] not needed here if commented block below is removed
+       }
+
+       /*if (!_dbus_set_fd_nonblocking (fd, error))
+    {
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+               _dbus_close (fd, NULL);
+               return -1;
+    }*/
+
+       return fd;
+}
+
+
+/**
+ * Creates a new transport for kdbus.
+ * This creates a client-side of a transport.
+ *
+ * @param path the path to the domain socket.
+ * @param error address where an error can be returned.
+ * @returns a new transport, or #NULL on failure.
+ */
+DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
+{
+       int fd;
+       DBusTransport *transport;
+       DBusString address;
+
+       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+       if (!_dbus_string_init (&address))
+    {
+               dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+               return NULL;
+    }
+
+       fd = -1;
+
+       if (!_dbus_string_append (&address, path))
+    {
+               dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+               goto failed_0;
+    }
+
+       fd = _dbus_connect_kdbus (path, error);
+//     fd = _dbus_connect_unix_socket (path, error);
+       if (fd < 0)
+    {
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+               goto failed_0;
+    }
+
+       _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
+
+       transport = _dbus_transport_new_for_socket (fd, NULL, &address);  //todo
+       if (transport == NULL)
+    {
+               dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+               goto failed_1;
+    }
+
+       _dbus_string_free (&address);
+
+       return transport;
+
+       failed_1:
+               _dbus_close_socket (fd, NULL);
+       failed_0:
+               _dbus_string_free (&address);
+       return NULL;
+}
+
+
+/**
+ * Opens kdbus transport.
+ *
+ * @param entry the address entry to try opening
+ * @param transport_p return location for the opened transport
+ * @param error error to be set
+ * @returns result of the attempt
+ */
+DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
+                                                          DBusTransport    **transport_p,
+                                                          DBusError         *error)
+{
+       const char *method;
+
+       method = dbus_address_entry_get_method (entry);
+       _dbus_assert (method != NULL);
+
+       if (strcmp (method, "kdbus") == 0)
+    {
+               const char *path = dbus_address_entry_get_value (entry, "path");
+
+               if (path == NULL)
+        {
+                       _dbus_set_bad_address (error, "kdbus", "path", NULL);
+                       return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
+        }
+
+        *transport_p = _dbus_transport_new_for_kdbus (path, error);
+
+        if (*transport_p == NULL)
+        {
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+               return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
+        }
+        else
+        {
+               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+               return DBUS_TRANSPORT_OPEN_OK;
+        }
+    }
+       else
+    {
+               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+               return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
+    }
+}
+
+dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, DBusError *error)
+{
+       dbus_bool_t retval = TRUE;
+       char name[18];
+       struct kdbus_cmd_hello hello;
+       int fd;
+
+       memset(&hello, 0, sizeof(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 = (16 * 1024LU * 1024LU);  //todo was: #define POOL_SIZE
+
+       if(!dbus_connection_get_socket(connection, &fd))
+       {
+               dbus_set_error (error, "failed to get fd for connection", NULL);
+               return FALSE;
+       }
+       if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
+       {
+               dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send  hello: %s", _dbus_strerror (errno));
+               return FALSE;
+       }
+
+       _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);  //todo [RP] can be removed after development
+       sprintf(name, "%llx", (unsigned long long)hello.id);
+       *unique_name = _dbus_strdup(name);
+       if (*unique_name == NULL)
+       {
+         _DBUS_SET_OOM (error);
+         return FALSE;
+       }
+
+       return retval;
+}
diff --git a/dbus/dbus-transport-kdbus.h b/dbus/dbus-transport-kdbus.h
new file mode 100644 (file)
index 0000000..1b1d98c
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include "dbus-transport.h"
+#include "dbus-transport-protected.h"
+#include "dbus-address.h"
+#include "dbus-errors.h"
+
+DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry, DBusTransport **transport_p, DBusError *error);
+dbus_bool_t bus_register_kdbus(char** uniqe_name, DBusConnection *connection, DBusError *error);
index c483d76..972f02c 100644 (file)
@@ -21,7 +21,7 @@
  *
  */
 
-#include <config.h>
+#include <../config.h>
 #include "dbus-transport-protected.h"
 #include "dbus-transport-unix.h"
 #include "dbus-transport-socket.h"
@@ -32,6 +32,8 @@
 #include "dbus-credentials.h"
 #include "dbus-mainloop.h"
 #include "dbus-message.h"
+
+#include "dbus-transport-kdbus.h"
 #ifdef DBUS_BUILD_TESTS
 #include "dbus-server-debug-pipe.h"
 #endif
@@ -347,6 +349,7 @@ static const struct {
 } open_funcs[] = {
   { _dbus_transport_open_socket },
   { _dbus_transport_open_platform_specific },
+  { _dbus_transport_open_kdbus },
   { _dbus_transport_open_autolaunch }
 #ifdef DBUS_BUILD_TESTS
   , { _dbus_transport_open_debug_pipe }
diff --git a/dbus/kdbus.h b/dbus/kdbus.h
new file mode 100644 (file)
index 0000000..4604eb3
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * 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_
+
+#ifndef __KERNEL__
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+#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;                                             \
+       }
+
+/* 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