[easytag/wip/mingw-fixes] Ugly WIP process spawn improvements



commit e3e9898426e82dabffd3dc661002b799c07e02c7
Author: David King <amigadave amigadave com>
Date:   Tue Feb 18 22:34:33 2014 +0000

    Ugly WIP process spawn improvements

 src/browser.c |   83 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 65 insertions(+), 18 deletions(-)
---
diff --git a/src/browser.c b/src/browser.c
index fc4527c..74ad06c 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -4286,13 +4286,13 @@ Run_Program_With_Selected_Files (GtkWidget *combobox)
 static gboolean
 Run_Program (const gchar *program_name, GList *args_list)
 {
-    gchar **argv_user;
-    gint    argv_user_number;
+    gchar **program_args_argv = NULL;
+    guint n_program_args = 0;
+    gsize i;
     gchar  *msg;
     GPid pid;
     GError *error = NULL;
     gchar **argv;
-    gint    argv_index = 0;
     GList *l;
     gchar *program_path;
 
@@ -4333,27 +4333,72 @@ Run_Program (const gchar *program_name, GList *args_list)
         return FALSE;
     }
 
-    g_free(program_path); // Freed as never used
+    /* If user arguments are included, try to skip them. FIXME: This works
+     * poorly when there are spaces in the absolute path to the binary. */
+    if (strcmp (program_name, program_path) != 0)
+    {
+        /* Reaching here only means that program_name is not an absolute
+         * path. */
+        gchar *program_tmp;
+        const gchar *program_args;
+
+        program_tmp = g_strdup (program_name);
+
+        /* Skip the binary name and a delimiter. Same logic in
+         * Check_If_Executable_Exists()*/
+#ifdef G_OS_WIN32
+        /* FIXME: Should also consider .com, .bat, .sys. See
+         * g_find_program_in_path(). */
+        if (program_args = strstr (program_tmp, ".exe"))
+        {
+            /* Skip ".exe". */
+            program_args += 4;
+        }
+#else /* !G_OS_WIN32 */
+        /* Remove arguments if found. */
+        program_args = strchr (program_tmp, ' ');
+#endif /* !G_OS_WIN32 */
+
+        if (program_args && *program_args)
+        {
+            /* FIXME: Splitting arguments based on a delimiting space is bogus
+             * if the arguments have been quoted. */
+            program_args_argv = g_strsplit (program_args, " ", 0);
+            n_program_args = g_strv_length (program_args_argv);
+        }
+        else
+        {
+            n_program_args = 1;
+        }
+
+        g_free (program_tmp);
+    }
 
-    argv_user = g_strsplit(program_name," ",0); // the string may contains arguments, space is the delimiter
-    // Number of arguments into 'argv_user'
-    for (argv_user_number=0;argv_user[argv_user_number];argv_user_number++);
+    /* +1 for NULL, program_name is already included in n_program_args. */
+    argv = g_new0 (gchar *, n_program_args + g_list_length (args_list) + 1);
 
-    argv = g_new0(gchar *,argv_user_number + g_list_length(args_list) + 1); // +1 for NULL
+    argv[0] = program_path;
 
-    // Load 'user' arguments (program name and more...)
-    while (argv_user[argv_index])
+    if (program_args_argv)
+    {
+        /* Skip program_args_argv[0], which is " ". */
+        for (i = 1; program_args_argv[i] != NULL; i++)
+        {
+            argv[i] = program_args_argv[i];
+        }
+    }
+    else
     {
-        argv[argv_index] = argv_user[argv_index];
-        argv_index++;
+        i = 1;
     }
-    // Load arguments from 'args_list'
-    for (l = args_list; l != NULL; l = g_list_next (l))
+
+    /* Load arguments from 'args_list'. */
+    for (l = args_list; l != NULL; l = g_list_next (l), i++)
     {
-        argv[argv_index] = (gchar *)l->data;
-        argv_index++;
+        argv[i] = (gchar *)l->data;
     }
-    argv[argv_index] = NULL;
+
+    argv[i] = NULL;
 
     /* Execution ... */
     if (g_spawn_async (NULL, argv, NULL,
@@ -4373,7 +4418,9 @@ Run_Program (const gchar *program_name, GList *args_list)
         g_clear_error (&error);
     }
 
-    g_strfreev (argv_user);
+    g_strfreev (program_args_argv);
+    g_free (program_path);
+    g_free (argv);
 
     return TRUE;
 }


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