[console] application: Execute a --command directly if possible



commit 54dcfff4e67f464de4e251112ea3340a2288572f
Author: Simon McVittie <smcv debian org>
Date:   Sat Apr 9 17:29:34 2022 +0100

    application: Execute a --command directly if possible
    
    For the simple case where the command exists as an executable file or
    in PATH, we don't need the shell. This matches the behaviour of
    xterm -e with a single argument. For example,
    
        kgx --command xeyes
    
    would execve() xeyes directly, whereas
    
        kgx --command "ls *.txt"
    
    would use a shell to evaluate "ls *.txt".
    
    Signed-off-by: Simon McVittie <smcv debian org>

 src/kgx-application.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/src/kgx-application.c b/src/kgx-application.c
index 30af450..08d2b30 100644
--- a/src/kgx-application.c
+++ b/src/kgx-application.c
@@ -503,17 +503,34 @@ kgx_application_command_line (GApplication            *app,
   }
 
   if (command != NULL) {
+    gboolean can_exec_directly;
+
     if (argv != NULL && argv[0] != NULL) {
       g_warning (_("Cannot use both --command and positional parameters"));
       return EXIT_FAILURE;
     }
 
     g_clear_pointer (&argv, g_strfreev);
-    argv = g_new0 (char *, 4);
-    argv[0] = g_strdup ("/bin/sh");
-    argv[1] = g_strdup ("-c");
-    argv[2] = g_strdup (command);
-    argv[3] = NULL;
+
+    if (strchr (command, '/') != NULL) {
+      can_exec_directly = g_file_test (command, G_FILE_TEST_IS_EXECUTABLE);
+    } else {
+      g_autofree char *program = g_find_program_in_path (command);
+
+      can_exec_directly = (program != NULL);
+    }
+
+    if (can_exec_directly) {
+      argv = g_new0 (char *, 2);
+      argv[0] = g_strdup (command);
+      argv[1] = NULL;
+    } else {
+      argv = g_new0 (char *, 4);
+      argv[0] = g_strdup ("/bin/sh");
+      argv[1] = g_strdup ("-c");
+      argv[2] = g_strdup (command);
+      argv[3] = NULL;
+    }
   }
 
   if (g_variant_dict_lookup (options, "tab", "b", &tab) && tab) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]