Skip to content
Snippets Groups Projects
Commit eb37e653 authored by Simon McVittie's avatar Simon McVittie
Browse files

wrap: Use execve() to replace pressure-vessel process with bwrap


Now that pressure-vessel doesn't need to hold a temporary directory
open, it can be a pure "adverb" that replaces itself with the command
it wants to run, like sudo, env or `flatpak run`.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent b3cacf82
No related branches found
No related tags found
No related merge requests found
...@@ -284,9 +284,8 @@ Instructions for testing ...@@ -284,9 +284,8 @@ Instructions for testing
|-SteamChildMonit,13109 |-SteamChildMonit,13109
| `-sh,13110 -c... | `-sh,13110 -c...
| `-pressure-vessel,13111 --runtime /home/desktop/.local... | `-bwrap,13132 --new-session --setenv LD_LIBRARY_PATH...
| `-bwrap,13132 --new-session --setenv LD_LIBRARY_PATH... | `-Floating Point.,13133
| `-Floating Point.,13133
* The test UI automatically looks for runtimes in the following locations: * The test UI automatically looks for runtimes in the following locations:
......
...@@ -1526,24 +1526,6 @@ wrap_interactive (FlatpakBwrap *wrapped_command, ...@@ -1526,24 +1526,6 @@ wrap_interactive (FlatpakBwrap *wrapped_command,
return TRUE; return TRUE;
} }
typedef struct
{
gboolean exited;
gint wait_status;
} ChildExitedClosure;
static void
child_exited_cb (GPid pid,
gint wait_status,
gpointer user_data)
{
ChildExitedClosure *closure = user_data;
closure->exited = TRUE;
closure->wait_status = wait_status;
g_spawn_close_pid (pid);
}
static char **opt_env_if_host = NULL; static char **opt_env_if_host = NULL;
static char *opt_fake_home = NULL; static char *opt_fake_home = NULL;
static char *opt_freedesktop_app_id = NULL; static char *opt_freedesktop_app_id = NULL;
...@@ -1645,15 +1627,12 @@ main (int argc, ...@@ -1645,15 +1627,12 @@ main (int argc,
g_autofree gchar *bwrap_executable = NULL; g_autofree gchar *bwrap_executable = NULL;
g_autoptr(GString) ld_library_path = g_string_new (""); g_autoptr(GString) ld_library_path = g_string_new ("");
g_autoptr(GString) adjusted_ld_preload = g_string_new (""); g_autoptr(GString) adjusted_ld_preload = g_string_new ("");
GPid child_pid;
ChildExitedClosure child_exited_closure = { FALSE, 0 };
g_autofree gchar *cwd_p = NULL; g_autofree gchar *cwd_p = NULL;
g_autofree gchar *cwd_l = NULL; g_autofree gchar *cwd_l = NULL;
const gchar *home; const gchar *home;
g_autofree gchar *bwrap_help = NULL; g_autofree gchar *bwrap_help = NULL;
g_autofree gchar *tools_dir = NULL; g_autofree gchar *tools_dir = NULL;
const gchar *bwrap_help_argv[] = { "<bwrap>", "--help", NULL }; const gchar *bwrap_help_argv[] = { "<bwrap>", "--help", NULL };
GSpawnFlags spawn_flags = G_SPAWN_DO_NOT_REAP_CHILD;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
pv_avoid_gvfs (); pv_avoid_gvfs ();
...@@ -1761,6 +1740,21 @@ main (int argc, ...@@ -1761,6 +1740,21 @@ main (int argc,
* us exit 1. */ * us exit 1. */
ret = 1; ret = 1;
if (!opt_interactive)
{
int fd;
if (!glnx_openat_rdonly (-1, "/dev/null", TRUE, &fd, error))
goto out;
if (dup2 (fd, STDIN_FILENO) < 0)
{
glnx_throw_errno_prefix (error,
"Cannot replace stdin with /dev/null");
goto out;
}
}
pv_get_current_dirs (&cwd_p, &cwd_l); pv_get_current_dirs (&cwd_p, &cwd_l);
if (opt_verbose) if (opt_verbose)
...@@ -2167,47 +2161,15 @@ main (int argc, ...@@ -2167,47 +2161,15 @@ main (int argc,
/* flatpak_bwrap_finish did this */ /* flatpak_bwrap_finish did this */
g_assert (g_ptr_array_index (bwrap->argv, bwrap->argv->len - 1) == NULL); g_assert (g_ptr_array_index (bwrap->argv, bwrap->argv->len - 1) == NULL);
g_debug ("Launching child process..."); g_debug ("Replacing self with bwrap...");
if (opt_interactive)
spawn_flags |= G_SPAWN_CHILD_INHERITS_STDIN;
if (!g_spawn_async (NULL, /* cwd */
(gchar **) bwrap->argv->pdata,
bwrap->envp,
spawn_flags,
flatpak_bwrap_child_setup_cb,
bwrap->fds,
&child_pid,
error))
{
ret = 127;
goto out;
}
g_child_watch_add (child_pid, child_exited_cb, &child_exited_closure);
while (!child_exited_closure.exited) flatpak_bwrap_child_setup_cb (bwrap->fds);
g_main_context_iteration (NULL, TRUE); execve (bwrap->argv->pdata[0],
(char * const *) bwrap->argv->pdata,
bwrap->envp);
if (opt_verbose) /* If we are still here then execve failed */
{ g_warning ("execve failed: %s", g_strerror (errno));
if (WIFEXITED (child_exited_closure.wait_status))
g_message ("Command exited with status %d",
WEXITSTATUS (child_exited_closure.wait_status));
else if (WIFSIGNALED (child_exited_closure.wait_status))
g_message ("Command killed by signal %d",
WTERMSIG (child_exited_closure.wait_status));
else
g_message ("Command terminated in an unknown way");
}
if (WIFEXITED (child_exited_closure.wait_status))
ret = WEXITSTATUS (child_exited_closure.wait_status);
else if (WIFSIGNALED (child_exited_closure.wait_status))
ret = 128 + WTERMSIG (child_exited_closure.wait_status);
else
ret = 126;
out: out:
if (local_error != NULL) if (local_error != NULL)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment