On 12/17/2012 03:31 PM, Jakub Filak wrote:
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/applet/applet.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/src/applet/applet.c b/src/applet/applet.c
index 602e0fa..4408246 100644
--- a/src/applet/applet.c
+++ b/src/applet/applet.c
@@ -66,6 +66,7 @@ static char *ap_last_problem_dir;
static char **s_dirs;
static GList *g_deferred_crash_queue;
static guint g_deferred_timeout;
+static int g_signal_pipe[2];
static bool is_autoreporting_enabled(void)
{
@@ -1159,6 +1160,35 @@ static void die_if_dbus_error(bool error_flag, DBusError* err,
const char* msg)
error_msg_and_die("%s", msg);
}
+static void handle_signal(int signo)
+{
+ int save_errno = errno;
+
+ // Enable for debugging only, malloc/printf are unsafe in signal handlers
+ //VERB3 log("Got signal %d", signo);
+
+ uint8_t sig_caught = signo;
+ if (write(g_signal_pipe[1], &sig_caught, 1))
+ /* we ignore result, if () shuts up stupid compiler */;
+
+ errno = save_errno;
+}
+
+static gboolean handle_sigterm_pipe(GIOChannel *gio, GIOCondition condition, gpointer
ptr_unused)
+{
+ /* It can be only SIGTERM.
+ * We are going to quit.
+ * Therefore No read from the channel is necessary.
+ */
+
+ /* Next received SIGTERM will kill the applet. */
+ signal(SIGTERM, SIG_DFL);
+
+ gtk_main_quit();
+
+ return FALSE; /* Pointless (loop is done and signal handler was reseted);
"please remove this event" */
"was reset"
+}
+
int main(int argc, char** argv)
{
/* I18n */
@@ -1329,9 +1359,24 @@ int main(int argc, char** argv)
list_free_with_free(new_dirs);
+ /* Set up signal pipe */
/* (Comment why do we need to handle SIGTERM. What would happen if we don't?) */
+ xpipe(g_signal_pipe);
+ close_on_exec_on(g_signal_pipe[0]);
+ close_on_exec_on(g_signal_pipe[1]);
+ ndelay_on(g_signal_pipe[0]);
+ ndelay_on(g_signal_pipe[1]);
+ signal(SIGTERM, handle_signal);
+ GIOChannel *channel_id_signal = my_io_channel_unix_new(g_signal_pipe[0]);
+ g_io_add_watch(channel_id_signal,
+ G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ handle_sigterm_pipe,
+ NULL);
+
/* Enter main loop */
gtk_main();
+ g_io_channel_unref(channel_id_signal);
+
/* GTK3 doesn't return from main loop in case of termination due to desktop
* session end. (GTK handles XSMP (X Session Management Protocol) messages
* on its own and exits on session end.)