[sysprof] libsysprof: add vfunc to modify spawn arguments
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] libsysprof: add vfunc to modify spawn arguments
- Date: Wed, 29 May 2019 22:41:37 +0000 (UTC)
commit c204081cc0b8c8753291e625ca98858d00de45f7
Author: Christian Hergert <chergert redhat com>
Date: Tue May 21 21:57:36 2019 -0700
libsysprof: add vfunc to modify spawn arguments
src/libsysprof/sysprof-local-profiler.c | 80 +++++++++++++++++++++++++--------
src/libsysprof/sysprof-source.c | 13 ++++++
src/libsysprof/sysprof-source.h | 19 +++++++-
3 files changed, 92 insertions(+), 20 deletions(-)
---
diff --git a/src/libsysprof/sysprof-local-profiler.c b/src/libsysprof/sysprof-local-profiler.c
index bcf57eb..3413d44 100644
--- a/src/libsysprof/sysprof-local-profiler.c
+++ b/src/libsysprof/sysprof-local-profiler.c
@@ -467,6 +467,25 @@ sysprof_local_profiler_finish_startup (SysprofLocalProfiler *self)
sysprof_local_profiler_stop (SYSPROF_PROFILER (self));
}
+static void
+sysprof_local_profiler_wait_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSubprocess *subprocess = (GSubprocess *)object;
+ g_autoptr(SysprofLocalProfiler) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (G_IS_SUBPROCESS (subprocess));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (SYSPROF_IS_LOCAL_PROFILER (self));
+
+ if (!g_subprocess_wait_finish (subprocess, result, &error))
+ g_warning ("Wait on subprocess failed: %s", error->message);
+
+ sysprof_local_profiler_stop (SYSPROF_PROFILER (self));
+}
+
static void
sysprof_local_profiler_authorize_cb (GObject *object,
GAsyncResult *result,
@@ -521,7 +540,10 @@ sysprof_local_profiler_authorize_cb (GObject *object,
if (priv->spawn && priv->spawn_argv && priv->spawn_argv[0])
{
- g_autoptr(GPtrArray) ar = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GPtrArray) env = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GPtrArray) argv = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GSubprocessLauncher) launcher = NULL;
+ g_autoptr(GSubprocess) subprocess = NULL;
GPid pid;
if (priv->spawn_inherit_environ)
@@ -529,41 +551,61 @@ sysprof_local_profiler_authorize_cb (GObject *object,
gchar **environ = g_get_environ ();
for (guint i = 0; environ[i]; i++)
- g_ptr_array_add (ar, environ[i]);
+ g_ptr_array_add (env, environ[i]);
g_free (environ);
}
if (priv->spawn_env)
{
for (guint i = 0; priv->spawn_env[i]; i++)
- g_ptr_array_add (ar, g_strdup (priv->spawn_env[i]));
+ g_ptr_array_add (env, g_strdup (priv->spawn_env[i]));
+ }
+
+ g_ptr_array_add (env, NULL);
+
+ launcher = g_subprocess_launcher_new (0);
+ g_subprocess_launcher_set_environ (launcher, (gchar **)env->pdata);
+ g_subprocess_launcher_set_cwd (launcher, g_get_home_dir ());
+
+ if (priv->spawn_argv)
+ {
+ for (guint i = 0; priv->spawn_argv[i]; i++)
+ g_ptr_array_add (argv, g_strdup (priv->spawn_argv[i]));
}
- g_ptr_array_add (ar, NULL);
-
- if (!g_spawn_async (g_get_home_dir (),
- priv->spawn_argv,
- (gchar **)ar->pdata,
- (G_SPAWN_SEARCH_PATH |
- G_SPAWN_STDOUT_TO_DEV_NULL |
- G_SPAWN_STDOUT_TO_DEV_NULL),
- NULL,
- NULL,
- &pid,
- &error))
- g_ptr_array_add (priv->failures, g_steal_pointer (&error));
+ for (guint i = 0; i < priv->sources->len; i++)
+ {
+ SysprofSource *source = g_ptr_array_index (priv->sources, i);
+ sysprof_source_modify_spawn (source, launcher, argv);
+ }
+
+ g_ptr_array_add (argv, NULL);
+
+ if (!(subprocess = g_subprocess_launcher_spawnv (launcher,
+ (const gchar * const *)argv->pdata,
+ &error)))
+ {
+ g_ptr_array_add (priv->failures, g_steal_pointer (&error));
+ }
else
- g_array_append_val (priv->pids, pid);
+ {
+ const gchar *ident = g_subprocess_get_identifier (subprocess);
+ pid = atoi (ident);
+ g_array_append_val (priv->pids, pid);
+ g_subprocess_wait_async (subprocess,
+ NULL,
+ sysprof_local_profiler_wait_cb,
+ g_object_ref (self));
+ }
}
for (guint i = 0; i < priv->sources->len; i++)
{
SysprofSource *source = g_ptr_array_index (priv->sources, i);
- guint j;
if (priv->whole_system == FALSE)
{
- for (j = 0; j < priv->pids->len; j++)
+ for (guint j = 0; j < priv->pids->len; j++)
{
GPid pid = g_array_index (priv->pids, GPid, j);
diff --git a/src/libsysprof/sysprof-source.c b/src/libsysprof/sysprof-source.c
index cece9c3..420cf14 100644
--- a/src/libsysprof/sysprof-source.c
+++ b/src/libsysprof/sysprof-source.c
@@ -139,3 +139,16 @@ sysprof_source_stop (SysprofSource *self)
if (SYSPROF_SOURCE_GET_IFACE (self)->stop)
SYSPROF_SOURCE_GET_IFACE (self)->stop (self);
}
+
+void
+sysprof_source_modify_spawn (SysprofSource *self,
+ GSubprocessLauncher *launcher,
+ GPtrArray *argv)
+{
+ g_return_if_fail (SYSPROF_IS_SOURCE (self));
+ g_return_if_fail (G_IS_SUBPROCESS_LAUNCHER (launcher));
+ g_return_if_fail (argv != NULL);
+
+ if (SYSPROF_SOURCE_GET_IFACE (self)->modify_spawn)
+ SYSPROF_SOURCE_GET_IFACE (self)->modify_spawn (self, launcher, argv);
+}
diff --git a/src/libsysprof/sysprof-source.h b/src/libsysprof/sysprof-source.h
index 896d237..31c8989 100644
--- a/src/libsysprof/sysprof-source.h
+++ b/src/libsysprof/sysprof-source.h
@@ -24,7 +24,7 @@
# error "Only <sysprof.h> can be included directly."
#endif
-#include <glib-object.h>
+#include <gio/gio.h>
#include "sysprof-capture-writer.h"
@@ -119,6 +119,19 @@ struct _SysprofSourceInterface
* sysprof_source_emit_finished() must be called from the main-thread.
*/
void (*stop) (SysprofSource *self);
+
+ /**
+ * SysprofSource::modify-spawn:
+ * @self: a #SysprofSource
+ * @launcher: a #GSubprocessLauncher
+ * @argv: (element-type utf8): arguments for spawning
+ *
+ * Allows the source to modify the launcher or argv before the
+ * process is spawned.
+ */
+ void (*modify_spawn) (SysprofSource *self,
+ GSubprocessLauncher *launcher,
+ GPtrArray *argv);
};
SYSPROF_AVAILABLE_IN_ALL
@@ -142,5 +155,9 @@ SYSPROF_AVAILABLE_IN_ALL
void sysprof_source_start (SysprofSource *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_source_stop (SysprofSource *self);
+SYSPROF_AVAILABLE_IN_ALL
+void sysprof_source_modify_spawn (SysprofSource *self,
+ GSubprocessLauncher *launcher,
+ GPtrArray *argv);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]