diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2010-06-09 08:01:42 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2010-06-09 08:01:42 +0000 |
commit | bb4bce018962c5d7a0bb0776911e516ba78401c2 (patch) | |
tree | 298cf55eeb87ed5c63f7a8ba22f62b9c7d4c52cb /src/action.c | |
parent | bf8f09d3ba0cb9722a4aac217b3b2f49fc9b6683 (diff) |
action.c: prevent double free when using %f.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2566 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src/action.c')
-rw-r--r-- | src/action.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/action.c b/src/action.c index 1fc39335..894945b2 100644 --- a/src/action.c +++ b/src/action.c @@ -668,7 +668,7 @@ static gboolean execute_actions(gchar *action, GSList *msg_list, g_free(user_hidden_str); if (!children_list) { - /* If not waiting for children, return */ + /* If not waiting for children, return */ free_children(children); } else { GSList *cur; @@ -787,9 +787,9 @@ static ChildInfo *fork_child(gchar *cmd, const gchar *msg_str, close(chld_err[1]); close(chld_status[0]); - debug_print("Child: Waiting for grandchild\n"); + debug_print("Child: Waiting for grandchild (PID: %d)\n", gch_pid); waitpid(gch_pid, NULL, 0); - debug_print("Child: grandchild ended\n"); + debug_print("Child: grandchild ended (PID: %d)\n", gch_pid); write(chld_status[1], "0\n", 2); close(chld_status[1]); } @@ -838,6 +838,8 @@ static ChildInfo *fork_child(gchar *cmd, const gchar *msg_str, child_info->tag_err = gdk_input_add(chld_err[0], GDK_INPUT_READ, catch_output, child_info); + debug_print("Monitoring child (PID: %d)\n", pid); + if (!(children->action_type & (ACTION_PIPE_IN | ACTION_PIPE_OUT | ACTION_INSERT))) return child_info; @@ -879,6 +881,8 @@ static gint wait_for_children(Children *children) GSList *cur; gint nb = children->nb; + debug_print("wait_for_children (%p)\n", children); + children->nb = 0; cur = children->list; @@ -900,7 +904,7 @@ static gint wait_for_children(Children *children) return FALSE; if (!children->dialog) { - free_children(children); + /* free_children(children); */ } else if (!children->output) { gtk_widget_destroy(children->dialog); } @@ -983,6 +987,7 @@ static void free_children(Children *children) child_info = (ChildInfo *)children->list->data; #ifdef G_OS_UNIX if (child_info->pid != 0) { + debug_print("free_children: waiting PID %d\n", child_info->pid); if (waitpid(child_info->pid, NULL, 0) != child_info->pid) { perror("waitpid (free_children)"); @@ -1170,10 +1175,12 @@ static void catch_status(gpointer data, gint source, GdkInputCondition cond) gchar buf; gint c; + gdk_threads_enter(); + gdk_input_remove(child_info->tag_status); c = read(source, &buf, 1); - debug_print("Child returned %c\n", buf); + debug_print("Child (PID: %d) returned %c\n", child_info->pid, buf); #ifdef G_OS_UNIX waitpid(child_info->pid, NULL, 0); @@ -1182,6 +1189,8 @@ static void catch_status(gpointer data, gint source, GdkInputCondition cond) child_info->pid = 0; wait_for_children(child_info->children); + + gdk_threads_leave(); } static void catch_input(gpointer data, gint source, GdkInputCondition cond) @@ -1195,6 +1204,8 @@ static void catch_input(gpointer data, gint source, GdkInputCondition cond) if (!(cond && GDK_INPUT_WRITE)) return; + gdk_threads_enter(); + gdk_input_remove(child_info->tag_in); child_info->tag_in = -1; @@ -1219,6 +1230,8 @@ static void catch_input(gpointer data, gint source, GdkInputCondition cond) close(child_info->chld_in); child_info->chld_in = -1; debug_print("Input to grand child sent.\n"); + + gdk_threads_leave(); } static void catch_output(gpointer data, gint source, GdkInputCondition cond) @@ -1227,7 +1240,9 @@ static void catch_output(gpointer data, gint source, GdkInputCondition cond) gint c; gchar buf[BUFFSIZE]; - debug_print("Catching grand child's output.\n"); + gdk_threads_enter(); + + debug_print("Catching grand child's output (child PID: %d).\n", child_info->pid); if (child_info->children->action_type & (ACTION_PIPE_OUT | ACTION_INSERT) && source == child_info->chld_out) { @@ -1302,6 +1317,8 @@ static void catch_output(gpointer data, gint source, GdkInputCondition cond) } wait_for_children(child_info->children); + + gdk_threads_leave(); } static gchar *get_user_string(const gchar *action, ActionType type) |