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 (20)
steam-runtime-tools (0.20210219.0) UNRELEASED; urgency=medium
steam-runtime-tools (0.20210224.0) UNRELEASED; urgency=medium
[ Simon McVittie ]
* pressure-vessel: Fix processing of Vulkan ICDs/layers outside /usr
......@@ -14,12 +14,19 @@ steam-runtime-tools (0.20210219.0) UNRELEASED; urgency=medium
* pv-launch: Use unset-env option for subsandbox API >= v5.
This was added in Flatpak 1.10.0.
* pressure-vessel: Improve diagnostics for various error conditions
* pressure-vessel: Generalize --copy-runtime-into into --variable-dir
* pressure-vessel: Fix locking behaviour in variable directory
* pressure-vessel: Add support for unpacking runtimes from an archive.
This previously had to be done by the SteamLinuxRuntime shell scripts.
* pressure-vessel: Automatically enable --copy-runtime if running
under Flatpak
[ Ludovico de Nittis ]
* pressure-vessel: Update flatpak-run to the latest upstream version.
This includes a fix to propagate the X11 cookies that have an address
equal to XAUTHLOCALHOSTNAME, fixing X11 authentication on some openSUSE
systems (Resolves: steam-runtime-tools#53)
* pressure-vessel: Improve library binding speed
* pv-adverb: Remove unused locales temporary directories
(Resolves: steam-runtime-tools#56)
* system-info: Report duplicate Vulkan ICDs/layers as an issue.
......@@ -30,7 +37,7 @@ steam-runtime-tools (0.20210219.0) UNRELEASED; urgency=medium
* system-info: Parse Vulkan layers from a report in the right order
* build: Refactoring
-- Simon McVittie <smcv@collabora.com> Mon, 22 Feb 2021 13:34:14 +0000
-- Simon McVittie <smcv@collabora.com> Wed, 24 Feb 2021 15:57:08 +0000
steam-runtime-tools (0.20210203.0) scout; urgency=medium
......
......@@ -336,10 +336,6 @@ test:ubuntu-20.04:
python3 tests/pressure-vessel/containers.py
test:archlinux:
# Temporarily not a blocker because our Docker's seccomp profiles
# don't know about faccess2() yet, and new Arch glibc relies on that
allow_failure: true
extends: .test_template
image: archlinux:latest
# Do not use the global before_script because it is only for Debian based
......
......@@ -22,6 +22,7 @@
#include <gio/gio.h>
#include "bwrap.h"
#include "utils.h"
#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
......@@ -42,65 +43,14 @@ pv_bwrap_run_sync (FlatpakBwrap *bwrap,
int *exit_status_out,
GError **error)
{
gint exit_status;
g_autofree gchar *output = NULL;
g_autofree gchar *errors = NULL;
guint i;
g_autoptr(GString) command = g_string_new ("");
g_return_val_if_fail (bwrap != NULL, FALSE);
g_return_val_if_fail (bwrap->argv->len >= 2, FALSE);
g_return_val_if_fail (pv_bwrap_was_finished (bwrap), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (exit_status_out != NULL)
*exit_status_out = -1;
for (i = 0; i < bwrap->argv->len; i++)
{
g_autofree gchar *quoted = NULL;
char *unquoted = g_ptr_array_index (bwrap->argv, i);
if (unquoted == NULL)
break;
quoted = g_shell_quote (unquoted);
g_string_append_printf (command, " %s", quoted);
}
g_debug ("run:%s", command->str);
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* and to avoid wasting a lot of time closing fds if the rlimit for
* maximum open file descriptors is high. Because we're waiting for the
* subprocess to finish anyway, it doesn't really matter that any fds
* that are not close-on-execute will get leaked into the child. */
if (!g_spawn_sync (NULL, /* cwd */
(char **) bwrap->argv->pdata,
bwrap->envp,
(G_SPAWN_SEARCH_PATH |
G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
NULL,
NULL,
&output,
&errors,
&exit_status,
error))
return FALSE;
g_print ("%s", output);
g_printerr ("%s", errors);
if (exit_status_out != NULL)
{
if (WIFEXITED (exit_status))
*exit_status_out = WEXITSTATUS (exit_status);
}
if (!g_spawn_check_exit_status (exit_status, error))
return FALSE;
return TRUE;
return pv_run_sync ((const char * const *) bwrap->argv->pdata,
(const char * const *) bwrap->envp,
exit_status_out, NULL, error);
}
/**
......@@ -126,7 +76,8 @@ pv_bwrap_execve (FlatpakBwrap *bwrap,
g_return_val_if_fail (pv_bwrap_was_finished (bwrap), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_debug ("Replacing self with bwrap...");
g_debug ("Replacing self with %s...",
glnx_basename (g_ptr_array_index (bwrap->argv, 0)));
if (bwrap->fds != NULL && bwrap->fds->len > 0)
flatpak_bwrap_child_setup_cb (bwrap->fds);
......
......@@ -395,18 +395,47 @@ class Gui:
self.grid.attach(label, 1, row, 1, 1)
row += 1
self.host_graphics_check = Gtk.CheckButton.new_with_label(
'Use host-system graphics stack'
)
value = boolean_environment('PRESSURE_VESSEL_HOST_GRAPHICS', True)
self.host_graphics_check.set_active(value)
self.grid.attach(self.host_graphics_check, 1, row, 1, 1)
label = Gtk.Label.new('Graphics stack')
self.grid.attach(label, 0, row, 1, 1)
self.graphics_provider_combo = Gtk.ComboBoxText.new()
env = os.getenv('PRESSURE_VESSEL_GRAPHICS_PROVIDER')
if env is not None:
self.graphics_provider_combo.append(
env, '$PRESSURE_VESSEL_GRAPHICS_PROVIDER ({})'.format(
env or 'empty'
),
)
if env is None or env != '/':
self.graphics_provider_combo.append(
'/', 'Current execution environment',
)
if (
(env is None or env != '/run/host')
and os.path.isdir('/run/host/etc')
and os.path.isdir('/run/host/usr')
):
self.graphics_provider_combo.append(
'/run/host', 'Host system',
)
if env is None or env != '':
self.graphics_provider_combo.append(
'', "Container's own libraries (probably won't work)",
)
self.graphics_provider_combo.set_active(0)
self.grid.attach(self.graphics_provider_combo, 1, row, 1, 1)
row += 1
label = Gtk.Label.new('')
label.set_markup(
'<small><i>'
"Most games and GPUs won't work when this is disabled."
"Most games and GPUs won't work if this is changed."
'</i></small>'
)
label.set_halign(Gtk.Align.START)
......@@ -602,11 +631,11 @@ class Gui:
if combo.get_active_id() == '/':
self.copy_runtime_check.set_sensitive(False)
self.gc_runtimes_check.set_sensitive(False)
self.host_graphics_check.set_sensitive(False)
self.graphics_provider_combo.set_sensitive(False)
else:
self.copy_runtime_check.set_sensitive(True)
self.gc_runtimes_check.set_sensitive(True)
self.host_graphics_check.set_sensitive(True)
self.graphics_provider_combo.set_sensitive(True)
def run_cb(self, _ignored=None):
# type: (typing.Any) -> None
......@@ -633,13 +662,10 @@ class Gui:
else:
argv.append('--runtime=' + id)
if self.host_graphics_check.get_active():
if os.path.isdir('/run/host'):
argv.append('--graphics-provider=/run/host')
else:
argv.append('--graphics-provider=/')
else:
argv.append('--graphics-provider=')
argv.append(
'--graphics-provider='
+ self.graphics_provider_combo.get_active_id()
)
if self.copy_runtime_check.get_active():
os.makedirs(self.var_path, mode=0o755, exist_ok=True)
......
......@@ -42,6 +42,7 @@ steam_runtime="${STEAM_RUNTIME-}"
# executables. We put it back before running the actual app/game.
declare -a options
ld_audit=
ld_preload=
options=()
......@@ -49,6 +50,11 @@ if [ -n "${LD_LIBRARY_PATH-}" ]; then
options+=("--env-if-host=LD_LIBRARY_PATH=$LD_LIBRARY_PATH")
fi
if [ -n "${LD_AUDIT-}" ]; then
options+=("--env-if-host=LD_AUDIT=$LD_AUDIT")
ld_audit="$LD_AUDIT"
fi
if [ -n "${LD_PRELOAD-}" ]; then
options+=("--env-if-host=LD_PRELOAD=$LD_PRELOAD")
ld_preload="$LD_PRELOAD"
......@@ -62,6 +68,7 @@ if [ -n "${STEAM_RUNTIME-}" ]; then
options+=("--env-if-host=STEAM_RUNTIME=$STEAM_RUNTIME")
fi
unset LD_AUDIT
unset LD_LIBRARY_PATH
unset LD_PRELOAD
PATH="$default_path"
......@@ -103,8 +110,11 @@ unset PRESSURE_VESSEL_APP_LD_LIBRARY_PATH
old_IFS="$IFS"
IFS=":"
for word in $ld_audit; do
options+=("--ld-audit=$word")
done
for word in $ld_preload; do
options+=("--host-ld-preload=$word")
options+=("--ld-preload=$word")
done
IFS="$old_IFS"
......
This diff is collapsed.
......@@ -168,10 +168,12 @@ pv_search_path_append (GString *search_path,
g_string_append (search_path, item);
}
gchar *
pv_capture_output (const char * const * argv,
const char * const * envp,
GError **error)
gboolean
pv_run_sync (const char * const * argv,
const char * const * envp,
int *exit_status_out,
char **output_out,
GError **error)
{
gsize len;
gint wait_status;
......@@ -180,10 +182,14 @@ pv_capture_output (const char * const * argv,
gsize i;
g_autoptr(GString) command = g_string_new ("");
g_return_val_if_fail (argv != NULL, NULL);
g_return_val_if_fail (argv[0] != NULL, NULL);
g_return_val_if_fail (argv != NULL, FALSE);
g_return_val_if_fail (argv[0] != NULL, FALSE);
g_return_val_if_fail (output_out == NULL || *output_out == NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (exit_status_out != NULL)
*exit_status_out = -1;
for (i = 0; argv[i] != NULL; i++)
{
g_autofree gchar *quoted = g_shell_quote (argv[i]);
......@@ -208,12 +214,15 @@ pv_capture_output (const char * const * argv,
&errors,
&wait_status,
error))
return NULL;
return FALSE;
g_printerr ("%s", errors);
if (!g_spawn_check_exit_status (wait_status, error))
return NULL;
if (exit_status_out != NULL)
{
if (WIFEXITED (wait_status))
*exit_status_out = WEXITSTATUS (wait_status);
}
len = strlen (output);
......@@ -223,7 +232,13 @@ pv_capture_output (const char * const * argv,
g_debug ("-> %s", output);
return g_steal_pointer (&output);
if (!g_spawn_check_exit_status (wait_status, error))
return FALSE;
if (output_out != NULL)
*output_out = g_steal_pointer (&output);
return TRUE;
}
/*
......
......@@ -48,9 +48,11 @@ void pv_get_current_dirs (gchar **cwd_p,
void pv_search_path_append (GString *search_path,
const gchar *item);
gchar *pv_capture_output (const char * const * argv,
const char * const * envp,
GError **error);
gboolean pv_run_sync (const char * const * argv,
const char * const * envp,
int *exit_status_out,
char **output_out,
GError **error);
gpointer pv_hash_table_get_arbitrary_key (GHashTable *table);
......
......@@ -349,6 +349,34 @@ export_contents_of_run (FlatpakBwrap *bwrap,
return TRUE;
}
/* Nvidia Vulkan ray-tracing requires to load the `nvidia_uvm.ko` kernel
* module, and this is usually done in `libcuda.so.1` by running the setuid
* binary `nvidia-modprobe`. But when we are inside a container we don't bind
* `nvidia-modprobe` and, even if we did, its setuid would not be effective
* because we have `PR_SET_NO_NEW_PRIVS` and we don't have `CAP_SYS_MODULE` in
* our capability bounding set.
* For this reason if the current system is using the proprietary Nvidia
* drivers, and `nvidia_uvm.ko` has not been already loaded, we should execute
* `nvidia-modprobe` before entering in the container environment. */
static gboolean
maybe_load_nvidia_modules (GError **error)
{
const char *nvidia_modprobe_argv[] =
{
"nvidia-modprobe",
"-u",
NULL
};
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (g_file_test ("/sys/module/nvidia/version", G_FILE_TEST_IS_REGULAR)
&& !g_file_test ("/sys/module/nvidia_uvm", G_FILE_TEST_IS_DIR))
return pv_run_sync (nvidia_modprobe_argv, NULL, NULL, NULL, error);
return TRUE;
}
typedef enum
{
ENV_MOUNT_FLAGS_COLON_DELIMITED = (1 << 0),
......@@ -723,7 +751,6 @@ static gboolean opt_only_prepare = FALSE;
static gboolean opt_remove_game_overlay = FALSE;
static gboolean opt_import_vulkan_layers = TRUE;
static PvShell opt_shell = PV_SHELL_NONE;
static GPtrArray *opt_ld_preload = NULL;
static GArray *opt_pass_fds = NULL;
static char *opt_runtime = NULL;
static char *opt_runtime_archive = NULL;
......@@ -741,20 +768,67 @@ static gboolean opt_test = FALSE;
static PvTerminal opt_terminal = PV_TERMINAL_AUTO;
static char *opt_write_final_argv = NULL;
typedef struct
{
const char *variable;
GPtrArray *values;
} PreloadModule;
static PreloadModule opt_preload_modules[] =
{
{ "LD_AUDIT", NULL },
{ "LD_PRELOAD", NULL },
};
static gboolean
append_preload_module (const char *variable,
const char *value,
GError **error)
{
gsize i;
for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++)
{
if (strcmp (variable, opt_preload_modules[i].variable) == 0)
break;
}
g_return_val_if_fail (i < G_N_ELEMENTS (opt_preload_modules), FALSE);
if (opt_preload_modules[i].values == NULL)
opt_preload_modules[i].values = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (opt_preload_modules[i].values, g_strdup (value));
return TRUE;
}
static gboolean
opt_host_ld_preload_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
gchar *preload = g_strdup_printf ("host:%s", value);
if (opt_ld_preload == NULL)
opt_ld_preload = g_ptr_array_new_with_free_func (g_free);
g_warning ("%s is deprecated, use --ld-preload=%s instead",
option_name, value);
return append_preload_module ("LD_PRELOAD", value, error);
}
g_ptr_array_add (opt_ld_preload, g_steal_pointer (&preload));
static gboolean
opt_ld_audit_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
return append_preload_module ("LD_AUDIT", value, error);
}
return TRUE;
static gboolean
opt_ld_preload_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
return append_preload_module ("LD_PRELOAD", value, error);
}
static gboolean
......@@ -970,7 +1044,8 @@ opt_with_host_graphics_cb (const gchar *option_name,
/* This is the old way to get the graphics from the host system */
if (g_strcmp0 (option_name, "--with-host-graphics") == 0)
{
if (g_file_test ("/run/host", G_FILE_TEST_IS_DIR))
if (g_file_test ("/run/host/usr", G_FILE_TEST_IS_DIR)
&& g_file_test ("/run/host/etc", G_FILE_TEST_IS_DIR))
opt_graphics_provider = g_strdup ("/run/host");
else
opt_graphics_provider = g_strdup ("/");
......@@ -1064,8 +1139,9 @@ static GOptionEntry options[] =
"Use HOME as home directory. Implies --unshare-home. "
"[Default: $PRESSURE_VESSEL_HOME if set]", "HOME" },
{ "host-ld-preload", '\0',
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.",
G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb,
"Deprecated alias for --ld-preload=MODULE, which despite its name "
"does not necessarily take the module from the host system",
"MODULE" },
{ "graphics-provider", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_graphics_provider,
......@@ -1074,7 +1150,7 @@ static GOptionEntry options[] =
"and will be adjusted for use on the host system if pressure-vessel "
"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" },
"[Default: $PRESSURE_VESSEL_GRAPHICS_PROVIDER or '/']", "PATH" },
{ "launcher", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_launcher,
"Instead of specifying a command with its arguments to execute, all the "
......@@ -1083,6 +1159,16 @@ static GOptionEntry options[] =
"edited by pressure-vessel, or that are known to be wrong in the new "
"container, or that needs to inherit the value from the host system, "
"will be locked. This option implies --batch.", NULL },
{ "ld-audit", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_ld_audit_cb,
"Add MODULE from current execution environment to LD_AUDIT when "
"executing COMMAND.",
"MODULE" },
{ "ld-preload", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_ld_preload_cb,
"Add MODULE from current execution environment to LD_PRELOAD when "
"executing COMMAND.",
"MODULE" },
{ "pass-fd", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_pass_fd_cb,
"Let the launched process inherit the given fd.",
......@@ -1275,7 +1361,6 @@ main (int argc,
g_autoptr(FlatpakExports) exports = NULL;
g_autofree gchar *launch_executable = NULL;
g_autofree gchar *bwrap_executable = NULL;
g_autoptr(GString) adjusted_ld_preload = g_string_new ("");
g_autofree gchar *cwd_p = NULL;
g_autofree gchar *cwd_l = NULL;
g_autofree gchar *cwd_p_host = NULL;
......@@ -1431,12 +1516,25 @@ main (int argc,
if (opt_graphics_provider == NULL)
{
/* Also check the deprecated 'PRESSURE_VESSEL_HOST_GRAPHICS' */
if (!pv_boolean_environment ("PRESSURE_VESSEL_HOST_GRAPHICS", TRUE))
opt_graphics_provider = g_strdup ("");
else if (g_file_test ("/run/host", G_FILE_TEST_IS_DIR))
opt_graphics_provider = g_strdup ("/run/host");
Tristate value = tristate_environment ("PRESSURE_VESSEL_HOST_GRAPHICS");
if (value == TRISTATE_MAYBE)
{
opt_graphics_provider = g_strdup ("/");
}
else
opt_graphics_provider = g_strdup ("/");
{
g_warning ("$PRESSURE_VESSEL_HOST_GRAPHICS is deprecated, "
"please use PRESSURE_VESSEL_GRAPHICS_PROVIDER instead");
if (value == TRISTATE_NO)
opt_graphics_provider = g_strdup ("");
else if (g_file_test ("/run/host/usr", G_FILE_TEST_IS_DIR)
&& g_file_test ("/run/host/etc", G_FILE_TEST_IS_DIR))
opt_graphics_provider = g_strdup ("/run/host");
else
opt_graphics_provider = g_strdup ("/");
}
}
g_assert (opt_graphics_provider != NULL);
......@@ -1954,31 +2052,40 @@ main (int argc,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
"/tmp");
g_debug ("Adjusting LD_PRELOAD...");
/* We need the LD_PRELOADs from Steam visible at the paths that were
* used for them, which might be their physical rather than logical
* locations. */
if (opt_ld_preload != NULL)
* locations. Steam doesn't generally use LD_AUDIT, but the Steam app
* on Flathub does, and it needs similar handling. */
for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++)
{
for (i = 0; i < opt_ld_preload->len; i++)
const char *variable = opt_preload_modules[i].variable;
const GPtrArray *values = opt_preload_modules[i].values;
g_autoptr(GString) adjusted = NULL;
gsize len;
gsize j;
adjusted = g_string_new ("");
g_debug ("Adjusting %s...", variable);
if (values == NULL)
len = 0;
else
len = values->len;
for (j = 0; j < len; j++)
{
const char *preload = g_ptr_array_index (opt_ld_preload, i);
const char *preload = g_ptr_array_index (values, j);
g_assert (preload != NULL);
if (*preload == '\0')
continue;
/* We have the beginnings of infrastructure to set a LD_PRELOAD
* from inside the container, but currently the only thing we
* support is it coming from the host. */
g_assert (g_str_has_prefix (preload, "host:"));
preload = preload + 5;
if (strstr (preload, "gtk3-nocsd") != NULL)
{
g_warning ("Disabling gtk3-nocsd LD_PRELOAD: it is known to cause crashes.");
g_warning ("Disabling gtk3-nocsd %s: it is known to cause crashes.",
variable);
continue;
}
......@@ -1995,14 +2102,14 @@ main (int argc,
&& (g_str_has_prefix (preload, "/usr/")
|| g_str_has_prefix (preload, "/lib")))
{
g_autofree gchar *in_run_host = g_build_filename ("/run/host",
preload,
NULL);
g_autofree gchar *adjusted_path = NULL;
adjusted_path = g_build_filename ("/run/host", preload, NULL);
/* When using a runtime we can't write to /usr/ or /libQUAL/,
* so redirect this preloaded module to the corresponding
* location in /run/host. */
pv_search_path_append (adjusted_ld_preload, in_run_host);
pv_search_path_append (adjusted, adjusted_path);
}
else
{
......@@ -2022,25 +2129,25 @@ main (int argc,
preload);
}
pv_search_path_append (adjusted_ld_preload, preload);
pv_search_path_append (adjusted, preload);
}
}
else
{
g_info ("LD_PRELOAD module '%s' does not exist", preload);
g_info ("%s module '%s' does not exist", variable, preload);
}
}
}
/* If we adjusted the LD_PRELOAD entries, from the one provided by the host,
* to something that is valid in the container, we shouldn't add them to
* the bwrap envp. Otherwise when we call "pv_bwrap_execve()" we will
* create an environment that tries to preload libraries that are not
* available, until it actually executes "bwrap".
* This can be avoided by using the bwrap option "--setenv" instead. */
if (adjusted_ld_preload->len != 0)
flatpak_bwrap_add_args (bwrap, "--setenv", "LD_PRELOAD",
adjusted_ld_preload->str, NULL);
/* If we adjusted the module paths from the one provided by the host
* to something that is valid in the container, we shouldn't add them to
* the bwrap envp. Otherwise when we call "pv_bwrap_execve()" we will
* create an environment that tries to preload libraries that are not
* available, until it actually executes "bwrap".
* This can be avoided by using the bwrap option "--setenv" instead. */
if (adjusted->len != 0)
flatpak_bwrap_add_args (bwrap, "--setenv", variable,
adjusted->str, NULL);
}
/* TODO: In future we will not do this when using Flatpak sub-sandboxing */
if (1)
......@@ -2683,6 +2790,15 @@ main (int argc,
}
}
if (!is_flatpak_env)
{
if (!maybe_load_nvidia_modules (error))
{
g_debug ("Cannot load nvidia modules: %s", local_error->message);
g_clear_error (&local_error);
}
}
if (opt_only_prepare)
ret = 0;
else
......@@ -2692,7 +2808,9 @@ out:
if (local_error != NULL)
g_warning ("%s", local_error->message);
g_clear_pointer (&opt_ld_preload, g_ptr_array_unref);
for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++)
g_clear_pointer (&opt_preload_modules[i].values, g_ptr_array_unref);
g_clear_pointer (&opt_env_if_host, g_strfreev);
g_clear_pointer (&opt_freedesktop_app_id, g_free);
g_clear_pointer (&opt_steam_app_id, g_free);
......
......@@ -889,8 +889,8 @@ _srt_file_test_in_sysroot (const char *sysroot,
{
if (!glnx_opendirat (-1, sysroot, FALSE, &local_sysroot_fd, &error))
{
g_debug ("An error occurred trying to open %s: %s", sysroot,
error->message);
g_debug ("An error occurred trying to open sysroot \"%s\": %s",
sysroot, error->message);
return FALSE;
}
......@@ -903,8 +903,8 @@ _srt_file_test_in_sysroot (const char *sysroot,
if (file_fd < 0)
{
g_debug ("An error occurred trying to resolve %s in sysroot: %s",
filename, error->message);
g_debug ("An error occurred trying to resolve \"%s\" in sysroot \"%s\": %s",
filename, sysroot, error->message);
return FALSE;
}
......
......@@ -86,8 +86,8 @@ test_arbitrary_key (Fixture *f,
}
static void
test_capture_output (Fixture *f,
gconstpointer context)
test_run_sync (Fixture *f,
gconstpointer context)
{
const gchar * argv[] =
{
......@@ -96,20 +96,27 @@ test_capture_output (Fixture *f,
g_autofree gchar *output = NULL;
g_autoptr(GError) error = NULL;
g_auto(GStrv) envp = g_get_environ ();
int exit_status = -1;
output = pv_capture_output (argv, NULL, &error);
pv_run_sync (argv, NULL, NULL, &output, &error);
g_assert_cmpstr (output, ==, "hello");
g_assert_no_error (error);
g_clear_pointer (&output, g_free);
pv_run_sync (argv, NULL, &exit_status, NULL, &error);
g_assert_cmpint (exit_status, ==, 0);
g_assert_no_error (error);
argv[1] = "hello\\nworld"; /* deliberately no trailing newline */
output = pv_capture_output (argv, NULL, &error);
pv_run_sync (argv, NULL, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, 0);
g_assert_no_error (error);
g_assert_cmpstr (output, ==, "hello\nworld");
g_clear_pointer (&output, g_free);
argv[0] = "/nonexistent/doesnotexist";
output = pv_capture_output (argv, NULL, &error);
pv_run_sync (argv, NULL, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, -1);
g_assert_nonnull (error);
if (error->domain == G_SPAWN_ERROR
......@@ -134,7 +141,8 @@ test_capture_output (Fixture *f,
argv[0] = "false";
argv[1] = NULL;
output = pv_capture_output (argv, NULL, &error);
pv_run_sync (argv, NULL, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, 1);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_assert_cmpstr (output, ==, NULL);
g_clear_error (&error);
......@@ -142,7 +150,8 @@ test_capture_output (Fixture *f,
argv[0] = "sh";
argv[1] = "-euc";
argv[2] = "echo \"$PATH\"";
output = pv_capture_output (argv, NULL, &error);
pv_run_sync (argv, NULL, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, 0);
g_assert_no_error (error);
g_assert_cmpstr (output, ==, g_getenv ("PATH"));
g_clear_pointer (&output, g_free);
......@@ -151,7 +160,8 @@ test_capture_output (Fixture *f,
argv[0] = "sh";
argv[1] = "-euc";
argv[2] = "echo \"${FOO-unset}\"";
output = pv_capture_output (argv, (const char * const *) envp, &error);
pv_run_sync (argv, (const char * const *) envp, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, 0);
g_assert_no_error (error);
g_assert_cmpstr (output, ==, "bar");
g_clear_pointer (&output, g_free);
......@@ -160,7 +170,8 @@ test_capture_output (Fixture *f,
argv[0] = "sh";
argv[1] = "-euc";
argv[2] = "echo \"${FOO-unset}\"";
output = pv_capture_output (argv, (const char * const *) envp, &error);
pv_run_sync (argv, (const char * const *) envp, &exit_status, &output, &error);
g_assert_cmpint (exit_status, ==, 0);
g_assert_no_error (error);
g_assert_cmpstr (output, ==, "unset");
g_clear_pointer (&output, g_free);
......@@ -371,8 +382,8 @@ main (int argc,
g_test_init (&argc, &argv, NULL);
g_test_add ("/arbitrary-key", Fixture, NULL,
setup, test_arbitrary_key, teardown);
g_test_add ("/capture-output", Fixture, NULL,
setup, test_capture_output, teardown);
g_test_add ("/run-sync", Fixture, NULL,
setup, test_run_sync, teardown);
g_test_add ("/delete-dangling-symlink", Fixture, NULL,
setup, test_delete_dangling_symlink, teardown);
g_test_add ("/envp-cmp", Fixture, NULL, setup, test_envp_cmp, teardown);
......