diff options
Diffstat (limited to 'src/recoverable-problem.c')
-rw-r--r-- | src/recoverable-problem.c | 232 |
1 files changed, 116 insertions, 116 deletions
diff --git a/src/recoverable-problem.c b/src/recoverable-problem.c index 7aff163..670b78c 100644 --- a/src/recoverable-problem.c +++ b/src/recoverable-problem.c @@ -23,145 +23,145 @@ #include <errno.h> /* Helpers to ensure we write nicely */ -static void +static void write_string (int fd, const gchar *string) { - int res; - do - res = write (fd, string, strlen (string)); - while (G_UNLIKELY (res == -1 && errno == EINTR)); + int res; + do + res = write (fd, string, strlen (string)); + while (G_UNLIKELY (res == -1 && errno == EINTR)); } /* Make NULLs fast and fun! */ -static void +static void write_null (int fd) { - int res; - do - res = write (fd, "", 1); - while (G_UNLIKELY (res == -1 && errno == EINTR)); + int res; + do + res = write (fd, "", 1); + while (G_UNLIKELY (res == -1 && errno == EINTR)); } /* Child watcher */ static gboolean apport_child_watch (GPid pid G_GNUC_UNUSED, gint status G_GNUC_UNUSED, gpointer user_data) { - g_main_loop_quit((GMainLoop *)user_data); - return FALSE; + g_main_loop_quit((GMainLoop *)user_data); + return FALSE; } static gboolean apport_child_timeout (gpointer user_data) { - g_warning("Recoverable Error Reporter Timeout"); - g_main_loop_quit((GMainLoop *)user_data); - return FALSE; + g_warning("Recoverable Error Reporter Timeout"); + g_main_loop_quit((GMainLoop *)user_data); + return FALSE; } /* Code to report an error */ void report_recoverable_problem (const gchar * signature, GPid report_pid, gboolean wait, gchar * additional_properties[]) { - GSpawnFlags flags; - gboolean first; - GError * error = NULL; - gint error_stdin = 0; - GPid pid = 0; - gchar * pid_str = NULL; - gchar ** argv = NULL; - gchar * argv_nopid[2] = { - "/usr/share/apport/recoverable_problem", - NULL - }; - gchar * argv_pid[4] = { - "/usr/share/apport/recoverable_problem", - "-p", - NULL, /* put pid_str when allocated here */ - NULL - }; - - - argv = (gchar **)argv_nopid; - - if (report_pid != 0) { - pid_str = g_strdup_printf("%d", report_pid); - argv_pid[2] = pid_str; - argv = (gchar**)argv_pid; - } - - flags = G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; - if (wait) { - flags |= G_SPAWN_DO_NOT_REAP_CHILD; - } - - g_spawn_async_with_pipes(NULL, /* cwd */ - argv, - NULL, /* envp */ - flags, - NULL, NULL, /* child setup func */ - &pid, - &error_stdin, - NULL, /* stdout */ - NULL, /* stderr */ - &error); - - if (error != NULL) { - g_warning("Unable to report a recoverable error: %s", error->message); - g_error_free(error); - } - - first = TRUE; - - if (error_stdin != 0 && signature != NULL) { - write_string(error_stdin, "DuplicateSignature"); - write_null(error_stdin); - write_string(error_stdin, signature); - - first = FALSE; - } - - if (error_stdin != 0 && additional_properties != NULL) { - gint i; - for (i = 0; additional_properties[i] != NULL; i++) { - if (!first) { - write_null(error_stdin); - } else { - first = FALSE; - } - - write_string(error_stdin, additional_properties[i]); - } - } - - if (error_stdin != 0) { - close(error_stdin); - } - - if (wait && pid != 0) { - GSource * child_source, * timeout_source; - GMainContext * context = g_main_context_new(); - GMainLoop * loop = g_main_loop_new(context, FALSE); - - child_source = g_child_watch_source_new(pid); - g_source_attach(child_source, context); - g_source_set_callback(child_source, (GSourceFunc)apport_child_watch, loop, NULL); - - timeout_source = g_timeout_source_new_seconds(5); - g_source_attach(timeout_source, context); - g_source_set_callback(timeout_source, apport_child_timeout, loop, NULL); - - g_main_loop_run(loop); - - g_source_destroy(timeout_source); - g_source_destroy(child_source); - g_main_loop_unref(loop); - g_main_context_unref(context); - - g_spawn_close_pid(pid); - } - - g_free(pid_str); - - return; + GSpawnFlags flags; + gboolean first; + GError * error = NULL; + gint error_stdin = 0; + GPid pid = 0; + gchar * pid_str = NULL; + gchar ** argv = NULL; + gchar * argv_nopid[2] = { + "/usr/share/apport/recoverable_problem", + NULL + }; + gchar * argv_pid[4] = { + "/usr/share/apport/recoverable_problem", + "-p", + NULL, /* put pid_str when allocated here */ + NULL + }; + + + argv = (gchar **)argv_nopid; + + if (report_pid != 0) { + pid_str = g_strdup_printf("%d", report_pid); + argv_pid[2] = pid_str; + argv = (gchar**)argv_pid; + } + + flags = G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; + if (wait) { + flags |= G_SPAWN_DO_NOT_REAP_CHILD; + } + + g_spawn_async_with_pipes(NULL, /* cwd */ + argv, + NULL, /* envp */ + flags, + NULL, NULL, /* child setup func */ + &pid, + &error_stdin, + NULL, /* stdout */ + NULL, /* stderr */ + &error); + + if (error != NULL) { + g_warning("Unable to report a recoverable error: %s", error->message); + g_error_free(error); + } + + first = TRUE; + + if (error_stdin != 0 && signature != NULL) { + write_string(error_stdin, "DuplicateSignature"); + write_null(error_stdin); + write_string(error_stdin, signature); + + first = FALSE; + } + + if (error_stdin != 0 && additional_properties != NULL) { + gint i; + for (i = 0; additional_properties[i] != NULL; i++) { + if (!first) { + write_null(error_stdin); + } else { + first = FALSE; + } + + write_string(error_stdin, additional_properties[i]); + } + } + + if (error_stdin != 0) { + close(error_stdin); + } + + if (wait && pid != 0) { + GSource * child_source, * timeout_source; + GMainContext * context = g_main_context_new(); + GMainLoop * loop = g_main_loop_new(context, FALSE); + + child_source = g_child_watch_source_new(pid); + g_source_attach(child_source, context); + g_source_set_callback(child_source, (GSourceFunc)apport_child_watch, loop, NULL); + + timeout_source = g_timeout_source_new_seconds(5); + g_source_attach(timeout_source, context); + g_source_set_callback(timeout_source, apport_child_timeout, loop, NULL); + + g_main_loop_run(loop); + + g_source_destroy(timeout_source); + g_source_destroy(child_source); + g_main_loop_unref(loop); + g_main_context_unref(context); + + g_spawn_close_pid(pid); + } + + g_free(pid_str); + + return; } |