[sysprof] sysprofd: start on port to GDBusConnection
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] sysprofd: start on port to GDBusConnection
- Date: Wed, 29 May 2019 22:17:02 +0000 (UTC)
commit ed48eadd0818e3300cbd33dd67630526dc8e367a
Author: Christian Hergert <chergert redhat com>
Date: Wed May 8 18:45:05 2019 -0700
sysprofd: start on port to GDBusConnection
This will help us reduce a lot of code and eventually make some things
more asynchronous to allow for interactive authorization.
src/sysprofd/ipc-service-impl.c | 135 +++++++++
src/sysprofd/ipc-service-impl.h | 33 ++
src/sysprofd/meson.build | 16 +-
src/sysprofd/org.gnome.Sysprof2.xml | 39 ---
src/sysprofd/org.gnome.Sysprof3.Service.xml | 54 ++++
src/sysprofd/sd-bus-helper.c | 188 ------------
src/sysprofd/sd-bus-helper.h | 36 ---
src/sysprofd/sysprofd.c | 453 +++++-----------------------
8 files changed, 307 insertions(+), 647 deletions(-)
---
diff --git a/src/sysprofd/ipc-service-impl.c b/src/sysprofd/ipc-service-impl.c
new file mode 100644
index 0000000..d8ef8d7
--- /dev/null
+++ b/src/sysprofd/ipc-service-impl.c
@@ -0,0 +1,135 @@
+/* ipc-service-impl.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ipc-service-impl"
+
+#include "config.h"
+
+#include "ipc-service-impl.h"
+
+struct _IpcServiceImpl
+{
+ IpcServiceSkeleton parent_instance;
+};
+
+static gboolean
+ipc_service_impl_handle_list_processes (IpcService *service,
+ GDBusMethodInvocation *invocation)
+{
+ g_autoptr(GDir) dir = NULL;
+ g_autoptr(GArray) pids = NULL;
+ const gchar *name;
+
+ g_assert (IPC_IS_SERVICE_IMPL (service));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ if (!(dir = g_dir_open ("/proc/", 0, NULL)))
+ {
+ g_dbus_method_invocation_return_error (g_steal_pointer (&invocation),
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FILE_NOT_FOUND,
+ "Failed to access /proc");
+ return TRUE;
+ }
+
+ pids = g_array_new (FALSE, FALSE, sizeof (gint32));
+
+ while ((name = g_dir_read_name (dir)))
+ {
+ if (g_ascii_isalnum (*name))
+ {
+ gchar *endptr = NULL;
+ gint64 val = g_ascii_strtoll (name, &endptr, 10);
+
+ if (endptr != NULL && *endptr == 0 && val < G_MAXINT && val >= 0)
+ {
+ gint32 v32 = val;
+ g_array_append_val (pids, v32);
+ }
+ }
+ }
+
+ ipc_service_complete_list_processes (service,
+ g_steal_pointer (&invocation),
+ g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
+ pids->data,
+ pids->len,
+ sizeof (gint32)));
+
+ return TRUE;
+}
+
+static gboolean
+ipc_service_impl_handle_get_proc_file (IpcService *service,
+ GDBusMethodInvocation *invocation,
+ const gchar *path)
+{
+ g_autofree gchar *canon = NULL;
+ g_autofree gchar *contents = NULL;
+ gsize len;
+
+ g_assert (IPC_IS_SERVICE_IMPL (service));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ canon = g_canonicalize_filename (path, "/proc/");
+
+ if (!g_str_has_prefix (canon, "/proc/"))
+ g_dbus_method_invocation_return_error (g_steal_pointer (&invocation),
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "File is not within /proc/");
+ else if (!g_file_get_contents (canon, &contents, &len, NULL))
+ g_dbus_method_invocation_return_error (g_steal_pointer (&invocation),
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FILE_NOT_FOUND,
+ "Failed to locate the file");
+ else
+ ipc_service_complete_get_proc_file (service,
+ g_steal_pointer (&invocation),
+ contents);
+
+ return TRUE;
+}
+
+static void
+init_service_iface (IpcServiceIface *iface)
+{
+ iface->handle_list_processes = ipc_service_impl_handle_list_processes;
+ iface->handle_get_proc_file = ipc_service_impl_handle_get_proc_file;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IpcServiceImpl, ipc_service_impl, IPC_TYPE_SERVICE_SKELETON,
+ G_IMPLEMENT_INTERFACE (IPC_TYPE_SERVICE, init_service_iface))
+
+static void
+ipc_service_impl_class_init (IpcServiceImplClass *klass)
+{
+}
+
+static void
+ipc_service_impl_init (IpcServiceImpl *self)
+{
+}
+
+IpcService *
+ipc_service_impl_new (void)
+{
+ return g_object_new (IPC_TYPE_SERVICE_IMPL, NULL);
+}
diff --git a/src/sysprofd/ipc-service-impl.h b/src/sysprofd/ipc-service-impl.h
new file mode 100644
index 0000000..b56c6a6
--- /dev/null
+++ b/src/sysprofd/ipc-service-impl.h
@@ -0,0 +1,33 @@
+/* ipc-service-impl.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ipc-service.h"
+
+G_BEGIN_DECLS
+
+#define IPC_TYPE_SERVICE_IMPL (ipc_service_impl_get_type())
+
+G_DECLARE_FINAL_TYPE (IpcServiceImpl, ipc_service_impl, IPC, SERVICE_IMPL, IpcServiceSkeleton)
+
+IpcService *ipc_service_impl_new (void);
+
+G_END_DECLS
diff --git a/src/sysprofd/meson.build b/src/sysprofd/meson.build
index 9fb793e..4ddc856 100644
--- a/src/sysprofd/meson.build
+++ b/src/sysprofd/meson.build
@@ -1,10 +1,15 @@
if get_option('with_sysprofd') == 'bundled'
+ipc_service_src = gnome.gdbus_codegen('ipc-service',
+ sources: 'org.gnome.Sysprof3.Service.xml',
+ interface_prefix: 'org.gnome.Sysprof3.',
+ namespace: 'Ipc',
+)
+
sysprofd_sources = [
'sysprofd.c',
- 'sd-bus-helper.c',
- 'sd-bus-helper.h',
- '../libsysprof/sysprof-kallsyms.c',
+ 'ipc-service-impl.c',
+ ipc_service_src,
]
pkglibexecdir = join_paths(get_option('prefix'), get_option('libexecdir'))
@@ -12,6 +17,8 @@ pkglibexecdir = join_paths(get_option('prefix'), get_option('libexecdir'))
sysprofd_deps = [
dependency('libsystemd', version: '>=222'),
dependency('glib-2.0', version: glib_req_version),
+ dependency('gio-2.0', version: glib_req_version),
+ dependency('gio-unix-2.0', version: glib_req_version),
]
sysprofd = executable('sysprofd', sysprofd_sources,
@@ -19,9 +26,6 @@ sysprofd = executable('sysprofd', sysprofd_sources,
install: true,
install_dir: pkglibexecdir,
pie: true,
- include_directories: [include_directories('.'),
- '../libsysprof',
- libsysprof_capture_include_dirs],
)
sysprofdconf = configuration_data()
diff --git a/src/sysprofd/org.gnome.Sysprof3.Service.xml b/src/sysprofd/org.gnome.Sysprof3.Service.xml
new file mode 100644
index 0000000..0f6d6b4
--- /dev/null
+++ b/src/sysprofd/org.gnome.Sysprof3.Service.xml
@@ -0,0 +1,54 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.gnome.Sysprof3.Service">
+ <!--
+ PerfEventOpen:
+ @options: key-value pair of attributes for the perf_event_open() syscall.
+ @pid: the process id to monitor, or -1 for system-wide.
+ @cpu: affinity to cpu.
+ @flags: flags for perf_event_open() syscall.
+ @perf_stream_fd: (out): A fd to communicate with perf.
+
+ Performs the perf_event_open() syscall with elevated privileges and passes
+ the resulting fd back to the calling process.
+ -->
+ <method name="PerfEventOpen">
+ <arg name="options" type="a{sv}" direction="in"/>
+ <arg name="pid" type="i" direction="in"/>
+ <arg name="cpu" type="i" direction="in"/>
+ <arg name="flags" type="t" direction="in"/>
+ <arg name="perf_stream_fd" type="h" direction="out"/>
+ </method>
+
+ <!--
+ GetProcFile:
+ @path: the path including "/proc/" prefix.
+
+ Gets a file from /proc.
+
+ The file must be a C-string (no embedded NUL bytes) but need not be UTF-8.
+
+ Returns: an array of bytes.
+
+ Since: 3.34
+ -->
+ <method name="GetProcFile">
+ <arg name="path" type="ay" direction="in"/>
+ <arg name="contents" type="ay" direction="out"/>
+ </method>
+
+ <!--
+ ListProcesses:
+
+ List the processes on the system.
+
+ Returns: an array of 32-bit integers
+
+ Since: 3.34
+ -->
+ <method name="ListProcesses">
+ <arg name="processes" type="ai" direction="out"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/sysprofd/sysprofd.c b/src/sysprofd/sysprofd.c
index d876fea..fc94458 100644
--- a/src/sysprofd/sysprofd.c
+++ b/src/sysprofd/sysprofd.c
@@ -1,6 +1,6 @@
/* sysprofd.c
*
- * Copyright 2016 Christian Hergert <christian hergert me>
+ * Copyright 2019 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,413 +14,110 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
-#include "config.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <glib.h>
-#include <linux/capability.h>
-#include <linux/perf_event.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/syscall.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "sd-bus-helper.h"
-
-#include "sysprof-kallsyms.h"
-
-#define BUS_TIMEOUT_USEC (1000000L * 10L)
-
-#if 0
-#define GOTO(l) do { \
- fprintf (stderr, "GOTO: %s:%d: " #l "\n", __FUNCTION__, __LINE__); \
- goto l; \
-} while (0)
-#else
-#define GOTO(l) goto l
-#endif
-
-static int
-sysprofd_get_kernel_symbols (sd_bus_message *msg,
- void *user_data,
- sd_bus_error *error)
-{
- g_autoptr(SysprofKallsyms) kallsyms = NULL;
- sd_bus_message *reply = NULL;
- const gchar *name;
- guint64 addr;
- guint8 type;
- bool challenge = false;
- int r;
-
- assert (msg);
- assert (error);
-
- /* Authorize peer */
- r = bus_test_polkit (msg,
- CAP_SYS_ADMIN,
- "org.gnome.sysprof2.get-kernel-symbols",
- NULL,
- UID_INVALID,
- &challenge,
- error);
+#define G_LOG_DOMAIN "sysprofd"
- if (r <= 0)
- fprintf (stderr, "GetKernelSymbols() Failure: %s\n", error->message);
-
- if (r < 0)
- return r;
- else if (r == 0)
- return -EACCES;
-
- if (!(kallsyms = sysprof_kallsyms_new (NULL)))
- {
- sd_bus_error_set (error,
- SD_BUS_ERROR_FILE_NOT_FOUND,
- "Failed to open /proc/kallsyms");
- return -ENOENT;
- }
-
- r = sd_bus_message_new_method_return (msg, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container (reply, 'a', "(tys)");
- if (r < 0)
- return r;
+#include "config.h"
- while (sysprof_kallsyms_next (kallsyms, &name, &addr, &type))
- sd_bus_message_append (reply, "(tys)", addr, type, name);
+#include <gio/gio.h>
- r = sd_bus_message_close_container (reply);
- if (r < 0)
- return r;
+#include "ipc-service.h"
+#include "ipc-service-impl.h"
- r = sd_bus_send (NULL, reply, NULL);
- sd_bus_message_unref (reply);
+#define BUS_NAME "org.gnome.Sysprof3"
+#define OBJECT_PATH "/org/gnome/Sysprof3"
+#define NAME_ACQUIRE_DELAY_SECS 3
- return r;
-}
+static GMainLoop *main_loop;
+static gboolean name_acquired;
+static gint exit_status = EXIT_SUCCESS;
-static int
-_perf_event_open (struct perf_event_attr *attr,
- pid_t pid,
- int cpu,
- int group_fd,
- unsigned long flags)
+static void
+name_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
{
- assert (attr != NULL);
-
- /* Quick sanity check */
- if (attr->sample_period < 100000 && attr->type != PERF_TYPE_TRACEPOINT)
- return -EINVAL;
-
- return syscall (__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
+ g_message ("Acquired Bus Name: %s", name);
+ name_acquired = TRUE;
}
-static int
-sysprofd_perf_event_open (sd_bus_message *msg,
- void *user_data,
- sd_bus_error *error)
+static void
+name_lost_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
{
- struct perf_event_attr attr = { 0 };
- sd_bus_message *reply = NULL;
- uint64_t flags = 0;
- int disabled = 0;
- int32_t wakeup_events = 149;
- int32_t cpu = -1;
- int32_t pid = -1;
- bool challenge = false;
- int32_t type = 0;
- uint64_t sample_period = 0;
- uint64_t sample_type = 0;
- uint64_t config = 0;
- int clockid = CLOCK_MONOTONIC_RAW;
- int comm = 0;
- int mmap_ = 0;
- int task = 0;
- int exclude_idle = 0;
- int fd = -1;
- int use_clockid = 0;
- int sample_id_all = 0;
- int r;
-
- assert (msg);
-
- r = sd_bus_message_enter_container (msg, SD_BUS_TYPE_ARRAY, "{sv}");
- if (r < 0)
- return r;
-
- for (;;)
+ /* Exit if we lost the name */
+ if (g_strcmp0 (name, BUS_NAME) == 0)
{
- const char *name = NULL;
-
- r = sd_bus_message_enter_container (msg, SD_BUS_TYPE_DICT_ENTRY, "sv");
- if (r < 0)
- return r;
-
- if (r == 0)
- break;
-
- r = sd_bus_message_read (msg, "s", &name);
- if (r < 0)
- goto cleanup;
-
- r = sd_bus_message_enter_container (msg, SD_BUS_TYPE_VARIANT, NULL);
- if (r < 0)
- goto cleanup;
-
- if (strcmp (name, "disabled") == 0)
- {
- r = sd_bus_message_read (msg, "b", &disabled);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "wakeup_events") == 0)
- {
- r = sd_bus_message_read (msg, "u", &wakeup_events);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "sample_id_all") == 0)
- {
- r = sd_bus_message_read (msg, "b", &sample_id_all);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "clockid") == 0)
- {
- r = sd_bus_message_read (msg, "i", &clockid);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "comm") == 0)
- {
- r = sd_bus_message_read (msg, "b", &comm);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "exclude_idle") == 0)
- {
- r = sd_bus_message_read (msg, "b", &exclude_idle);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "mmap") == 0)
- {
- r = sd_bus_message_read (msg, "b", &mmap_);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "config") == 0)
- {
- r = sd_bus_message_read (msg, "t", &config);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "sample_period") == 0)
- {
- r = sd_bus_message_read (msg, "t", &sample_period);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "sample_type") == 0)
- {
- r = sd_bus_message_read (msg, "t", &sample_type);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "task") == 0)
- {
- r = sd_bus_message_read (msg, "b", &task);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "type") == 0)
- {
- r = sd_bus_message_read (msg, "u", &type);
- if (r < 0)
- GOTO (cleanup);
- }
- else if (strcmp (name, "use_clockid") == 0)
- {
- r = sd_bus_message_read (msg, "b", &use_clockid);
- if (r < 0)
- GOTO (cleanup);
- }
-
- r = sd_bus_message_exit_container (msg);
- if (r < 0)
- goto cleanup;
-
- sd_bus_message_exit_container (msg);
- if (r < 0)
- goto cleanup;
-
- cleanup:
- if (r < 0)
- return r;
+ g_message ("Lost Bus Name: %s, exiting.", name);
+ name_acquired = FALSE;
+ g_main_loop_quit (main_loop);
}
+}
- r = sd_bus_message_exit_container (msg);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read (msg, "iit", &pid, &cpu, &flags);
- if (r < 0)
- return r;
-
- if (pid < -1 || cpu < -1)
- return -EINVAL;
-
- r = sd_bus_message_new_method_return (msg, &reply);
- if (r < 0)
- return r;
-
- /* Authorize peer */
- r = bus_test_polkit (msg,
- CAP_SYS_ADMIN,
- "org.gnome.sysprof2.perf-event-open",
- NULL,
- UID_INVALID,
- &challenge,
- error);
- if (r < 0)
- return r;
- else if (r == 0)
- return -EACCES;
-
- attr.comm = !!comm;
- attr.config = config;
- attr.disabled = disabled;
- attr.exclude_idle = !!exclude_idle;
- attr.mmap = !!mmap_;
- attr.sample_id_all = sample_id_all;
- attr.sample_period = sample_period;
- attr.sample_type = sample_type;
- attr.task = !!task;
- attr.type = type;
- attr.wakeup_events = wakeup_events;
-
-#ifdef HAVE_PERF_CLOCKID
- if (!use_clockid || clockid < 0)
- attr.clockid = CLOCK_MONOTONIC_RAW;
- else
- attr.clockid = clockid;
- attr.use_clockid = use_clockid;
-#endif
-
- attr.size = sizeof attr;
-
- fd = _perf_event_open (&attr, pid, cpu, -1, 0);
- if (fd < 0)
+static gboolean
+wait_for_acquire_timeout_cb (gpointer data)
+{
+ if (!name_acquired)
{
- fprintf (stderr,
- "Failed to open perf event stream: %s\n",
- strerror (errno));
- return -EINVAL;
+ exit_status = EXIT_FAILURE;
+ g_critical ("Failed to acquire name on bus after %d seconds, exiting.",
+ NAME_ACQUIRE_DELAY_SECS);
+ g_main_loop_quit (main_loop);
}
- sd_bus_message_append_basic (reply, SD_BUS_TYPE_UNIX_FD, &fd);
- r = sd_bus_send (NULL, reply, NULL);
- sd_bus_message_unref (reply);
-
- close (fd);
-
- return r;
+ return G_SOURCE_REMOVE;
}
-static const sd_bus_vtable sysprofd_vtable[] = {
- SD_BUS_VTABLE_START (0),
- SD_BUS_METHOD ("PerfEventOpen", "a{sv}iit", "h", sysprofd_perf_event_open, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD ("GetKernelSymbols", "", "a(tys)", sysprofd_get_kernel_symbols, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
-};
-
-int
-main (int argc,
- char *argv[])
+gint
+main (gint argc,
+ gchar *argv[])
{
- sd_bus_slot *slot = NULL;
- sd_bus *bus = NULL;
- int r;
+ g_autoptr(GDBusConnection) bus = NULL;
+ g_autoptr(GError) error = NULL;
+ GBusType bus_type = G_BUS_TYPE_SYSTEM;
- /* Connect to the system bus */
- r = sd_bus_default_system (&bus);
- if (r < 0)
- {
- fprintf (stderr,
- "Failed to connect to system bus: %s\n",
- strerror (-r));
- goto failure;
- }
+ g_set_prgname ("sysprofd");
+ g_set_application_name ("sysprofd");
- /* Install our object */
- r = sd_bus_add_object_vtable (bus,
- &slot,
- "/org/gnome/Sysprof2",
- "org.gnome.Sysprof2",
- sysprofd_vtable,
- NULL);
- if (r < 0)
- {
- fprintf (stderr,
- "Failed to install object on bus: %s\n",
- strerror (-r));
- goto failure;
- }
+ if (g_getenv ("SYSPROFD_USE_SESSION_BUS"))
+ bus_type = G_BUS_TYPE_SESSION;
- /* Request our well-known name on the bus */
- r = sd_bus_request_name (bus, "org.gnome.Sysprof2", 0);
- if (r < 0)
- {
- fprintf (stderr,
- "Failed to register name on the bus: %s\n",
- strerror (-r));
- goto failure;
- }
+ main_loop = g_main_loop_new (NULL, FALSE);
- for (;;)
+ if ((bus = g_bus_get_sync (bus_type, NULL, &error)))
{
- /* Process requests */
- r = sd_bus_process (bus, NULL);
- if (r < 0)
- {
- fprintf (stderr,
- "Failed to process bus: %s\n",
- strerror (-r));
- goto failure;
- }
-
- /* If we processed a request, continue processing */
- if (r > 0)
- continue;
+ g_autoptr(IpcService) service = ipc_service_impl_new ();
- /* Wait for the next request to process */
- r = sd_bus_wait (bus, BUS_TIMEOUT_USEC);
- if (r < 0)
+ if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service),
+ bus,
+ OBJECT_PATH,
+ &error))
{
- fprintf (stderr,
- "Failed to wait on bus: %s\n",
- strerror (-r));
- goto failure;
+ g_bus_own_name_on_connection (bus,
+ BUS_NAME,
+ (G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE),
+ name_acquired_cb,
+ name_lost_cb,
+ NULL,
+ NULL);
+ g_timeout_add_seconds (NAME_ACQUIRE_DELAY_SECS,
+ wait_for_acquire_timeout_cb,
+ NULL);
+ g_main_loop_run (main_loop);
+ g_main_loop_unref (main_loop);
+
+ return exit_status;
}
-
- /*
- * If we timed out, we can expire, we will be auto-started by
- * systemd or dbus on the next activation request.
- */
- if (r == 0)
- break;
}
-failure:
- sd_bus_slot_unref (slot);
- sd_bus_unref (bus);
+ g_error ("Failed to setup system bus: %s", error->message);
+
+ g_main_loop_unref (main_loop);
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ return EXIT_FAILURE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]