1 /*	$OpenBSD: sigaltstack_fork.c,v 1.2 2011/11/26 04:11:34 guenther Exp $	*/
2 
3 /*
4  * Public domain.  2011, Joshua Elsasser
5  *
6  * Test if child processes inherit an alternate signal stack.
7  */
8 
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 
12 #include <err.h>
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 
18 void
19 check_stack(void *buf, const char *label)
20 {
21 	struct sigaltstack ss;
22 
23 	bzero(&ss, sizeof(ss));
24 	if (sigaltstack(NULL, &ss) != 0)
25 		err(1, "failed to get sigaltstack in %s", label);
26 	if (ss.ss_sp != buf ||
27 	    ss.ss_size != SIGSTKSZ ||
28 	    ss.ss_flags != 0)
29 		errx(1, "bad sigaltstack value in %s: "
30 		    "buf=%p ss_sp=%p ss_size=%zu ss_flags=0x%x",
31 		    label, buf, ss.ss_sp, ss.ss_size, ss.ss_flags);
32 }
33 
34 int
35 main(int argc, char *argv[])
36 {
37 	struct sigaltstack ss;
38 	int status;
39 	pid_t kid;
40 	void *buf;
41 
42 	if ((buf = malloc(SIGSTKSZ)) == NULL)
43 		err(1, "malloc failed");
44 
45 	bzero(&ss, sizeof(ss));
46 	ss.ss_sp = buf;
47 	ss.ss_size = SIGSTKSZ;
48 	if (sigaltstack(&ss, NULL) != 0)
49 		err(1, "failed to set sigaltstack");
50 
51 	check_stack(buf, "parent");
52 
53 	if ((kid = fork()) == -1)
54 		err(1, "fork failed");
55 
56 	if (kid == 0) {
57 		check_stack(buf, "child");
58 		_exit(0);
59 	}
60 
61 	if (waitpid(kid, &status, 0) != kid)
62 		err(1, "waitpid failed");
63 	if (!WIFEXITED(status))
64 		errx(1, "child did not exit normally");
65 
66 	return (WEXITSTATUS(status));
67 }
68