diff --git a/src/org.gnome.Sysprof3.Service.xml b/src/org.gnome.Sysprof3.Service.xml index c4b4a86b..1be4e137 100644 --- a/src/org.gnome.Sysprof3.Service.xml +++ b/src/org.gnome.Sysprof3.Service.xml @@ -52,5 +52,25 @@ + + + + + diff --git a/src/sysprofd/ipc-service-impl.c b/src/sysprofd/ipc-service-impl.c index 9458db00..c61d33b7 100644 --- a/src/sysprofd/ipc-service-impl.c +++ b/src/sysprofd/ipc-service-impl.c @@ -188,12 +188,87 @@ ipc_service_impl_g_authorize_method (GDBusInterfaceSkeleton *skeleton, return ret; } +static void +add_pid_proc_file_to (gint pid, + const gchar *name, + GVariantDict *dict) +{ + g_autofree gchar *path = NULL; + g_autofree gchar *contents = NULL; + gsize len; + + g_assert (pid > -1); + g_assert (name != NULL); + g_assert (dict != NULL); + + path = g_strdup_printf ("/proc/%d/%s", pid, name); + + if (g_file_get_contents (path, &contents, &len, NULL)) + g_variant_dict_insert (dict, name, "s", contents); +} + +static gboolean +ipc_service_impl_handle_get_process_info (IpcService *service, + GDBusMethodInvocation *invocation, + const gchar *attributes) +{ + GVariantBuilder builder; + g_autofree gint *processes = NULL; + gsize n_processes = 0; + gboolean want_statm; + gboolean want_cmdline; + gboolean want_maps; + gboolean want_mountinfo; + + g_assert (IPC_IS_SERVICE (service)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (attributes != NULL); + + want_statm = !!strstr (attributes, "statm"); + want_cmdline = !!strstr (attributes, "cmdline"); + want_maps = !!strstr (attributes, "maps"); + want_mountinfo = !!strstr (attributes, "mountinfo"); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + if (helpers_list_processes (&processes, &n_processes)) + { + for (guint i = 0; i < n_processes; i++) + { + gint pid = processes[i]; + GVariantDict dict; + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "pid", "i", pid); + + if (want_statm) + add_pid_proc_file_to (pid, "statm", &dict); + + if (want_cmdline) + add_pid_proc_file_to (pid, "cmdline", &dict); + + if (want_maps) + add_pid_proc_file_to (pid, "maps", &dict); + + if (want_mountinfo) + add_pid_proc_file_to (pid, "mountinfo", &dict); + + g_variant_builder_add (&builder, "a{sv}", g_variant_dict_end (&dict)); + } + } + + ipc_service_complete_get_process_info (service, invocation, g_variant_builder_end (&builder)); + + 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; iface->handle_perf_event_open = ipc_service_impl_handle_perf_event_open; + iface->handle_get_process_info = ipc_service_impl_handle_get_process_info; } G_DEFINE_TYPE_WITH_CODE (IpcServiceImpl, ipc_service_impl, IPC_TYPE_SERVICE_SKELETON,