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