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