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
isaltstack()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
inthandler(int signo)26 inthandler(int signo)
27 {
28 assert(isaltstack());
29 handled = 1;
30 siglongjmp(jb, 1);
31 }
32
33 int
main()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