diff options
author | Martin Willi <martin@revosec.ch> | 2014-03-10 12:12:47 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-06-04 15:53:11 +0200 |
commit | 66c0801dc7a789f0f2143d55b5067f246bf95d5f (patch) | |
tree | 3ade425bd42b4987901f63d759bfd9c5d93ee443 | |
parent | 13298719e3edc01fcbd1b3cb85ee36efaa573822 (diff) | |
download | strongswan-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.c | 83 | ||||
-rw-r--r-- | src/libstrongswan/utils/utils.h | 5 |
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. |