1 /* 2 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <errno.h> 8 #include <signal.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <unistd.h> 13 14 15 #if defined(__BEOS__) && !defined(__HAIKU__) 16 typedef void (*sighandler_t)(int); 17 # define SIGSTKSZ 16384 18 # define SA_ONESHOT 0 19 # define SA_ONSTACK 0 20 # define SA_RESTART 0 21 # define ualarm(usec, interval) alarm(1) 22 #endif 23 24 const void* kUserDataMagic = (void *)0x12345678; 25 26 static char sAlternateStack[SIGSTKSZ]; 27 28 29 bool 30 is_alternate(void* pointer) 31 { 32 return (char*)pointer > &sAlternateStack[0] 33 && (char*)pointer <= &sAlternateStack[0] + SIGSTKSZ; 34 } 35 36 37 void 38 sigHandler(int signal, void *userData, vregs *regs) 39 { 40 #if defined(__BEOS__) || defined(__HAIKU__) 41 if (userData != kUserDataMagic) 42 fprintf(stderr, "FAILED: user data not correct: %p\n", userData); 43 #endif 44 45 printf("signal handler called with signal %i on %s stack\n", 46 signal, is_alternate(&signal) ? "alternate" : "standard"); 47 } 48 49 50 void 51 wait_for_key() 52 { 53 char buffer[100]; 54 if (fgets(buffer, sizeof(buffer), stdin) == NULL 55 || buffer[0] == 'q') { 56 if (errno == EINTR) 57 puts("interrupted"); 58 else 59 exit(0); 60 } 61 } 62 63 int 64 main() 65 { 66 puts("-- 1 (should block) --"); 67 68 struct sigaction newAction; 69 newAction.sa_handler = (sighandler_t)sigHandler; 70 newAction.sa_mask = 0; 71 newAction.sa_flags = SA_ONESHOT | SA_ONSTACK | SA_RESTART; 72 #if defined(__BEOS__) || defined(__HAIKU__) 73 newAction.sa_userdata = (void*)kUserDataMagic; 74 #endif 75 sigaction(SIGALRM, &newAction, NULL); 76 77 ualarm(10000, 0); 78 wait_for_key(); 79 80 puts("-- 2 (does not block, should call handler twice) --"); 81 82 newAction.sa_flags = 0; 83 sigaction(SIGALRM, &newAction, NULL); 84 85 ualarm(0, 50000); 86 wait_for_key(); 87 wait_for_key(); 88 89 ualarm(0, 0); 90 91 puts("-- 3 (alternate stack, should block) --"); 92 93 #if defined(__BEOS__) && !defined(__HAIKU__) 94 set_signal_stack(sAlternateStack, SIGSTKSZ); 95 #else 96 stack_t newStack; 97 newStack.ss_sp = sAlternateStack; 98 newStack.ss_size = SIGSTKSZ; 99 newStack.ss_flags = 0; 100 if (sigaltstack(&newStack, NULL) != 0) 101 fprintf(stderr, "sigaltstack() failed: %s\n", strerror(errno)); 102 #endif 103 104 newAction.sa_flags = SA_RESTART | SA_ONSTACK; 105 sigaction(SIGALRM, &newAction, NULL); 106 107 ualarm(10000, 0); 108 wait_for_key(); 109 110 puts("-- end --"); 111 return 0; 112 } 113