aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2014-03-10 12:12:47 +0100
committerMartin Willi <martin@revosec.ch>2014-06-04 15:53:11 +0200
commit66c0801dc7a789f0f2143d55b5067f246bf95d5f (patch)
tree3ade425bd42b4987901f63d759bfd9c5d93ee443
parent13298719e3edc01fcbd1b3cb85ee36efaa573822 (diff)
downloadstrongswan-66c0801dc7a789f0f2143d55b5067f246bf95d5f.tar.bz2
strongswan-66c0801dc7a789f0f2143d55b5067f246bf95d5f.tar.xz
utils: Add a wait_sigint() function to wait for SIGINT or equivalent
-rw-r--r--src/libstrongswan/utils/utils.c83
-rw-r--r--src/libstrongswan/utils/utils.h5
2 files changed, 88 insertions, 0 deletions
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c
index 0f12b58d7..8ef9a1f33 100644
--- a/src/libstrongswan/utils/utils.c
+++ b/src/libstrongswan/utils/utils.c
@@ -31,12 +31,17 @@
#include <limits.h>
#include <dirent.h>
#include <time.h>
+#ifndef WIN32
+# include <signal.h>
+#endif
#include <library.h>
#include <utils/debug.h>
#include <utils/chunk.h>
#include <collections/enumerator.h>
#include <threading/spinlock.h>
+#include <threading/mutex.h>
+#include <threading/condvar.h>
ENUM(status_names, SUCCESS, NEED_MORE,
"SUCCESS",
@@ -222,6 +227,84 @@ char* strreplace(const char *str, const char *search, const char *replace)
return res;
}
+#ifdef WIN32
+
+/**
+ * Flag to indicate signaled wait_sigint()
+ */
+static bool sigint_signaled = FALSE;
+
+/**
+ * Condvar to wait in wait_sigint()
+ */
+static condvar_t *sigint_cond;
+
+/**
+ * Mutex to check signaling()
+ */
+static mutex_t *sigint_mutex;
+
+/**
+ * Control handler to catch ^C
+ */
+static BOOL handler(DWORD dwCtrlType)
+{
+ switch (dwCtrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ sigint_mutex->lock(sigint_mutex);
+ sigint_signaled = TRUE;
+ sigint_cond->signal(sigint_cond);
+ sigint_mutex->unlock(sigint_mutex);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Windows variant
+ */
+void wait_sigint()
+{
+ SetConsoleCtrlHandler(handler, TRUE);
+
+ sigint_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ sigint_cond = condvar_create(CONDVAR_TYPE_DEFAULT);
+
+ sigint_mutex->lock(sigint_mutex);
+ while (!sigint_signaled)
+ {
+ sigint_cond->wait(sigint_cond, sigint_mutex);
+ }
+ sigint_mutex->unlock(sigint_mutex);
+
+ sigint_mutex->destroy(sigint_mutex);
+ sigint_cond->destroy(sigint_cond);
+}
+
+#else /* !WIN32 */
+
+/**
+ * Unix variant
+ */
+void wait_sigint()
+{
+ sigset_t set;
+ int sig;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGTERM);
+
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ sigwait(&set, &sig);
+}
+
+#endif
+
/**
* Described in header.
*/
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
index ac0841c49..961ddb583 100644
--- a/src/libstrongswan/utils/utils.h
+++ b/src/libstrongswan/utils/utils.h
@@ -543,6 +543,11 @@ char *translate(char *str, const char *from, const char *to);
char *strreplace(const char *str, const char *search, const char *replace);
/**
+ * Portable function to wait for SIGINT/SIGTERM (or equivalent).
+ */
+void wait_sigint();
+
+/**
* Like dirname(3) returns the directory part of the given null-terminated
* pathname, up to but not including the final '/' (or '.' if no '/' is found).
* Trailing '/' are not counted as part of the pathname.