1 /* $OpenBSD: sigsuspend.c,v 1.2 2010/06/20 17:57:09 phessler Exp $ */
3 * Written by Artur Grabowski <art@openbsd.org> 2005, Public domain.
11 #include <sys/types.h>
18 usr1handler(int signo)
24 usr2handler(int signo)
39 memset(&sa, 0, sizeof(sa));
40 sigemptyset(&sa.sa_mask);
41 sa.sa_handler = usr1handler;
42 if (sigaction(SIGUSR1, &sa, NULL))
43 err(1, "sigaction(USR1)");
45 sa.sa_handler = usr2handler;
46 if (sigaction(SIGUSR2, &sa, NULL))
47 err(1, "sigaction(USR2)");
50 * Set the procmask to mask the early USR1 the child will send us.
53 sigaddset(&set, SIGUSR1);
54 sigaddset(&set, SIGUSR2);
55 if (sigprocmask(SIG_BLOCK, &set, &oset))
56 err(1, "sigprocmask");
58 switch((pid = fork())) {
64 kill(ppid, SIGUSR1); /* Tell the parent we're ready. */
67 sigaddset(&set, SIGUSR2);
71 * Check that sigsuspend didn't change the signal mask.
73 if (sigprocmask(SIG_SETMASK, NULL, &oset))
74 err(1, "sigprocmask");
75 if (!sigismember(&oset, SIGUSR1) ||
76 !sigismember(&oset, SIGUSR2))
77 errx(1, "sigprocmask is bad");
79 /* Check that we got the sigusr1 that we expected. */
81 errx(1, "didn't get usr1");
83 errx(1, "got incorrect usr2");
86 sigaddset(&set, SIGUSR1);
90 errx(1, "didn't get usr2");
98 * Waiting for the initial USR1 that tells us the child
105 * Check that sigsuspend didn't change the signal mask.
107 if (sigprocmask(SIG_SETMASK, NULL, &oset))
108 err(1, "sigprocmask");
109 if (!sigismember(&oset, SIGUSR1) ||
110 !sigismember(&oset, SIGUSR2))
111 errx(1, "sigprocmask is bad");
114 * Deliberately send USR2 first to confuse.
119 if (waitpid(pid, &status, 0) != pid)
122 if (WIFEXITED(status))
123 exit(WEXITSTATUS(status));