summaryrefslogtreecommitdiff
path: root/regress/sys/kern/stackjmp/stackjmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'regress/sys/kern/stackjmp/stackjmp.c')
-rw-r--r--regress/sys/kern/stackjmp/stackjmp.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/regress/sys/kern/stackjmp/stackjmp.c b/regress/sys/kern/stackjmp/stackjmp.c
new file mode 100644
index 00000000000..aa73c2d97a0
--- /dev/null
+++ b/regress/sys/kern/stackjmp/stackjmp.c
@@ -0,0 +1,54 @@
+/* $OpenBSD: stackjmp.c,v 1.1 2012/06/23 05:54:49 matthew Exp $ */
+#include <assert.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+static jmp_buf jb;
+static char buf[SIGSTKSZ];
+static volatile int handled;
+
+static int
+isaltstack()
+{
+ stack_t os;
+ assert(sigaltstack(NULL, &os) == 0);
+ return (os.ss_flags & SS_ONSTACK) != 0;
+}
+
+static void
+inthandler(int signo)
+{
+ assert(isaltstack());
+ handled = 1;
+ siglongjmp(jb, 1);
+}
+
+int
+main()
+{
+ struct sigaction sa;
+ stack_t stack;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = inthandler;
+ sa.sa_flags = SA_ONSTACK;
+ assert(sigaction(SIGINT, &sa, NULL) == 0);
+
+ memset(&stack, 0, sizeof(stack));
+ stack.ss_sp = buf;
+ stack.ss_size = sizeof(buf);
+ stack.ss_flags = 0;
+ assert(sigaltstack(&stack, NULL) == 0);
+
+ assert(!isaltstack());
+ sigsetjmp(jb, 1);
+ assert(!isaltstack());
+ if (!handled) {
+ kill(getpid(), SIGINT);
+ assert(0); /* Shouldn't reach here. */
+ }
+
+ return (0);
+}