summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--hw/systemd.c177
-rw-r--r--hw/systemd.h37
-rwxr-xr-xpackaging/libdevice-node.spec1
4 files changed, 217 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c4e82d..bdba1d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,7 +12,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/${INC_DIR})
INCLUDE(FindPkgConfig)
-pkg_check_modules(rpkgs REQUIRED dlog vconf glib-2.0)
+pkg_check_modules(rpkgs REQUIRED dlog vconf glib-2.0 libsystemd)
FOREACH(flag ${rpkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -40,7 +40,7 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS} "-ldl")
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION})
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-ADD_LIBRARY(hwcommon SHARED hw/common.c)
+ADD_LIBRARY(hwcommon SHARED hw/common.c hw/systemd.c)
TARGET_LINK_LIBRARIES(hwcommon ${rpkgs_LDFLAGS} "-ldl")
SET_TARGET_PROPERTIES(hwcommon PROPERTIES SOVERSION ${VERSION})
INSTALL(TARGETS hwcommon DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/hw/systemd.c b/hw/systemd.c
new file mode 100644
index 0000000..97d32ce
--- /dev/null
+++ b/hw/systemd.c
@@ -0,0 +1,177 @@
+/*
+ * libdevice-node
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <hw/systemd.h>
+#include <systemd/sd-bus.h>
+
+#define SYSTEMD_DBUS_SERVICE "org.freedesktop.systemd1"
+#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1"
+#define SYSTEMD_DBUS_MANAGER_IFACE "org.freedesktop.systemd1.Manager"
+
+#define SYSTEMD_SOCKET_SUFFIX ".socket"
+#define MAX_SOCKET_NAME 1024
+
+#define SYSTEMD_SERVICE_SUFFIX ".service"
+#define MAX_SERVICE_NAME 1024
+
+#ifndef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+#endif
+
+struct bus_ctx {
+ const char *unit;
+ sd_event *loop;
+};
+
+static int socket_started(sd_bus_message *m, void *userdata,
+ sd_bus_error *ret_error)
+{
+ struct bus_ctx *ctx = userdata;
+ char *signal_unit;
+ int ret;
+
+ ret = sd_bus_message_read(m, "uoss", NULL, NULL, &signal_unit, NULL);
+ if (ret < 0) {
+ sd_event_exit(ctx->loop, ret);
+ return 0;
+ }
+
+ if (!strcmp(signal_unit, ctx->unit))
+ sd_event_exit(ctx->loop, 0);
+
+ return 0;
+}
+
+static int systemd_unit_interface_sync(const char *method, const char *unit,
+ bool wait)
+{
+ sd_bus *bus = NULL;
+ sd_event *loop = NULL;
+ struct bus_ctx ctx;
+ int ret;
+
+ ret = sd_bus_open_system(&bus);
+ if (ret < 0)
+ return ret;
+
+ if (wait) {
+ ret = sd_event_new(&loop);
+ if (ret < 0)
+ goto unref_bus;
+
+ ctx.loop = loop;
+ ctx.unit = unit;
+
+ ret = sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL);
+ if (ret < 0)
+ goto unref_loop;
+
+ ret = sd_bus_add_match(bus, NULL,
+ "type='signal',"
+ "sender='" SYSTEMD_DBUS_SERVICE "',"
+ "interface='" SYSTEMD_DBUS_MANAGER_IFACE "',"
+ "member='JobRemoved',"
+ "path_namespace='" SYSTEMD_DBUS_PATH "'",
+ socket_started,
+ &ctx);
+ if (ret < 0)
+ goto unref_loop;
+ }
+
+
+ ret = sd_bus_call_method(bus,
+ SYSTEMD_DBUS_SERVICE,
+ SYSTEMD_DBUS_PATH,
+ SYSTEMD_DBUS_MANAGER_IFACE,
+ method,
+ NULL,
+ NULL,
+ "ss",
+ unit,
+ "replace");
+ if (ret < 0)
+ goto unref_loop;
+
+ if (wait)
+ ret = sd_event_loop(loop);
+
+unref_loop:
+ if (wait)
+ sd_event_unref(loop);
+unref_bus:
+ sd_bus_unref(bus);
+ return ret;
+}
+
+EXPORT int systemd_start_service(const char *service_name)
+{
+ char unit[MAX_SERVICE_NAME];
+ int ret;
+
+ ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+ service_name);
+ if (ret < 0 || ret >= sizeof(unit))
+ return -ENAMETOOLONG;
+
+ return systemd_unit_interface_sync("StartUnit", unit, true);
+}
+
+EXPORT int systemd_stop_service(const char *service_name)
+{
+ char unit[MAX_SERVICE_NAME];
+ int ret;
+
+ ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+ service_name);
+ if (ret < 0 || ret >= sizeof(unit))
+ return -ENAMETOOLONG;
+
+ return systemd_unit_interface_sync("StopUnit", unit, false);
+}
+
+EXPORT int systemd_start_socket(const char *socket_name)
+{
+ char unit[MAX_SOCKET_NAME];
+ int ret;
+
+ ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX,
+ socket_name);
+ if (ret < 0 || ret >= sizeof(unit))
+ return -ENAMETOOLONG;
+
+
+ return systemd_unit_interface_sync("StartUnit", unit, true);
+}
+
+EXPORT int systemd_stop_socket(const char *socket_name)
+{
+ char unit[MAX_SOCKET_NAME];
+ int ret;
+
+ ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX,
+ socket_name);
+ if (ret < 0 || ret >= sizeof(unit))
+ return -ENAMETOOLONG;
+
+ return systemd_unit_interface_sync("StopUnit", unit, false);
+}
diff --git a/hw/systemd.h b/hw/systemd.h
new file mode 100644
index 0000000..28ce944
--- /dev/null
+++ b/hw/systemd.h
@@ -0,0 +1,37 @@
+/*
+ * libdevice-node
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __HW_SYSTEMD_H__
+#define __HW_SYSTEMD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int systemd_start_service(const char *service_name);
+int systemd_stop_service(const char *service_name);
+int systemd_start_socket(const char *socket_name);
+int systemd_stop_socket(const char *socket_name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __HW_SYSTEMD_H__ */
+
diff --git a/packaging/libdevice-node.spec b/packaging/libdevice-node.spec
index 0aef2a2..bdfd0de 100755
--- a/packaging/libdevice-node.spec
+++ b/packaging/libdevice-node.spec
@@ -13,6 +13,7 @@ BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(gmock)
BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(libsystemd)
%description
development package of library to control OAL APIs