summaryrefslogtreecommitdiff
path: root/src/sig_handler.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2011-02-16 22:51:37 (GMT)
committerChristian Pointner <equinox@helsinki.at>2011-02-16 22:51:37 (GMT)
commitdb20dcf04d70d525d2a8e055e1ada0a7338cda98 (patch)
treebb72c6a00947c358125f4007653af1cba8f86efa /src/sig_handler.c
parentec6b037cd20e09766279689755df745e3da756ce (diff)
added signal handler
Diffstat (limited to 'src/sig_handler.c')
-rw-r--r--src/sig_handler.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/sig_handler.c b/src/sig_handler.c
new file mode 100644
index 0000000..e2afb17
--- /dev/null
+++ b/src/sig_handler.c
@@ -0,0 +1,111 @@
+/*
+ * rharchive
+ *
+ * rharchive is a simple tcp connection proxy which combines the
+ * features of rinetd and 6tunnel. rharchive supports IPv4 and
+ * IPv6 and also supports connections from IPv6 to IPv4
+ * endpoints and vice versa.
+ *
+ *
+ * Copyright (C) 2010-2011 Christian Pointner <equinox@helsinki.at>
+ *
+ * This file is part of rharchive.
+ *
+ * rharchive 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.
+ *
+ * rharchive 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 rharchive. 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,TRUE, TRUE, G_THREAD_PRIORITY_HIGH, NULL);
+ if(!signal_thread)
+ return -1;
+
+ return 0;
+}
+
+void signal_stop()
+{
+ // nothing yet..
+}