Use sigsetjmp()/siglongjmp() when available

Without using siglongjmp, the signal mask is not restored when
longjmp-ing from the signal handler, and whichever signal was
being handled remains blocked for the remainder of the tests. As a
result, the same signal cannot be caught twice, and will cause process
termination when being raised the second time.

This does not change 'jmp_buf global_expect_assert_env', because it is
part of the public API, and isn't used from a signal handler.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index c0dd13d..c82f099 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -76,6 +76,7 @@
 check_function_exists(fprintf HAVE_FPRINTF)
 check_function_exists(free HAVE_FREE)
 check_function_exists(longjmp HAVE_LONGJMP)
+check_function_exists(siglongjmp HAVE_SIGLONGJMP)
 check_function_exists(malloc HAVE_MALLOC)
 check_function_exists(memcpy HAVE_MEMCPY)
 check_function_exists(memset HAVE_MEMSET)
diff --git a/config.h.cmake b/config.h.cmake
index 78cce7a..920bb10 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -110,6 +110,9 @@
 /* Define to 1 if you have the `longjmp' function. */
 #cmakedefine HAVE_LONGJMP 1
 
+/* Define to 1 if you have the `siglongjmp' function. */
+#cmakedefine HAVE_SIGLONGJMP 1
+
 /* Define to 1 if you have the `malloc' function. */
 #cmakedefine HAVE_MALLOC 1
 
diff --git a/src/cmocka.c b/src/cmocka.c
index 284d55f..fda3682 100644
--- a/src/cmocka.c
+++ b/src/cmocka.c
@@ -84,6 +84,20 @@
 #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
 #endif
 
+/**
+ * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
+ */
+#ifdef HAVE_SIGLONGJMP
+# define cm_jmp_buf             sigjmp_buf
+# define cm_setjmp(env)         sigsetjmp(env, 1)
+# define cm_longjmp(env, val)   siglongjmp(env, val)
+#else
+# define cm_jmp_buf             jmp_buf
+# define cm_setjmp(env)         setjmp(env)
+# define cm_longjmp(env, val)   longjmp(env, val)
+#endif
+
+
 /*
  * Declare and initialize the pointer member of ValuePointer variable name
  * with ptr.
@@ -238,7 +252,7 @@
  * Keeps track of the calling context returned by setenv() so that the fail()
  * method can jump out of a test.
  */
-static CMOCKA_THREAD jmp_buf global_run_test_env;
+static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
 static CMOCKA_THREAD int global_running_test = 0;
 
 /* Keeps track of the calling context returned by setenv() so that */
@@ -347,7 +361,7 @@
         print_error("%s", cm_error_message);
         abort();
     } else if (global_running_test) {
-        longjmp(global_run_test_env, 1);
+        cm_longjmp(global_run_test_env, 1);
     } else if (quit_application) {
         exit(-1);
     }
@@ -2339,7 +2353,7 @@
 
     global_running_test = 1;
 
-    if (setjmp(global_run_test_env) == 0) {
+    if (cm_setjmp(global_run_test_env) == 0) {
         if (test_func != NULL) {
             test_func(state != NULL ? state : &current_state);
 
@@ -2677,7 +2691,7 @@
     }
     initialize_testing(function_name);
     global_running_test = 1;
-    if (setjmp(global_run_test_env) == 0) {
+    if (cm_setjmp(global_run_test_env) == 0) {
         Function(state ? state : &current_state);
         fail_if_leftover_values(function_name);