[easytag/wip/mingw-fixes: 1/3] Refactor process spawning code
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag/wip/mingw-fixes: 1/3] Refactor process spawning code
- Date: Wed, 19 Feb 2014 17:29:46 +0000 (UTC)
commit 6d28bb7afe5ffe11bd23f9b0d365b0bea6d1d6fa
Author: David King <amigadave amigadave com>
Date: Tue Feb 18 22:34:33 2014 +0000
Refactor process spawning code
Refactor the process spawning code so that it handles additional
arguments, as it did before switching to use g_spawn_async(). Use a
single et_run_program() method for spawning processes, and merge the
existing implementations.
src/browser.c | 105 +--------------------
src/misc.c | 296 ++++++++++++++++++++++++++++++++++-----------------------
src/misc.h | 2 +
3 files changed, 181 insertions(+), 222 deletions(-)
---
diff --git a/src/browser.c b/src/browser.c
index fc4527c..6787cf6 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -191,8 +191,6 @@ static void Run_Program_With_Directory (GtkWidget *combobox);
static void Destroy_Run_Program_List_Window (void);
static void Run_Program_With_Selected_Files (GtkWidget *combobox);
-static gboolean Run_Program (const gchar *program_name, GList *args_list);
-
static void empty_entry_disable_widget (GtkWidget *widget, GtkEntry *entry);
static void et_rename_directory_on_response (GtkDialog *dialog,
@@ -4119,7 +4117,7 @@ void Run_Program_With_Directory (GtkWidget *combobox)
// List of parameters (here only one! : the current directory)
args_list = g_list_append(args_list,current_directory);
- program_ran = Run_Program(program_name,args_list);
+ program_ran = et_run_program (program_name, args_list);
g_list_free(args_list);
if (program_ran)
@@ -4259,7 +4257,7 @@ Run_Program_With_Selected_Files (GtkWidget *combobox)
}
args_list = g_list_reverse (args_list);
- program_ran = Run_Program(program_name,args_list);
+ program_ran = et_run_program (program_name, args_list);
g_list_free_full (selected_paths, (GDestroyNotify)gtk_tree_path_free);
g_list_free(args_list);
@@ -4280,105 +4278,6 @@ Run_Program_With_Selected_Files (GtkWidget *combobox)
}
/*
- * Run a program with a list of parameters
- * - args_list : list of filename (with path)
- */
-static gboolean
-Run_Program (const gchar *program_name, GList *args_list)
-{
- gchar **argv_user;
- gint argv_user_number;
- gchar *msg;
- GPid pid;
- GError *error = NULL;
- gchar **argv;
- gint argv_index = 0;
- GList *l;
- gchar *program_path;
-
- g_return_val_if_fail (program_name != NULL && args_list != NULL, FALSE);
-
- /* Check if a name for the program have been supplied */
- if (!program_name || strlen(program_name)<1)
- {
- GtkWidget *msgdialog;
-
- msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- "%s",
- _("You must type a program name"));
- gtk_window_set_title(GTK_WINDOW(msgdialog),_("Program Name Error"));
-
- gtk_dialog_run(GTK_DIALOG(msgdialog));
- gtk_widget_destroy(msgdialog);
- return FALSE;
- }
-
- if ( !(program_path = Check_If_Executable_Exists(program_name)) )
- {
- GtkWidget *msgdialog;
-
- msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- _("The program '%s' cannot be found"),
- program_name);
- gtk_window_set_title(GTK_WINDOW(msgdialog),_("Program Name Error"));
-
- gtk_dialog_run(GTK_DIALOG(msgdialog));
- gtk_widget_destroy(msgdialog);
- return FALSE;
- }
-
- g_free(program_path); // Freed as never used
-
- 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++);
-
- argv = g_new0(gchar *,argv_user_number + g_list_length(args_list) + 1); // +1 for NULL
-
- // Load 'user' arguments (program name and more...)
- while (argv_user[argv_index])
- {
- argv[argv_index] = argv_user[argv_index];
- argv_index++;
- }
- // Load arguments from 'args_list'
- for (l = args_list; l != NULL; l = g_list_next (l))
- {
- argv[argv_index] = (gchar *)l->data;
- argv_index++;
- }
- argv[argv_index] = NULL;
-
- /* Execution ... */
- if (g_spawn_async (NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &pid, &error))
- {
- g_child_watch_add (pid, et_on_child_exited, NULL);
-
- msg = g_strdup_printf (_("Executed command: %s"), program_name);
- Statusbar_Message (msg, TRUE);
- g_free (msg);
- }
- else
- {
- Log_Print (LOG_ERROR, _("Failed to launch program: %s"),
- error->message);
- g_clear_error (&error);
- }
-
- g_strfreev (argv_user);
-
- return TRUE;
-}
-
-/*
* empty_entry_disable_widget:
* @widget: a widget to set sensitive if @entry contains text
* @entry: the entry for which to test the text
diff --git a/src/misc.c b/src/misc.c
index f077fd8..b6befe1 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -684,6 +684,137 @@ gint Combo_Alphabetic_Sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
}
+/*
+ * Run a program with a list of parameters
+ * - args_list : list of filename (with path)
+ */
+gboolean
+et_run_program (const gchar *program_name, GList *args_list)
+{
+ gchar *program_tmp;
+ const gchar *program_args;
+ gchar **program_args_argv = NULL;
+ guint n_program_args = 0;
+ gsize i;
+ gchar *msg;
+ GPid pid;
+ GError *error = NULL;
+ gchar **argv;
+ GList *l;
+ gchar *program_path;
+ gboolean res = FALSE;
+
+ g_return_val_if_fail (program_name != NULL && args_list != NULL, FALSE);
+
+ /* Check if a name for the program have been supplied */
+ if (!program_name && *program_name)
+ {
+ GtkWidget *msgdialog;
+
+ msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s",
+ _("You must type a program name"));
+ gtk_window_set_title(GTK_WINDOW(msgdialog),_("Program Name Error"));
+
+ gtk_dialog_run(GTK_DIALOG(msgdialog));
+ gtk_widget_destroy(msgdialog);
+ return res;
+ }
+
+ /* If user arguments are included, try to skip them. FIXME: This works
+ * poorly when there are spaces in the absolute path to the binary. */
+ 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)
+ {
+ size_t len;
+
+ len = program_args - program_tmp;
+ program_path = g_strndup (program_name, len);
+
+ /* 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;
+ program_path = g_strdup (program_name);
+ }
+
+ g_free (program_tmp);
+
+ /* +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[0] = program_path;
+
+ 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
+ {
+ i = 1;
+ }
+
+ /* Load arguments from 'args_list'. */
+ for (l = args_list; l != NULL; l = g_list_next (l), i++)
+ {
+ argv[i] = (gchar *)l->data;
+ }
+
+ argv[i] = NULL;
+
+ /* Execution ... */
+ if (g_spawn_async (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, &error))
+ {
+ g_child_watch_add (pid, et_on_child_exited, NULL);
+
+ msg = g_strdup_printf (_("Executed command: %s"), program_name);
+ Statusbar_Message (msg, TRUE);
+ g_free (msg);
+ res = TRUE;
+ }
+ else
+ {
+ Log_Print (LOG_ERROR, _("Failed to launch program: %s"),
+ error->message);
+ g_clear_error (&error);
+ }
+
+ g_strfreev (program_args_argv);
+ g_free (program_path);
+ g_free (argv);
+
+ return res;
+}
+
/*************************
* File selection window *
*************************/
@@ -747,113 +878,29 @@ static void Open_File_Selection_Window (GtkWidget *entry, gchar *title, GtkFileC
-/*
- * Run the audio player and load files of the current dir
- */
-static void
-Run_Audio_Player_Using_File_List (GList *etfilelist)
+void Run_Audio_Player_Using_Directory (void)
{
- gchar **argv;
- gint argv_index = 0;
GList *l;
- ET_File *etfile;
- gchar *filename;
- gchar *program_path;
- GPid pid;
- gchar **argv_user;
- gint argv_user_number;
- GError *error = NULL;
+ GList *path_list = NULL;
- g_return_if_fail (etfilelist != NULL);
-
- // Exit if no program selected...
- if (!AUDIO_FILE_PLAYER || strlen(g_strstrip(AUDIO_FILE_PLAYER))<1)
- {
- GtkWidget *msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE,
- "%s",
- _("No audio player defined"));
- gtk_window_set_title(GTK_WINDOW(msgdialog),_("Audio Player Warning"));
-
- gtk_dialog_run(GTK_DIALOG(msgdialog));
- gtk_widget_destroy(msgdialog);
-
- return;
- }
-
- if ( !(program_path = Check_If_Executable_Exists(AUDIO_FILE_PLAYER)) )
- {
- gchar *msg = g_strdup_printf(_("The program '%s' cannot be found"),AUDIO_FILE_PLAYER);
- Log_Print (LOG_ERROR, "%s", msg);
- g_free(msg);
- return;
- }
- g_free(program_path);
-
- argv_user = g_strsplit(AUDIO_FILE_PLAYER," ",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. */
- argv = g_new0 (gchar *,
- argv_user_number + g_list_length (etfilelist) + 1);
-
- // Load 'user' arguments (program name and more...)
- while (argv_user[argv_index])
- {
- argv[argv_index] = argv_user[argv_index];
- argv_index++;
- }
-
- // Load files as arguments
- for (l = etfilelist; l != NULL; l = g_list_next (l))
- {
- etfile = (ET_File *)l->data;
- filename = ((File_Name *)etfile->FileNameCur->data)->value;
- //filename_utf8 = ((File_Name *)etfile->FileNameCur->data)->value_utf8;
- argv[argv_index++] = filename;
- }
- argv[argv_index] = NULL; // Ends the list of arguments
-
- if (g_spawn_async (NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &pid, &error))
- {
- gchar *msg;
-
- g_child_watch_add (pid, et_on_child_exited, NULL);
-
- msg = g_strdup_printf (_("Executed command: %s"), argv[0]);
- Statusbar_Message (msg, TRUE);
- g_free (msg);
- }
- else
+ for (l = g_list_first (ETCore->ETFileList); l != NULL; l = g_list_next (l))
{
- Log_Print (LOG_ERROR, _("Failed to launch program: %s"),
- error->message);
- g_clear_error (&error);
+ ET_File *etfile = (ET_File *)l->data;
+ gchar *path = ((File_Name *)etfile->FileNameCur->data)->value;
+ path_list = g_list_prepend (path_list, path);
}
- g_strfreev (argv_user);
-
- g_free(argv);
-}
-
-void Run_Audio_Player_Using_Directory (void)
-{
- GList *etfilelist = g_list_first(ETCore->ETFileList);
+ path_list = g_list_reverse (path_list);
- Run_Audio_Player_Using_File_List(etfilelist);
+ et_run_program (AUDIO_FILE_PLAYER, path_list);
+ g_list_free (path_list);
}
void Run_Audio_Player_Using_Selection (void)
{
- GList *etfilelist = NULL;
GList *selfilelist = NULL;
GList *l;
- ET_File *etfile;
+ GList *path_list = NULL;
GtkTreeSelection *selection;
g_return_if_fail (BrowserList != NULL);
@@ -863,16 +910,16 @@ void Run_Audio_Player_Using_Selection (void)
for (l = selfilelist; l != NULL; l = g_list_next (l))
{
- etfile = Browser_List_Get_ETFile_From_Path(selfilelist->data);
- etfilelist = g_list_prepend (etfilelist, etfile);
+ ET_File *etfile = Browser_List_Get_ETFile_From_Path (l->data);
+ gchar *path = ((File_Name *)etfile->FileNameCur->data)->value;
+ path_list = g_list_prepend (path_list, path);
}
- etfilelist = g_list_reverse (etfilelist);
- g_list_free_full (selfilelist, (GDestroyNotify)gtk_tree_path_free);
-
- Run_Audio_Player_Using_File_List(etfilelist);
+ path_list = g_list_reverse (path_list);
- g_list_free(etfilelist);
+ et_run_program (AUDIO_FILE_PLAYER, path_list);
+ g_list_free (path_list);
+ g_list_free_full (selfilelist, (GDestroyNotify)gtk_tree_path_free);
}
void Run_Audio_Player_Using_Browser_Artist_List (void)
@@ -880,8 +927,8 @@ void Run_Audio_Player_Using_Browser_Artist_List (void)
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkTreeModel *artistListModel;
- GList *AlbumList, *etfilelist;
- GList *concatenated_list = NULL;
+ GList *l, *m;
+ GList *path_list = NULL;
g_return_if_fail (BrowserArtistList != NULL);
@@ -889,22 +936,23 @@ void Run_Audio_Player_Using_Browser_Artist_List (void)
if (!gtk_tree_selection_get_selected(selection, &artistListModel, &iter))
return;
- gtk_tree_model_get(artistListModel, &iter,
- ARTIST_ALBUM_LIST_POINTER, &AlbumList,
- -1);
+ gtk_tree_model_get (artistListModel, &iter, ARTIST_ALBUM_LIST_POINTER, &l,
+ -1);
- for (; AlbumList != NULL; AlbumList = g_list_next (AlbumList))
+ for (; l != NULL; l = g_list_next (l))
{
- etfilelist = g_list_copy((GList *)AlbumList->data);
- concatenated_list = concatenated_list ? g_list_concat (concatenated_list,
- etfilelist)
- : etfilelist;
+ for (m = l->data; m != NULL; m = g_list_next (m))
+ {
+ ET_File *etfile = (ET_File *)m->data;
+ gchar *path = ((File_Name *)etfile->FileNameCur->data)->value;
+ path_list = g_list_prepend (path_list, path);
+ }
}
- Run_Audio_Player_Using_File_List(concatenated_list);
+ path_list = g_list_reverse (path_list);
- if (concatenated_list)
- g_list_free(concatenated_list);
+ et_run_program (AUDIO_FILE_PLAYER, path_list);
+ g_list_free (path_list);
}
void Run_Audio_Player_Using_Browser_Album_List (void)
@@ -912,7 +960,8 @@ void Run_Audio_Player_Using_Browser_Album_List (void)
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkTreeModel *albumListModel;
- GList *etfilelist;
+ GList *l;
+ GList *path_list = NULL;
g_return_if_fail (BrowserAlbumList != NULL);
@@ -920,11 +969,20 @@ void Run_Audio_Player_Using_Browser_Album_List (void)
if (!gtk_tree_selection_get_selected(selection, &albumListModel, &iter))
return;
- gtk_tree_model_get(albumListModel, &iter,
- ALBUM_ETFILE_LIST_POINTER, &etfilelist,
- -1);
+ gtk_tree_model_get (albumListModel, &iter, ALBUM_ETFILE_LIST_POINTER, &l,
+ -1);
+
+ for (; l != NULL; l = g_list_next (l))
+ {
+ ET_File *etfile = (ET_File *)l->data;
+ gchar *path = ((File_Name *)etfile->FileNameCur->data)->value;
+ path_list = g_list_prepend (path_list, path);
+ }
+
+ path_list = g_list_reverse (path_list);
- Run_Audio_Player_Using_File_List(etfilelist);
+ et_run_program (AUDIO_FILE_PLAYER, path_list);
+ g_list_free (path_list);
}
diff --git a/src/misc.h b/src/misc.h
index 0aa843f..a013700 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -86,6 +86,8 @@ goffset et_get_file_size (const gchar *filename);
gint Combo_Alphabetic_Sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data);
+gboolean et_run_program (const gchar *program_name, GList *args_list);
+
void File_Selection_Window_For_File (GtkWidget *entry);
void File_Selection_Window_For_Directory (GtkWidget *entry);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]