From ba9d29fa337247085ebbef92421aa7c5e39c1893 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 2 Jun 2023 15:57:46 -0700 Subject: [PATCH] libsysprof-profile: add trace_fd helper for spawnable I'd like to stop using tracefd, but since we need to maintain compatability with older tooling, lets at least make it more ergonomic than adding an instrument(s) for it. --- src/libsysprof-profile/sysprof-spawnable.c | 50 ++++++++++++++++++++++ src/libsysprof-profile/sysprof-spawnable.h | 5 ++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/libsysprof-profile/sysprof-spawnable.c b/src/libsysprof-profile/sysprof-spawnable.c index efe670ce..631c82ad 100644 --- a/src/libsysprof-profile/sysprof-spawnable.c +++ b/src/libsysprof-profile/sysprof-spawnable.c @@ -22,6 +22,8 @@ #include +#include + #include "sysprof-spawnable.h" typedef struct @@ -328,3 +330,51 @@ sysprof_spawnable_set_cwd (SysprofSpawnable *self, self->cwd = g_strdup (cwd); } } + +/** + * sysprof_spawnable_add_trace_fd: + * @self: a #SysprofSpawnable + * @envvar: (nullable): the environment variable + * + * Adds an environment variable to the spawnable that will contain a + * "tracing file-descriptor". The spawned process can use + * `sysprof_capture_writer_new_from_env()` if @envvar is %NULL + * or with `getenv()` and `sysprof_capture_writer_new_from_fd()`. + * + * If @envvar is %NULL, "SYSPROF_TRACE_FD" will be used. + * + * The caller is responsible for closin the resulting FD. + * + * Returns: A file-descriptor which can be used to read the trace or + * -1 upon failure and `errno` is set. Caller must `close()` the + * FD if >= 0. + */ +int +sysprof_spawnable_add_trace_fd (SysprofSpawnable *self, + const char *envvar) +{ + g_autofd int fd = -1; + g_autofd int dest = -1; + g_autofree char *name = NULL; + g_autofree char *fdstr = NULL; + + g_return_val_if_fail (SYSPROF_IS_SPAWNABLE (self), -1); + + if (envvar == NULL) + envvar = "SYSPROF_TRACE_FD"; + + name = g_strdup_printf ("[sysprof-tracefd:%s]", envvar); + + if (-1 == (fd = sysprof_memfd_create (name))) + return -1; + + if (-1 == (dest = dup (fd))) + return -1; + + fdstr = g_strdup_printf ("%d", dest); + + sysprof_spawnable_setenv (self, envvar, fdstr); + sysprof_spawnable_take_fd (self, g_steal_fd (&dest), -1); + + return g_steal_fd (&fd); +} diff --git a/src/libsysprof-profile/sysprof-spawnable.h b/src/libsysprof-profile/sysprof-spawnable.h index f8ad8bf7..81814e48 100644 --- a/src/libsysprof-profile/sysprof-spawnable.h +++ b/src/libsysprof-profile/sysprof-spawnable.h @@ -22,7 +22,7 @@ #include -#include "sysprof-version-macros.h" +#include G_BEGIN_DECLS @@ -75,6 +75,9 @@ SYSPROF_AVAILABLE_IN_ALL void sysprof_spawnable_set_starting_fd (SysprofSpawnable *self, gint starting_fd); SYSPROF_AVAILABLE_IN_ALL +int sysprof_spawnable_add_trace_fd (SysprofSpawnable *self, + const char *envvar); +SYSPROF_AVAILABLE_IN_ALL GSubprocess *sysprof_spawnable_spawn (SysprofSpawnable *self, GError **error); SYSPROF_AVAILABLE_IN_ALL