summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2014-03-07 16:12:04 +1300
committerRobert Ancell <robert.ancell@canonical.com>2014-03-07 16:12:04 +1300
commitd3dad011cba8e0f55a420d2bfdec3eae8f4df39c (patch)
tree1e3ed07a5620cca637a80d0ea91cbcb4e7071343
parentdcbdb0f63bbb5c796145376cf2f3535124ee7ae2 (diff)
downloadlightdm-git-d3dad011cba8e0f55a420d2bfdec3eae8f4df39c.tar.gz
Handle signals being received in child processes instead of treating them like they are received in the daemon
-rw-r--r--src/process.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/process.c b/src/process.c
index 860220ff..5fe11e72 100644
--- a/src/process.c
+++ b/src/process.c
@@ -58,6 +58,7 @@ G_DEFINE_TYPE (Process, process, G_TYPE_OBJECT);
static Process *current_process = NULL;
static GHashTable *processes = NULL;
+static pid_t signal_pid;
static int signal_pipe[2];
Process *
@@ -306,10 +307,15 @@ process_finalize (GObject *object)
static void
signal_cb (int signum, siginfo_t *info, void *data)
{
- /* NOTE: Using g_printerr as can't call g_warning from a signal callback */
+ /* Check if we are from a forked process that hasn't updated the signal handlers or execed.
+ If so, then we should just quit */
+ if (getpid () != signal_pid)
+ _exit (EXIT_SUCCESS);
+
+ /* Write signal to main thread, if something goes wrong just close the pipe so it is detected on the other end */
if (write (signal_pipe[1], &info->si_signo, sizeof (int)) < 0 ||
write (signal_pipe[1], &info->si_pid, sizeof (pid_t)) < 0)
- g_printerr ("Failed to write to signal pipe: %s", strerror (errno));
+ close (signal_pipe[1]);
}
static gboolean
@@ -323,7 +329,7 @@ handle_signal (GIOChannel *source, GIOCondition condition, gpointer data)
read (signal_pipe[0], &pid, sizeof (pid_t)) < 0)
{
g_warning ("Error reading from signal pipe: %s", strerror (errno));
- return TRUE;
+ return FALSE;
}
g_debug ("Got signal %d from process %d", signo, pid);
@@ -384,6 +390,7 @@ process_class_init (ProcessClass *klass)
/* Catch signals and feed them to the main loop via a pipe */
processes = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ signal_pid = getpid ();
if (pipe (signal_pipe) != 0)
g_critical ("Failed to create signal pipe");
fcntl (signal_pipe[0], F_SETFD, FD_CLOEXEC);