libsysprof: add vfunc to modify spawn arguments

This commit is contained in:
Christian Hergert
2019-05-21 21:57:36 -07:00
parent 13b3edcbf6
commit c204081cc0
3 changed files with 91 additions and 19 deletions

View File

@ -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 (ar, NULL);
g_ptr_array_add (env, 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));
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]));
}
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);

View File

@ -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);
}

View File

@ -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