From 01a7f5c3084f2eab1d57ecb8444f39880d978b54 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Fri, 23 Aug 2019 13:36:45 +0100 Subject: [PATCH] wrap: Add $PRESSURE_VESSEL_TERMINAL and --terminal This allows the equivalent of --tty and --xterm to be set via the environment. Signed-off-by: Simon McVittie <smcv@collabora.com> --- pressure-vessel-test-ui | 4 +- src/wrap.c | 146 +++++++++++++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 31 deletions(-) diff --git a/pressure-vessel-test-ui b/pressure-vessel-test-ui index a733ce02c..aa7618fce 100755 --- a/pressure-vessel-test-ui +++ b/pressure-vessel-test-ui @@ -283,7 +283,9 @@ class Gui: argv.append('--unshare-home') if self.xterm_check.get_active(): - argv.append('--xterm') + argv.append('--terminal=xterm') + else: + argv.append('--terminal=none') id = self.shell_combo.get_active_id() diff --git a/src/wrap.c b/src/wrap.c index 22e6d04ef..97345b813 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -1587,6 +1587,14 @@ wrap_tty (FlatpakBwrap *wrapped_command, return TRUE; } +typedef enum +{ + TERMINAL_NONE = 0, + TERMINAL_AUTO, + TERMINAL_TTY, + TERMINAL_XTERM, +} Terminal; + static char **opt_env_if_host = NULL; static char *opt_fake_home = NULL; static char *opt_freedesktop_app_id = NULL; @@ -1600,8 +1608,7 @@ static char *opt_runtime = NULL; static gboolean opt_share_home = TRUE; static gboolean opt_verbose = FALSE; static gboolean opt_version = FALSE; -static gboolean opt_tty = FALSE; -static gboolean opt_xterm = FALSE; +static Terminal opt_terminal = TERMINAL_AUTO; static gboolean opt_host_ld_preload_cb (const gchar *option_name, @@ -1682,6 +1689,67 @@ opt_shell_cb (const gchar *option_name, return FALSE; } +static gboolean +opt_terminal_cb (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + if (g_strcmp0 (option_name, "--tty") == 0) + value = "tty"; + else if (g_strcmp0 (option_name, "--xterm") == 0) + value = "xterm"; + + if (value == NULL || *value == '\0') + { + opt_terminal = TERMINAL_AUTO; + return TRUE; + } + + switch (value[0]) + { + case 'a': + if (g_strcmp0 (value, "auto") == 0) + { + opt_terminal = TERMINAL_AUTO; + return TRUE; + } + break; + + case 'n': + if (g_strcmp0 (value, "none") == 0 || g_strcmp0 (value, "no") == 0) + { + opt_terminal = TERMINAL_NONE; + return TRUE; + } + break; + + case 't': + if (g_strcmp0 (value, "tty") == 0) + { + opt_terminal = TERMINAL_TTY; + return TRUE; + } + break; + + case 'x': + if (g_strcmp0 (value, "xterm") == 0) + { + opt_terminal = TERMINAL_XTERM; + return TRUE; + } + break; + + default: + /* fall through to error */ + break; + } + + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + "Unknown choice \"%s\" for %s", value, option_name); + return FALSE; +} + static GOptionEntry options[] = { { "env-if-host", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_env_if_host, @@ -1730,15 +1798,18 @@ static GOptionEntry options[] = "Run an interactive shell instead of COMMAND. Executing \"$@\" in that " "shell will run COMMAND [ARGS].", NULL }, - { "tty", 0, 0, G_OPTION_ARG_NONE, &opt_tty, - "For --shell-after, --shell-fail and --shell-instead, use Steam's " - "controlling tty instead of running an xterm.", - NULL }, - { "xterm", 0, 0, G_OPTION_ARG_NONE, &opt_xterm, - "Run an xterm which will display the log output from the game. " - "Implied by --shell-after, --shell-fail and --shell-instead, " - "unless --tty is used.", - NULL }, + { "terminal", 0, 0, G_OPTION_ARG_CALLBACK, opt_terminal_cb, + "none: disable features that would use a terminal; " + "auto: equivalent to xterm if a --shell option is used, or none; " + "xterm: put game output (and --shell if used) in an xterm; " + "tty: put game output (and --shell if used) on Steam's " + "controlling tty " + "[Default: $PRESSURE_VESSEL_TERMINAL or 'auto']", + "{none|auto|xterm|tty}" }, + { "tty", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, opt_terminal_cb, + "Equivalent to --terminal=tty", NULL }, + { "xterm", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, opt_terminal_cb, + "Equivalent to --terminal=xterm", NULL }, { "verbose", 0, 0, G_OPTION_ARG_NONE, &opt_verbose, "Be more verbose.", NULL }, { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, @@ -1810,6 +1881,10 @@ main (int argc, g_getenv ("PRESSURE_VESSEL_SHELL"), NULL, error)) goto out; + if (!opt_terminal_cb ("$PRESSURE_VESSEL_TERMINAL", + g_getenv ("PRESSURE_VESSEL_TERMINAL"), NULL, error)) + goto out; + context = g_option_context_new ("[--] COMMAND [ARGS]\n" "Run COMMAND [ARGS] in a container.\n"); @@ -1849,16 +1924,19 @@ main (int argc, goto out; } - if (opt_tty && opt_xterm) + if (opt_terminal == TERMINAL_AUTO) { - g_printerr ("%s: --tty and --xterm are contradictory\n", - g_get_prgname ()); - goto out; + if (opt_shell != SHELL_NONE) + opt_terminal = TERMINAL_XTERM; + else + opt_terminal = TERMINAL_NONE; } - if (opt_shell != SHELL_NONE && !opt_tty) + if (opt_terminal == TERMINAL_NONE && opt_shell != SHELL_NONE) { - opt_xterm = TRUE; + g_printerr ("%s: --terminal=none is incompatible with --shell\n", + g_get_prgname ()); + goto out; } if (strcmp (argv[1], "--") == 0) @@ -1921,7 +1999,7 @@ main (int argc, * us exit 1. */ ret = 1; - if (!opt_tty) + if (opt_terminal != TERMINAL_TTY) { int fd; @@ -1989,23 +2067,31 @@ main (int argc, wrapped_command = flatpak_bwrap_new (NULL); - if (opt_tty) + switch (opt_terminal) { - g_debug ("Wrapping command to use tty"); + case TERMINAL_TTY: + g_debug ("Wrapping command to use tty"); - if (!wrap_tty (wrapped_command, error)) - goto out; - } + if (!wrap_tty (wrapped_command, error)) + goto out; - if (opt_xterm) - { - g_debug ("Wrapping command with xterm"); - wrap_in_xterm (wrapped_command); + break; + + case TERMINAL_XTERM: + g_debug ("Wrapping command with xterm"); + wrap_in_xterm (wrapped_command); + break; + + case TERMINAL_AUTO: + case TERMINAL_NONE: + default: + /* do nothing */ + break; } - if (opt_shell != SHELL_NONE || opt_xterm) + if (opt_shell != SHELL_NONE || opt_terminal == TERMINAL_XTERM) { - /* In the SHELL_NONE case, if opt_xterm, just don't let the xterm + /* In the (SHELL_NONE, TERMINAL_XTERM) case, just don't let the xterm * close before the user has had a chance to see the output */ wrap_interactive (wrapped_command, opt_shell); } @@ -2093,7 +2179,7 @@ main (int argc, /* Protect the controlling terminal from the app/game, unless we are * running an interactive shell in which case that would break its * job control. */ - if (!opt_tty) + if (opt_terminal != TERMINAL_TTY) flatpak_bwrap_add_arg (bwrap, "--new-session"); if (opt_runtime != NULL && opt_runtime[0] != '\0') -- GitLab