xref: /openbsd-src/regress/sys/kern/stackjmp/stackjmp.c (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1 /*	$OpenBSD: stackjmp.c,v 1.3 2013/12/21 05:45:04 guenther Exp $	*/
2 /*
3  * Written by Matthew Dempsky, 2012.
4  * Public domain.
5  */
6 
7 #include <assert.h>
8 #include <setjmp.h>
9 #include <signal.h>
10 #include <string.h>
11 #include <unistd.h>
12 
13 static sigjmp_buf jb;
14 static char buf[SIGSTKSZ];
15 static volatile int handled;
16 
17 static int
18 isaltstack()
19 {
20 	stack_t os;
21 	assert(sigaltstack(NULL, &os) == 0);
22 	return (os.ss_flags & SS_ONSTACK) != 0;
23 }
24 
25 static void
26 inthandler(int signo)
27 {
28 	assert(isaltstack());
29 	handled = 1;
30 	siglongjmp(jb, 1);
31 }
32 
33 int
34 main()
35 {
36 	struct sigaction sa;
37 	stack_t stack;
38 
39 	memset(&sa, 0, sizeof(sa));
40 	sa.sa_handler = inthandler;
41 	sa.sa_flags = SA_ONSTACK;
42 	assert(sigaction(SIGINT, &sa, NULL) == 0);
43 
44 	memset(&stack, 0, sizeof(stack));
45 	stack.ss_sp = buf;
46 	stack.ss_size = sizeof(buf);
47 	stack.ss_flags = 0;
48 	assert(sigaltstack(&stack, NULL) == 0);
49 
50 	assert(!isaltstack());
51 	sigsetjmp(jb, 1);
52 	assert(!isaltstack());
53 	if (!handled) {
54 		kill(getpid(), SIGINT);
55 		assert(0); /* Shouldn't reach here. */
56 	}
57 
58 	return (0);
59 }
60