Subject: [PATCH] polkitd: make sure child process exits will be processed This patch make 3 timers to ensure that the child process exits will be processed. Timer1: 10s send SIGTERM Timer2: 15s send SIGKILL Timer3: 20s exit the mainloop 0 ~ 10s: child exit normally 10 ~ 15s: child exit by SIGTERM 15 ~ 20s: child exit by SIGKILL 20s ~ : child seems to be abnormal. we don't wait and quit main loop. --- src/polkitbackend/polkitbackendjsauthority.c | 47 +++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c index 39ed718..00c2ece 100644 --- a/src/polkitbackend/polkitbackendjsauthority.c +++ b/src/polkitbackend/polkitbackendjsauthority.c @@ -1560,6 +1560,8 @@ typedef struct guint timeout_seconds; gboolean timed_out; GSource *timeout_source; + GSource *timeout_source_term; + GSource *timeout_source_kill; GString *child_stdout; GString *child_stderr; @@ -1765,6 +1767,37 @@ utils_timeout_cb (gpointer user_data) return FALSE; /* remove source */ } +static gboolean +utils_timeout_cb_signal (gpointer user_data, guint signal) +{ + UtilsSpawnData *data = user_data; + + data->timed_out = TRUE; + + /* ok, timeout is history */ + data->timeout_source_term = NULL; + + if (data->child_pid > 0) + { + g_print ("Polkitd: Timeout was reached, kill %d %d\n", signal, data->child_pid); + kill (data->child_pid, signal); + } + + return FALSE; /* remove source */ +} + +static gboolean +utils_timeout_cb_term (gpointer user_data) +{ + return utils_timeout_cb_signal (user_data, SIGTERM); +} + +static gboolean +utils_timeout_cb_kill (gpointer user_data) +{ + return utils_timeout_cb_signal (user_data, SIGKILL); +} + static void utils_spawn (const gchar *const *argv, guint timeout_seconds, @@ -1836,7 +1869,19 @@ utils_spawn (const gchar *const *argv, if (timeout_seconds > 0) { - data->timeout_source = g_timeout_source_new_seconds (timeout_seconds); + data->timeout_source_term = g_timeout_source_new_seconds (timeout_seconds); + g_source_set_priority (data->timeout_source_term, G_PRIORITY_DEFAULT); + g_source_set_callback (data->timeout_source_term, utils_timeout_cb_term, data, NULL); + g_source_attach (data->timeout_source_term, data->main_context); + g_source_unref (data->timeout_source_term); + + data->timeout_source_kill = g_timeout_source_new_seconds (timeout_seconds + 5); + g_source_set_priority (data->timeout_source_kill, G_PRIORITY_DEFAULT); + g_source_set_callback (data->timeout_source_kill, utils_timeout_cb_kill, data, NULL); + g_source_attach (data->timeout_source_kill, data->main_context); + g_source_unref (data->timeout_source_kill); + + data->timeout_source = g_timeout_source_new_seconds (timeout_seconds + 10); g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT); g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL); g_source_attach (data->timeout_source, data->main_context); -- 1.8.3.1