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