[sysprof/wip/chergert/sysprof-3] sysprofd: start on port to GDBusConnection



commit 5575bd7569c23eaa88b6b263d72125dab96a0a39
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]