From: Martin Willi Date: Mon, 10 Mar 2014 11:12:47 +0000 (+0100) Subject: utils: Add a wait_sigint() function to wait for SIGINT or equivalent X-Git-Tag: 5.2.0dr6~24^2~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66c0801dc7a789f0f2143d55b5067f246bf95d5f;p=thirdparty%2Fstrongswan.git utils: Add a wait_sigint() function to wait for SIGINT or equivalent --- diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 0f12b58d7f..8ef9a1f338 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -31,12 +31,17 @@ #include #include #include +#ifndef WIN32 +# include +#endif #include #include #include #include #include +#include +#include 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 ac0841c49e..961ddb5835 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -542,6 +542,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).