From b99e71ccf363324367160a2f4cb8eb92a1fd2928 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Mon, 7 Sep 2020 15:57:05 +0100 Subject: [PATCH] wrap: Add ability to pass fds through -wrap and -adverb to the command Part of pressure-vessel#6. Signed-off-by: Simon McVittie <smcv@collabora.com> --- man/wrap.1.md | 6 ++++++ src/wrap.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/man/wrap.1.md b/man/wrap.1.md index 3c13a01da..eee4e4e82 100644 --- a/man/wrap.1.md +++ b/man/wrap.1.md @@ -78,6 +78,12 @@ pressure-vessel-wrap - run programs in a bubblewrap container With `--copy-runtime-into`, the prepared runtime will appear in a subdirectory of *DIR*. +`--pass-fd` *FD* +: Pass the file descriptor *FD* (specified as a small positive integer) + from the parent process to the *COMMAND*. The default is to only pass + through file descriptors 0, 1 and 2 + (**stdin**, **stdout** and **stderr**). + `--runtime=` : Use the current execution environment's /usr to provide /usr in the container. diff --git a/src/wrap.c b/src/wrap.c index ee3f7d23d..a5408662b 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -657,6 +657,7 @@ static gboolean opt_only_prepare = FALSE; static gboolean opt_remove_game_overlay = FALSE; static PvShell opt_shell = PV_SHELL_NONE; static GPtrArray *opt_ld_preload = NULL; +static GArray *opt_pass_fds = NULL; static char *opt_runtime_base = NULL; static char *opt_runtime = NULL; static Tristate opt_share_home = TRISTATE_MAYBE; @@ -686,6 +687,41 @@ opt_host_ld_preload_cb (const gchar *option_name, return TRUE; } +static gboolean +opt_pass_fd_cb (const char *name, + const char *value, + gpointer data, + GError **error) +{ + char *endptr; + gint64 i64 = g_ascii_strtoll (value, &endptr, 10); + int fd; + int fd_flags; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if (i64 < 0 || i64 > G_MAXINT || endptr == value || *endptr != '\0') + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Integer out of range or invalid: %s", value); + return FALSE; + } + + fd = (int) i64; + + fd_flags = fcntl (fd, F_GETFD); + + if (fd_flags < 0) + return glnx_throw_errno_prefix (error, "Unable to receive --fd %d", fd); + + if (opt_pass_fds == NULL) + opt_pass_fds = g_array_new (FALSE, FALSE, sizeof (int)); + + g_array_append_val (opt_pass_fds, fd); + return TRUE; +} + static gboolean opt_shell_cb (const gchar *option_name, const gchar *value, @@ -925,6 +961,10 @@ static GOptionEntry options[] = "is run in a container. The empty string means use the graphics " "stack from container." "[Default: $PRESSURE_VESSEL_GRAPHICS_PROVIDER or '/run/host' or '/']", "PATH" }, + { "pass-fd", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_pass_fd_cb, + "Let the launched process inherit the given fd.", + NULL }, { "remove-game-overlay", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_remove_game_overlay, "Disable the Steam Overlay. " @@ -1946,6 +1986,17 @@ main (int argc, "--subreaper", NULL); + if (opt_pass_fds != NULL) + { + for (i = 0; i < opt_pass_fds->len; i++) + { + int fd = g_array_index (opt_pass_fds, int, i); + + flatpak_bwrap_add_fd (bwrap, fd); + flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%d", fd); + } + } + switch (opt_shell) { case PV_SHELL_AFTER: @@ -2087,6 +2138,7 @@ out: g_clear_pointer (&opt_fake_home, g_free); g_clear_pointer (&opt_runtime_base, g_free); g_clear_pointer (&opt_runtime, g_free); + g_clear_pointer (&opt_pass_fds, g_array_unref); g_debug ("Exiting with status %d", ret); return ret; -- GitLab