Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • steamrt/steam-runtime-tools
1 result
Show changes
Commits on Source (7)
...@@ -52,4 +52,8 @@ GFile *flatpak_get_data_dir (const char *app_id); ...@@ -52,4 +52,8 @@ GFile *flatpak_get_data_dir (const char *app_id);
void flatpak_run_add_font_path_args (FlatpakBwrap *bwrap); void flatpak_run_add_font_path_args (FlatpakBwrap *bwrap);
extern const char * const *flatpak_abs_usrmerged_dirs; extern const char * const *flatpak_abs_usrmerged_dirs;
int open_namespace_fd_if_needed (const char *path,
const char *other_path);
#endif /* __FLATPAK_RUN_H__ */ #endif /* __FLATPAK_RUN_H__ */
...@@ -3418,8 +3418,9 @@ check_parental_controls (const char *app_ref, ...@@ -3418,8 +3418,9 @@ check_parental_controls (const char *app_ref,
return TRUE; return TRUE;
} }
#endif
static int int
open_namespace_fd_if_needed (const char *path, open_namespace_fd_if_needed (const char *path,
const char *other_path) { const char *other_path) {
struct stat s, other_s; struct stat s, other_s;
...@@ -3438,6 +3439,7 @@ open_namespace_fd_if_needed (const char *path, ...@@ -3438,6 +3439,7 @@ open_namespace_fd_if_needed (const char *path,
return -1; return -1;
} }
#if 0
static gboolean static gboolean
check_sudo (GError **error) check_sudo (GError **error)
{ {
......
...@@ -60,9 +60,7 @@ as a subprocess of **pressure-vessel-launcher**. ...@@ -60,9 +60,7 @@ as a subprocess of **pressure-vessel-launcher**.
owned by the **flatpak-session-helper** per-user service, and the owned by the **flatpak-session-helper** per-user service, and the
*COMMAND* is launched on the host system, similar to the *COMMAND* is launched on the host system, similar to the
**--host** option of **flatpak-spawn**(1). **--host** option of **flatpak-spawn**(1).
The **--terminate** option is not allowed in this mode, and most The **--terminate** option is not allowed in this mode.
options that would unset environment variables, such as **--unset-env**,
are ignored with a warning (but **--clear-env** is still possible).
As another special case, if the *NAME* is As another special case, if the *NAME* is
**org.freedesktop.portal.Flatpak**, then it is assumed to be **org.freedesktop.portal.Flatpak**, then it is assumed to be
...@@ -72,8 +70,7 @@ as a subprocess of **pressure-vessel-launcher**. ...@@ -72,8 +70,7 @@ as a subprocess of **pressure-vessel-launcher**.
Options that alter how the sub-sandbox is created, such as Options that alter how the sub-sandbox is created, such as
**--sandbox-flag**, are not currently supported. **--sandbox-flag**, are not currently supported.
As with **org.freedesktop.Flatpak**, the As with **org.freedesktop.Flatpak**, the
**--terminate** option is not allowed in this mode, and most **--terminate** option is not allowed in this mode.
options that would unset environment variables are ignored with a warning.
**--clear-env** **--clear-env**
: The *COMMAND* runs in an empty environment, apart from any environment : The *COMMAND* runs in an empty environment, apart from any environment
......
...@@ -534,6 +534,7 @@ main (int argc, ...@@ -534,6 +534,7 @@ main (int argc,
g_auto(GStrv) original_environ = NULL; g_auto(GStrv) original_environ = NULL;
g_autoptr(GMainLoop) loop = NULL; g_autoptr(GMainLoop) loop = NULL;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
g_autoptr(GPtrArray) replacement_command_and_args = NULL;
g_autoptr(GError) local_error = NULL; g_autoptr(GError) local_error = NULL;
GError **error = &local_error; GError **error = &local_error;
char **command_and_args; char **command_and_args;
...@@ -865,14 +866,14 @@ main (int argc, ...@@ -865,14 +866,14 @@ main (int argc,
if (g_hash_table_size (opt_unsetenv) > 0) if (g_hash_table_size (opt_unsetenv) > 0)
{ {
GVariantBuilder strv_builder;
g_variant_builder_init (&strv_builder, G_VARIANT_TYPE_STRING_ARRAY);
g_hash_table_iter_init (&iter, opt_unsetenv); g_hash_table_iter_init (&iter, opt_unsetenv);
if (api == &launcher_api) if (api == &launcher_api)
{ {
GVariantBuilder strv_builder;
g_variant_builder_init (&strv_builder, G_VARIANT_TYPE_STRING_ARRAY);
while (g_hash_table_iter_next (&iter, &key, NULL)) while (g_hash_table_iter_next (&iter, &key, NULL))
g_variant_builder_add (&strv_builder, "s", key); g_variant_builder_add (&strv_builder, "s", key);
...@@ -881,9 +882,29 @@ main (int argc, ...@@ -881,9 +882,29 @@ main (int argc,
} }
else else
{ {
replacement_command_and_args = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (replacement_command_and_args, g_strdup ("/usr/bin/env"));
while (g_hash_table_iter_next (&iter, &key, NULL)) while (g_hash_table_iter_next (&iter, &key, NULL))
g_warning ("Cannot unset %s when using Flatpak services", {
(const char *) key); g_ptr_array_add (replacement_command_and_args, g_strdup ("-u"));
g_ptr_array_add (replacement_command_and_args, g_strdup (key));
}
if (strchr (command_and_args[0], '=') != NULL)
{
g_ptr_array_add (replacement_command_and_args, g_strdup ("/bin/sh"));
g_ptr_array_add (replacement_command_and_args, g_strdup ("-euc"));
g_ptr_array_add (replacement_command_and_args, g_strdup ("exec \"$@\""));
g_ptr_array_add (replacement_command_and_args, g_strdup ("sh")); /* argv[0] */
}
for (i = 0; command_and_args[i] != NULL; i++)
g_ptr_array_add (replacement_command_and_args, g_strdup (command_and_args[i]));
g_ptr_array_add (replacement_command_and_args, NULL);
command_and_args = (char **) replacement_command_and_args->pdata;
} }
} }
......
...@@ -795,6 +795,50 @@ pv_terminate_all_child_processes (GTimeSpan wait_period, ...@@ -795,6 +795,50 @@ pv_terminate_all_child_processes (GTimeSpan wait_period,
return TRUE; return TRUE;
} }
/*
* @str: A path
* @prefix: A possible prefix
*
* The same as flatpak_has_path_prefix(), but instead of a boolean,
* return the part of @str after @prefix (non-%NULL but possibly empty)
* if @str has prefix @prefix, or %NULL if it does not.
*
* Returns: (nullable) (transfer none): the part of @str after @prefix,
* or %NULL if @str is not below @prefix
*/
const char *
pv_get_path_after (const char *str,
const char *prefix)
{
while (TRUE)
{
/* Skip consecutive slashes to reach next path
element */
while (*str == '/')
str++;
while (*prefix == '/')
prefix++;
/* No more prefix path elements? Done! */
if (*prefix == 0)
return str;
/* Compare path element */
while (*prefix != 0 && *prefix != '/')
{
if (*str != *prefix)
return NULL;
str++;
prefix++;
}
/* Matched prefix path element,
must be entire str path element */
if (*str != '/' && *str != 0)
return NULL;
}
}
/** /**
* pv_current_namespace_path_to_host_path: * pv_current_namespace_path_to_host_path:
* @current_env_path: a path in the current environment * @current_env_path: a path in the current environment
...@@ -807,40 +851,32 @@ gchar * ...@@ -807,40 +851,32 @@ gchar *
pv_current_namespace_path_to_host_path (const gchar *current_env_path) pv_current_namespace_path_to_host_path (const gchar *current_env_path)
{ {
gchar *path_on_host = NULL; gchar *path_on_host = NULL;
g_autofree gchar *home_env_guarded = NULL;
const gchar *home_env = g_getenv ("HOME");
g_return_val_if_fail (g_path_is_absolute (current_env_path), g_return_val_if_fail (g_path_is_absolute (current_env_path),
g_strdup (current_env_path)); g_strdup (current_env_path));
if (home_env == NULL)
home_env = g_get_home_dir ();
if (home_env != NULL)
{
/* Avoid the edge case where e.g. current_env_path is
* '/home/melanie/Games' and home_env is '/home/me' */
if (g_str_has_suffix (home_env, "/"))
home_env_guarded = g_strdup (home_env);
else
home_env_guarded = g_strdup_printf ("%s/", home_env);
}
if (g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR)) if (g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR))
{ {
struct stat via_current_env_stat; struct stat via_current_env_stat;
struct stat via_persist_stat; struct stat via_persist_stat;
const gchar *home = g_getenv ("HOME");
const gchar *after = NULL;
if (home == NULL)
home = g_get_home_dir ();
if (home != NULL)
after = pv_get_path_after (current_env_path, home);
/* If we are inside a Flatpak container, usually, the home /* If we are inside a Flatpak container, usually, the home
* folder is '${HOME}/.var/app/${FLATPAK_ID}' on the host system */ * folder is '${HOME}/.var/app/${FLATPAK_ID}' on the host system */
if (home_env != NULL if (after != NULL)
&& g_str_has_prefix (current_env_path, home_env_guarded))
{ {
path_on_host = g_build_filename (home_env, path_on_host = g_build_filename (home,
".var", ".var",
"app", "app",
g_getenv ("FLATPAK_ID"), g_getenv ("FLATPAK_ID"),
current_env_path + strlen (home_env), after,
NULL); NULL);
if (lstat (path_on_host, &via_persist_stat) < 0) if (lstat (path_on_host, &via_persist_stat) < 0)
...@@ -860,12 +896,12 @@ pv_current_namespace_path_to_host_path (const gchar *current_env_path) ...@@ -860,12 +896,12 @@ pv_current_namespace_path_to_host_path (const gchar *current_env_path)
} }
} }
after = pv_get_path_after (current_env_path, "/run/host");
/* In a Flatpak container, usually, '/run/host' is the root of the /* In a Flatpak container, usually, '/run/host' is the root of the
* host system */ * host system */
if (g_str_has_prefix (current_env_path, "/run/host/")) if (after != NULL && path_on_host == NULL)
path_on_host = g_strdup (current_env_path + strlen ("/run/host")); path_on_host = g_build_filename ("/", after, NULL);
else if (g_strcmp0 (current_env_path, "/run/host") == 0)
path_on_host = g_strdup ("/");
} }
/* Either we are not in a Flatpak container or it's not obvious how the /* Either we are not in a Flatpak container or it's not obvious how the
* container to host translation should happen. Just keep the same path. */ * container to host translation should happen. Just keep the same path. */
......
...@@ -70,3 +70,6 @@ gboolean pv_terminate_all_child_processes (GTimeSpan wait_period, ...@@ -70,3 +70,6 @@ gboolean pv_terminate_all_child_processes (GTimeSpan wait_period,
GError **error); GError **error);
gchar *pv_current_namespace_path_to_host_path (const gchar *current_env_path); gchar *pv_current_namespace_path_to_host_path (const gchar *current_env_path);
const char *pv_get_path_after (const char *str,
const char *prefix);
...@@ -58,12 +58,6 @@ pressure-vessel-wrap - run programs in a bubblewrap container ...@@ -58,12 +58,6 @@ pressure-vessel-wrap - run programs in a bubblewrap container
`--home` *DIR* `--home` *DIR*
: Use *DIR* as the home directory. This implies `--unshare-home`. : Use *DIR* as the home directory. This implies `--unshare-home`.
`--host-fallback`
: If **bwrap**(1) cannot be run, attempt to run *COMMAND* in the
current execution environment using the `LD_LIBRARY_PATH`
Steam Runtime instead. In practice this will only work for
Steam Runtime version 1, "scout".
`--host-ld-preload` *MODULE* `--host-ld-preload` *MODULE*
: Add *MODULE* from the host system to `LD_PRELOAD` when executing : Add *MODULE* from the host system to `LD_PRELOAD` when executing
*COMMAND*. If *COMMAND* is run in a container, the path of the *COMMAND*. If *COMMAND* is run in a container, the path of the
......
...@@ -206,35 +206,26 @@ check_bwrap (const char *tools_dir, ...@@ -206,35 +206,26 @@ check_bwrap (const char *tools_dir,
return NULL; return NULL;
} }
static gchar * static gboolean
check_flatpak_spawn (void) check_launch_on_host (const char *launch_executable,
GError **error)
{ {
g_autoptr(GError) local_error = NULL;
GError **error = &local_error;
g_autofree gchar *spawn_exec = NULL;
g_autofree gchar *child_stdout = NULL; g_autofree gchar *child_stdout = NULL;
g_autofree gchar *child_stderr = NULL; g_autofree gchar *child_stderr = NULL;
int wait_status; int wait_status;
const char *spawn_test_argv[] = const char *test_argv[] =
{ {
NULL, NULL,
"--host", "--bus-name=org.freedesktop.Flatpak",
"--directory=/", "--",
"true", "true",
NULL NULL
}; };
/* All known Flatpak runtimes have flatpak-spawn in the PATH */ test_argv[0] = launch_executable;
spawn_exec = g_find_program_in_path ("flatpak-spawn");
if (spawn_exec == NULL
|| !g_file_test (spawn_exec, G_FILE_TEST_IS_EXECUTABLE))
return NULL;
spawn_test_argv[0] = spawn_exec;
if (!g_spawn_sync (NULL, /* cwd */ if (!g_spawn_sync (NULL, /* cwd */
(gchar **) spawn_test_argv, (gchar **) test_argv,
NULL, /* environ */ NULL, /* environ */
G_SPAWN_DEFAULT, G_SPAWN_DEFAULT,
NULL, NULL, /* child setup */ NULL, NULL, /* child setup */
...@@ -243,25 +234,24 @@ check_flatpak_spawn (void) ...@@ -243,25 +234,24 @@ check_flatpak_spawn (void)
&wait_status, &wait_status,
error)) error))
{ {
g_warning ("Cannot run flatpak-spawn: %s", local_error->message); return FALSE;
g_clear_error (&local_error);
} }
else if (wait_status != 0)
if (wait_status != 0)
{ {
g_warning ("Cannot run flatpak-spawn: wait status %d", wait_status); g_warning ("Cannot run commands on host system: wait status %d",
wait_status);
if (child_stdout != NULL && child_stdout[0] != '\0') if (child_stdout != NULL && child_stdout[0] != '\0')
g_warning ("Output:\n%s", child_stdout); g_warning ("Output:\n%s", child_stdout);
if (child_stderr != NULL && child_stderr[0] != '\0') if (child_stderr != NULL && child_stderr[0] != '\0')
g_warning ("Diagnostic output:\n%s", child_stderr); g_warning ("Diagnostic output:\n%s", child_stderr);
}
else return glnx_throw (error, "Unable to run a command on the host system");
{
return g_steal_pointer (&spawn_exec);
} }
return NULL; return TRUE;
} }
/* /*
...@@ -723,7 +713,6 @@ static char *opt_steam_app_id = NULL; ...@@ -723,7 +713,6 @@ static char *opt_steam_app_id = NULL;
static gboolean opt_gc_runtimes = TRUE; static gboolean opt_gc_runtimes = TRUE;
static gboolean opt_generate_locales = TRUE; static gboolean opt_generate_locales = TRUE;
static char *opt_home = NULL; static char *opt_home = NULL;
static gboolean opt_host_fallback = FALSE;
static char *opt_graphics_provider = NULL; static char *opt_graphics_provider = NULL;
static char *graphics_provider_mount_point = NULL; static char *graphics_provider_mount_point = NULL;
static gboolean opt_launcher = FALSE; static gboolean opt_launcher = FALSE;
...@@ -1021,9 +1010,6 @@ static GOptionEntry options[] = ...@@ -1021,9 +1010,6 @@ static GOptionEntry options[] =
G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_home, G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_home,
"Use HOME as home directory. Implies --unshare-home. " "Use HOME as home directory. Implies --unshare-home. "
"[Default: $PRESSURE_VESSEL_HOME if set]", "HOME" }, "[Default: $PRESSURE_VESSEL_HOME if set]", "HOME" },
{ "host-fallback", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_host_fallback,
"Run COMMAND on the host system if we cannot run it in a container.", NULL },
{ "host-ld-preload", '\0', { "host-ld-preload", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb,
"Add MODULE from the host system to LD_PRELOAD when executing COMMAND.", "Add MODULE from the host system to LD_PRELOAD when executing COMMAND.",
...@@ -1231,7 +1217,7 @@ main (int argc, ...@@ -1231,7 +1217,7 @@ main (int argc,
g_autoptr(FlatpakBwrap) adverb_args = NULL; g_autoptr(FlatpakBwrap) adverb_args = NULL;
g_autofree gchar *adverb_in_container = NULL; g_autofree gchar *adverb_in_container = NULL;
g_autoptr(FlatpakBwrap) wrapped_command = NULL; g_autoptr(FlatpakBwrap) wrapped_command = NULL;
g_autofree gchar *spawn_executable = NULL; g_autofree gchar *launch_executable = NULL;
g_autofree gchar *bwrap_executable = NULL; g_autofree gchar *bwrap_executable = NULL;
g_autoptr(GString) adjusted_ld_preload = g_string_new (""); g_autoptr(GString) adjusted_ld_preload = g_string_new ("");
g_autofree gchar *cwd_p = NULL; g_autofree gchar *cwd_p = NULL;
...@@ -1255,6 +1241,7 @@ main (int argc, ...@@ -1255,6 +1241,7 @@ main (int argc,
g_str_equal, g_str_equal,
g_free, NULL); g_free, NULL);
g_autofree char *lock_env_fd = NULL; g_autofree char *lock_env_fd = NULL;
g_autoptr(GArray) pass_fds_through_adverb = g_array_new (FALSE, FALSE, sizeof (int));
my_pid = getpid (); my_pid = getpid ();
...@@ -1625,76 +1612,33 @@ main (int argc, ...@@ -1625,76 +1612,33 @@ main (int argc,
/* If we are in a Flatpak environment we can't use bwrap directly */ /* If we are in a Flatpak environment we can't use bwrap directly */
if (is_flatpak_env) if (is_flatpak_env)
{ {
g_debug ("Checking for flatpak-spawn..."); launch_executable = g_build_filename (tools_dir,
spawn_executable = check_flatpak_spawn (); "pressure-vessel-launch",
NULL);
/* Assume "bwrap" to exist in the host system and to be in its PATH */ /* Assume "bwrap" to exist in the host system and to be in its PATH */
bwrap_executable = g_strdup ("bwrap"); bwrap_executable = g_strdup ("bwrap");
/* If we can't launch a command on the host, just fail. */
if (!check_launch_on_host (launch_executable, error))
goto out;
} }
else else
{ {
g_debug ("Checking for bwrap..."); g_debug ("Checking for bwrap...");
/* if this fails, it will warn */
bwrap_executable = check_bwrap (tools_dir, opt_only_prepare); bwrap_executable = check_bwrap (tools_dir, opt_only_prepare);
}
if (opt_test) if (bwrap_executable == NULL)
{ goto out;
if ((is_flatpak_env && spawn_executable == NULL)
|| bwrap_executable == NULL) g_debug ("OK (%s)", bwrap_executable);
{
ret = 1;
goto out;
}
else
{
if (spawn_executable != NULL)
g_debug ("OK (%s) (%s)", spawn_executable, bwrap_executable);
else
g_debug ("OK (%s)", bwrap_executable);
ret = 0;
goto out;
}
} }
if ((is_flatpak_env && spawn_executable == NULL) if (opt_test)
|| bwrap_executable == NULL)
{ {
/* TODO in a Flatpak environment, host is not what we expect it to be */ ret = 0;
if (opt_host_fallback) goto out;
{
g_message ("Falling back to executing wrapped command directly");
if (opt_env_if_host != NULL)
{
for (i = 0; opt_env_if_host[i] != NULL; i++)
{
char *equals = strchr (opt_env_if_host[i], '=');
g_assert (equals != NULL);
*equals = '\0';
flatpak_bwrap_set_env (wrapped_command, opt_env_if_host[i],
equals + 1, TRUE);
}
}
flatpak_bwrap_finish (wrapped_command);
/* flatpak_bwrap_finish did this */
g_assert (g_ptr_array_index (wrapped_command->argv,
wrapped_command->argv->len - 1) == NULL);
execvpe (g_ptr_array_index (wrapped_command->argv, 0),
(char * const *) wrapped_command->argv->pdata,
wrapped_command->envp);
glnx_throw_errno_prefix (error, "execvpe %s",
(gchar *) g_ptr_array_index (wrapped_command->argv, 0));
goto out;
}
else
{
goto out;
}
} }
if (!is_flatpak_env) if (!is_flatpak_env)
...@@ -2090,8 +2034,9 @@ main (int argc, ...@@ -2090,8 +2034,9 @@ main (int argc,
g_hash_table_add (extra_locked_vars_to_inherit, g_strdup ("XDG_RUNTIME_DIR")); g_hash_table_add (extra_locked_vars_to_inherit, g_strdup ("XDG_RUNTIME_DIR"));
/* The bwrap envp will be completely ignored when calling /* The bwrap envp will be completely ignored when calling
* `flatpak-spawn --host`. For this reason we convert them to * pv-launch. For this reason we convert them to `--setenv`.
* `--setenv`. */ * (TODO: Now that we're using pv-launch instead of flatpak-spawn,
* we could use --pass-env) */
for (i = 0; bwrap->envp != NULL && bwrap->envp[i] != NULL; i++) for (i = 0; bwrap->envp != NULL && bwrap->envp[i] != NULL; i++)
{ {
g_auto(GStrv) split = g_strsplit (bwrap->envp[i], "=", 2); g_auto(GStrv) split = g_strsplit (bwrap->envp[i], "=", 2);
...@@ -2194,6 +2139,49 @@ main (int argc, ...@@ -2194,6 +2139,49 @@ main (int argc,
lock_env_fd = g_strdup_printf ("%d", lock_env_tmpf.fd); lock_env_fd = g_strdup_printf ("%d", lock_env_tmpf.fd);
flatpak_bwrap_add_fd (bwrap, glnx_steal_fd (&lock_env_tmpf.fd)); flatpak_bwrap_add_fd (bwrap, glnx_steal_fd (&lock_env_tmpf.fd));
if (is_flatpak_env)
{
int userns_fd, userns2_fd, pidns_fd;
/* Tell the bwrap instance on the host to join the same user and pid
* namespaces as Steam in Flatpak. Otherwise, pid-based IPC between
* the Steam client and the game will fail.
*
* This is not expected to work if bwrap on the host is setuid,
* so it will not work for users of Debian, Arch linux-hardened, etc.,
* but it's better than nothing. */
userns_fd = open ("/run/.userns", O_RDONLY | O_CLOEXEC);
if (userns_fd >= 0)
{
g_array_append_val (pass_fds_through_adverb, userns_fd);
flatpak_bwrap_add_args_data_fd (bwrap, "--userns",
glnx_steal_fd (&userns_fd),
NULL);
userns2_fd = open_namespace_fd_if_needed ("/proc/self/ns/user",
"/run/.userns");
if (userns2_fd >= 0)
{
g_array_append_val (pass_fds_through_adverb, userns2_fd);
flatpak_bwrap_add_args_data_fd (bwrap, "--userns2",
glnx_steal_fd (&userns2_fd),
NULL);
}
}
pidns_fd = open ("/proc/self/ns/pid", O_RDONLY | O_CLOEXEC);
if (pidns_fd >= 0)
{
g_array_append_val (pass_fds_through_adverb, pidns_fd);
flatpak_bwrap_add_args_data_fd (bwrap, "--pidns",
glnx_steal_fd (&pidns_fd),
NULL);
}
}
if (opt_verbose) if (opt_verbose)
{ {
g_message ("%s options before bundling:", bwrap_executable); g_message ("%s options before bundling:", bwrap_executable);
...@@ -2254,6 +2242,13 @@ main (int argc, ...@@ -2254,6 +2242,13 @@ main (int argc,
} }
} }
for (i = 0; i < pass_fds_through_adverb->len; i++)
{
int fd = g_array_index (pass_fds_through_adverb, int, i);
flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%d", fd);
}
flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%s", lock_env_fd); flatpak_bwrap_add_arg_printf (bwrap, "--pass-fd=%s", lock_env_fd);
switch (opt_shell) switch (opt_shell)
...@@ -2325,24 +2320,26 @@ main (int argc, ...@@ -2325,24 +2320,26 @@ main (int argc,
if (is_flatpak_env) if (is_flatpak_env)
{ {
/* Just use the envp from @bwrap */ /* Just use the envp from @bwrap */
g_autoptr(FlatpakBwrap) flatpak_spawn = flatpak_bwrap_new (flatpak_bwrap_empty_env); g_autoptr(FlatpakBwrap) launch_on_host = flatpak_bwrap_new (flatpak_bwrap_empty_env);
flatpak_bwrap_add_arg (flatpak_spawn, spawn_executable); flatpak_bwrap_add_arg (launch_on_host, launch_executable);
flatpak_bwrap_add_arg (flatpak_spawn, "--host"); flatpak_bwrap_add_arg (launch_on_host, "--bus-name=org.freedesktop.Flatpak");
for (i = 0; i < bwrap->fds->len; i++) for (i = 0; i < bwrap->fds->len; i++)
{ {
g_autofree char *fd_str = g_strdup_printf ("--forward-fd=%d", g_autofree char *fd_str = g_strdup_printf ("--forward-fd=%d",
g_array_index (bwrap->fds, int, i)); g_array_index (bwrap->fds, int, i));
flatpak_bwrap_add_arg (flatpak_spawn, fd_str); flatpak_bwrap_add_arg (launch_on_host, fd_str);
} }
/* Change the current working directory where flatpak-spawn will run. /* Change the current working directory where pv-launch will run bwrap.
* Bwrap will then set its directory by itself. For this reason here * Bwrap will then set its directory by itself. For this reason here
* we just need a directory that it's known to exist. */ * we just need a directory that it's known to exist. */
flatpak_bwrap_add_arg (flatpak_spawn, "--directory=/"); flatpak_bwrap_add_arg (launch_on_host, "--directory=/");
flatpak_bwrap_add_arg (launch_on_host, "--");
flatpak_bwrap_append_bwrap (flatpak_spawn, bwrap); flatpak_bwrap_append_bwrap (launch_on_host, bwrap);
g_clear_pointer (&bwrap, flatpak_bwrap_free); g_clear_pointer (&bwrap, flatpak_bwrap_free);
bwrap = g_steal_pointer (&flatpak_spawn); bwrap = g_steal_pointer (&launch_on_host);
} }
if (opt_verbose) if (opt_verbose)
......
...@@ -182,6 +182,46 @@ test_envp_cmp (Fixture *f, ...@@ -182,6 +182,46 @@ test_envp_cmp (Fixture *f,
g_free (sort_this); g_free (sort_this);
} }
static void
test_get_path_after (Fixture *f,
gconstpointer context)
{
static const struct
{
const char *str;
const char *prefix;
const char *expected;
} tests[] =
{
{ "/run/host/usr", "/run/host", "usr" },
{ "/run/host/usr", "/run/host/", "usr" },
{ "/run/host", "/run/host", "" },
{ "////run///host////usr", "//run//host", "usr" },
{ "////run///host////usr", "//run//host////", "usr" },
{ "/run/hostage", "/run/host", NULL },
/* Any number of leading slashes is ignored, even zero */
{ "foo/bar", "/foo", "bar" },
{ "/foo/bar", "foo", "bar" },
};
gsize i;
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
const char *str = tests[i].str;
const char *prefix = tests[i].prefix;
const char *expected = tests[i].expected;
if (expected == NULL)
g_test_message ("%s should not have path prefix %s",
str, prefix);
else
g_test_message ("%s should have path prefix %s followed by %s",
str, prefix, expected);
g_assert_cmpstr (pv_get_path_after (str, prefix), ==, expected);
}
}
static void static void
test_search_path_append (Fixture *f, test_search_path_append (Fixture *f,
gconstpointer context) gconstpointer context)
...@@ -223,6 +263,8 @@ main (int argc, ...@@ -223,6 +263,8 @@ main (int argc,
g_test_add ("/capture-output", Fixture, NULL, g_test_add ("/capture-output", Fixture, NULL,
setup, test_capture_output, teardown); setup, test_capture_output, teardown);
g_test_add ("/envp-cmp", Fixture, NULL, setup, test_envp_cmp, teardown); g_test_add ("/envp-cmp", Fixture, NULL, setup, test_envp_cmp, teardown);
g_test_add ("/get-path-after", Fixture, NULL,
setup, test_get_path_after, teardown);
g_test_add ("/search-path-append", Fixture, NULL, g_test_add ("/search-path-append", Fixture, NULL,
setup, test_search_path_append, teardown); setup, test_search_path_append, teardown);
......