xref: /haiku/src/tests/system/libroot/posix/signal_test.cpp (revision 4466b89c65970de4c7236ac87faa2bee4589f413)
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