summaryrefslogtreecommitdiff
path: root/src/sig_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sig_handler.c')
-rw-r--r--src/sig_handler.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/sig_handler.c b/src/sig_handler.c
new file mode 100644
index 0000000..68a95cb
--- /dev/null
+++ b/src/sig_handler.c
@@ -0,0 +1,109 @@
+/*
+ * gstdvbbackend
+ *
+ * gstdvbbackend is a small programm which captures a given set of dvb
+ * channels from one dvb device and provides the streams via minimal http.
+ *
+ *
+ * Copyright (C) 2011 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of gstdvbbackend.
+ *
+ * gstdvbbackend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * gstdvbbackend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gstdvbbackend. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "datatypes.h"
+
+#include "log.h"
+
+#include "sig_handler.h"
+
+#include <glib.h>
+#include <errno.h>
+
+static GThread *signal_thread;
+
+void signal_init()
+{
+ sigset_t signal_set;
+
+ sigemptyset(&signal_set);
+ sigaddset(&signal_set, SIGINT);
+ sigaddset(&signal_set, SIGQUIT);
+ sigaddset(&signal_set, SIGHUP);
+ sigaddset(&signal_set, SIGTERM);
+ sigaddset(&signal_set, SIGUSR1);
+ sigaddset(&signal_set, SIGUSR2);
+
+ pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
+}
+
+static gpointer signal_thread_func(gpointer data)
+{
+ GMainLoop *loop = (GMainLoop *)data;
+
+ struct timespec timeout;
+ sigset_t signal_set;
+ int sig_num;
+ for(;;) {
+ sigemptyset(&signal_set);
+ sigaddset(&signal_set, SIGINT);
+ sigaddset(&signal_set, SIGQUIT);
+ sigaddset(&signal_set, SIGHUP);
+ sigaddset(&signal_set, SIGTERM);
+ sigaddset(&signal_set, SIGUSR1);
+ sigaddset(&signal_set, SIGUSR2);
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+ sig_num = sigtimedwait(&signal_set, NULL, &timeout);
+ if(sig_num == -1) {
+ if(errno != EINTR && errno != EAGAIN) {
+ log_printf(ERROR, "sigwait failed with error: %d, signal handling will be disabled", errno);
+ break;
+ }
+ } else {
+ switch(sig_num) {
+ case SIGTERM:
+ case SIGINT:
+ case SIGQUIT: {
+ log_printf(NOTICE, "signal %d received, exiting", sig_num);
+ g_main_loop_quit(loop);
+ break;
+ }
+ default: {
+ log_printf(NOTICE, "signal %d received, ignoring", sig_num);
+ break;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+int signal_start(GMainLoop *loop)
+{
+ g_assert(!signal_thread);
+
+ signal_thread = g_thread_create_full(signal_thread_func, loop, 8192, FALSE, TRUE, G_THREAD_PRIORITY_HIGH, NULL);
+ if(!signal_thread)
+ return -1;
+
+ return 0;
+}
+
+void signal_stop()
+{
+ // nothing yet..
+}