[console] application: Handle a command with multiple parameters
- From: Zander Brown <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [console] application: Handle a command with multiple parameters
- Date: Mon, 20 Jun 2022 13:45:19 +0000 (UTC)
commit 2f82c213b0811b4871abc7f6bad56e6b6a25a373
Author: Simon McVittie <smcv debian org>
Date: Sun Apr 3 15:47:15 2022 +0100
application: Handle a command with multiple parameters
gnome-terminal accepts multiple parameters after the "--" pseudo-option,
and uses them as a command and optional arguments. kgx previously
accepted positional parameters, but ignored them, which is confusing.
Instead, treat them the same way gnome-terminal does.
xterm accepts multiple parameters after the special "-e" option, which
also terminates command-line-option parsing, and Debian's
x-terminal-emulator interface borrows this interpretation of "-e" from
xterm. Convert "-e" into "--" so that it has the xterm-compatible
behaviour of terminating command-line parsing, which is otherwise not
available in GOptionContext.
Resolves: https://gitlab.gnome.org/GNOME/console/-/issues/26
Signed-off-by: Simon McVittie <smcv debian org>
src/kgx-application.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 72 insertions(+), 3 deletions(-)
---
diff --git a/src/kgx-application.c b/src/kgx-application.c
index afb66d8..fc4bae4 100644
--- a/src/kgx-application.c
+++ b/src/kgx-application.c
@@ -424,6 +424,39 @@ kgx_application_open (GApplication *app,
}
+static int
+kgx_application_local_command_line (GApplication *app,
+ char ***arguments,
+ int *exit_status)
+{
+ for (size_t i = 0; (*arguments)[i] != NULL; i++) {
+ /* Don't edit argv[0], but also don't start the loop with i = 1,
+ * because it's technically possible to run a program with argc == 0 */
+ if (i == 0) {
+ continue;
+ }
+
+ if (strcmp ((*arguments)[i], "-e") == 0) {
+ /* For xterm-compatible handling of -e, we want to stop parsing
+ * other command-line options at this point, so that
+ *
+ * kgx -T "Directory listing" -e ls -al /
+ *
+ * passes "-al" to ls instead of trying to parse them as kgx
+ * options. To do this, turn -e into the "--" pseudo-argument. */
+ (*arguments)[i][1] = '-';
+ break;
+ } else if (strcmp ((*arguments)[i], "--") == 0) {
+ /* Don't continue to edit arguments after the -- separator,
+ * so you can do: kgx -- some-command ... -e ... */
+ break;
+ }
+ }
+
+ return G_APPLICATION_CLASS (kgx_application_parent_class)->local_command_line (app, arguments,
exit_status);
+}
+
+
static int
kgx_application_command_line (GApplication *app,
GApplicationCommandLine *cli)
@@ -431,9 +464,10 @@ kgx_application_command_line (GApplication *app,
KgxApplication *self = KGX_APPLICATION (app);
guint32 timestamp = GDK_CURRENT_TIME;
GVariantDict *options = NULL;
+ g_autofree const char **argv = NULL;
+ g_autofree char *command = NULL;
const char *working_dir = NULL;
const char *title = NULL;
- const char *command = NULL;
const char *const *shell = NULL;
const char *cwd = NULL;
gint64 scrollback;
@@ -445,7 +479,8 @@ kgx_application_command_line (GApplication *app,
g_variant_dict_lookup (options, "working-directory", "^&ay", &working_dir);
g_variant_dict_lookup (options, "title", "&s", &title);
- g_variant_dict_lookup (options, "command", "^&ay", &command);
+ g_variant_dict_lookup (options, "command", "^ay", &command);
+ g_variant_dict_lookup (options, G_OPTION_REMAINING, "^a&ay", &argv);
if (g_variant_dict_lookup (options, "set-shell", "^as", &shell) && shell) {
g_settings_set_strv (self->settings, "shell", shell);
@@ -467,6 +502,30 @@ kgx_application_command_line (GApplication *app,
path = g_file_new_for_path (cwd);
}
+ /* TODO: These should be passed in as argv, rather than building and
+ * then re-parsing as if for a shell */
+ if (argv != NULL && argv[0] != NULL) {
+ g_autoptr (GString) buf = g_string_new ("");
+
+ if (command != NULL) {
+ g_warning (_("Cannot use both --command and positional parameters"));
+ return EXIT_FAILURE;
+ }
+
+ for (size_t i = 0; argv[i] != NULL; i++) {
+ g_autofree char *quoted = g_shell_quote (argv[i]);
+
+ g_string_append (buf, quoted);
+
+ if (buf->len > 0) {
+ g_string_append_c (buf, ' ');
+ }
+ }
+
+ g_debug ("Built command-line: %s", buf->str);
+ command = g_string_free (g_steal_pointer (&buf), FALSE);
+ }
+
if (g_variant_dict_lookup (options, "tab", "b", &tab) && tab) {
kgx_application_add_terminal (self,
KGX_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (self))),
@@ -594,6 +653,7 @@ kgx_application_class_init (KgxApplicationClass *klass)
app_class->activate = kgx_application_activate;
app_class->startup = kgx_application_startup;
app_class->open = kgx_application_open;
+ app_class->local_command_line = kgx_application_local_command_line;
app_class->command_line = kgx_application_command_line;
app_class->handle_local_options = kgx_application_handle_local_options;
@@ -694,7 +754,7 @@ static GOptionEntry entries[] = {
},
{
"command",
- 'e',
+ 0,
0,
G_OPTION_ARG_FILENAME,
NULL,
@@ -747,6 +807,15 @@ static GOptionEntry entries[] = {
N_("ADVANCED: Set the scrollback length"),
N_("LINES")
},
+ {
+ G_OPTION_REMAINING,
+ 0,
+ 0,
+ G_OPTION_ARG_FILENAME_ARRAY,
+ NULL,
+ NULL,
+ N_("[-e|-- COMMAND [ARGUMENT...]]")
+ },
{ NULL }
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]