summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Catanzaro <mcatanzaro@gnome.org>2016-10-31 17:28:02 -0500
committerMichael Catanzaro <mcatanzaro@gnome.org>2016-10-31 17:36:32 -0500
commit8094d949c2c85405fbafb7ce8caeaab5469ef032 (patch)
treeba334a801d7f320cda3c570ad0c40bd000fe2682
parent4350e43d7423c8f438b877b9ff88a1c3c5c0d0d7 (diff)
downloadepiphany-8094d949c2c85405fbafb7ce8caeaab5469ef032.tar.gz
main: Exit cleanly on SIGINT or SIGTERM
-rw-r--r--src/ephy-main.c35
-rw-r--r--src/ephy-shell.c8
-rw-r--r--src/ephy-shell.h2
-rw-r--r--src/window-commands.c3
4 files changed, 44 insertions, 4 deletions
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 65d97ed5e..c6413c10b 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -34,10 +34,12 @@
#include <errno.h>
#include <glib/gi18n.h>
+#include <glib-unix.h>
#include <gtk/gtk.h>
#include <libnotify/notify.h>
#include <libxml/xmlreader.h>
#include <libxml/xmlversion.h>
+#include <signal.h>
#include <string.h>
#include <stdlib.h>
@@ -56,6 +58,31 @@ static gboolean application_mode = FALSE;
static char *desktop_file_basename = NULL;
static char *profile_directory = NULL;
+static EphyShell *ephy_shell = NULL;
+static int shutdown_signum = 0;
+
+static gboolean
+handle_shutdown_signal (gpointer user_data)
+{
+ shutdown_signum = GPOINTER_TO_INT (user_data);
+
+ /* Note that this function executes on the main loop AFTER the signal handler
+ * has returned, so we don't have to worry about async signal safety.
+ */
+ g_assert (ephy_shell != NULL);
+ ephy_shell_try_quit (ephy_shell);
+
+ /* Goals:
+ *
+ * (1) Shutdown safely and cleanly if signal is received once.
+ * (2) Shutdown unsafely but immediately if signal is received twice.
+ * (3) Always re-raise the signal so the parent process knows what happened.
+ *
+ * Removing this source is required by goals (2) and (3).
+ */
+ return G_SOURCE_REMOVE;
+}
+
static gboolean
application_mode_cb (const gchar *option_name,
const gchar *value,
@@ -166,7 +193,6 @@ main (int argc,
EphyShellStartupContext *ctx;
EphyStartupFlags startup_flags;
EphyEmbedShellMode mode;
- EphyShell *ephy_shell;
int status;
EphyFileHelpersFlags flags;
GDesktopAppInfo *desktop_info = NULL;
@@ -400,6 +426,10 @@ main (int argc,
g_strfreev (arguments);
ephy_shell = ephy_shell_get_default ();
ephy_shell_set_startup_context (ephy_shell, ctx);
+
+ g_unix_signal_add (SIGINT, (GSourceFunc)handle_shutdown_signal, GINT_TO_POINTER (SIGINT));
+ g_unix_signal_add (SIGTERM, (GSourceFunc)handle_shutdown_signal, GINT_TO_POINTER (SIGTERM));
+
status = g_application_run (G_APPLICATION (ephy_shell), argc, argv);
/* Shutdown */
@@ -415,5 +445,8 @@ main (int argc,
ephy_file_helpers_shutdown ();
xmlCleanupParser ();
+ if (shutdown_signum != 0)
+ raise (shutdown_signum);
+
return status;
}
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index ffee46fd8..80d8ac072 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -905,6 +905,13 @@ ephy_shell_close_all_windows (EphyShell *shell)
return retval;
}
+void
+ephy_shell_try_quit (EphyShell *shell)
+{
+ if (ephy_shell_close_all_windows (shell))
+ g_application_quit (G_APPLICATION (shell));
+}
+
typedef struct {
EphyShell *shell;
EphySession *session;
@@ -1054,4 +1061,3 @@ ephy_shell_open_uris (EphyShell *shell,
shell->open_uris_idle_ids = g_slist_prepend (shell->open_uris_idle_ids, GUINT_TO_POINTER (id));
}
-
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 74fd03908..31d763f49 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -112,6 +112,8 @@ guint ephy_shell_get_n_windows (EphyShell *shell);
gboolean ephy_shell_close_all_windows (EphyShell *shell);
+void ephy_shell_try_quit (EphyShell *shell);
+
void ephy_shell_open_uris (EphyShell *shell,
const char **uris,
EphyStartupFlags startup_flags,
diff --git a/src/window-commands.c b/src/window-commands.c
index 4011382be..f48597c7d 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -283,8 +283,7 @@ window_cmd_quit (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
- if (ephy_shell_close_all_windows (ephy_shell_get_default ()))
- g_application_quit (g_application_get_default ());
+ ephy_shell_try_quit (ephy_shell_get_default ());
}
void