gsubprocess: Fix a number of leaks and a segfault

Fixed a number of leaks in gsubprocess, as well as a segfault
that was hidden by never calling g_subprocess_communicate_state_free().

https://bugzilla.gnome.org/show_bug.cgi?id=711803
This commit is contained in:
Stef Walter 2013-11-09 08:51:41 +01:00
parent d10f35310f
commit 1e5e3b64a8

View File

@ -405,6 +405,7 @@ g_subprocess_exited (GPid pid,
while (tasks) while (tasks)
{ {
g_task_return_boolean (tasks->data, TRUE); g_task_return_boolean (tasks->data, TRUE);
g_object_unref (tasks->data);
tasks = g_slist_delete_link (tasks, tasks); tasks = g_slist_delete_link (tasks, tasks);
} }
@ -597,7 +598,7 @@ g_subprocess_finalize (GObject *object)
g_clear_object (&self->stdin_pipe); g_clear_object (&self->stdin_pipe);
g_clear_object (&self->stdout_pipe); g_clear_object (&self->stdout_pipe);
g_clear_object (&self->stderr_pipe); g_clear_object (&self->stderr_pipe);
g_free (self->argv); g_strfreev (self->argv);
G_OBJECT_CLASS (g_subprocess_parent_class)->finalize (object); G_OBJECT_CLASS (g_subprocess_parent_class)->finalize (object);
} }
@ -1467,13 +1468,17 @@ g_subprocess_communicate_state_free (gpointer data)
{ {
CommunicateState *state = data; CommunicateState *state = data;
g_clear_object (&state->cancellable);
g_clear_object (&state->stdin_buf); g_clear_object (&state->stdin_buf);
g_clear_object (&state->stdout_buf); g_clear_object (&state->stdout_buf);
g_clear_object (&state->stderr_buf); g_clear_object (&state->stderr_buf);
if (state->cancellable_source)
{
if (!g_source_is_destroyed (state->cancellable_source)) if (!g_source_is_destroyed (state->cancellable_source))
g_source_destroy (state->cancellable_source); g_source_destroy (state->cancellable_source);
g_source_unref (state->cancellable_source); g_source_unref (state->cancellable_source);
}
g_slice_free (CommunicateState, state); g_slice_free (CommunicateState, state);
} }
@ -1539,6 +1544,7 @@ g_subprocess_communicate_internal (GSubprocess *subprocess,
g_subprocess_communicate_made_progress, g_object_ref (task)); g_subprocess_communicate_made_progress, g_object_ref (task));
state->outstanding_ops++; state->outstanding_ops++;
g_object_unref (task);
return state; return state;
} }