1 | #include <errno.h>
|
---|
2 | #include <signal.h>
|
---|
3 | #include <stdio.h>
|
---|
4 | #include <string.h>
|
---|
5 | #include <unistd.h>
|
---|
6 |
|
---|
7 | #include <sys/select.h>
|
---|
8 |
|
---|
9 |
|
---|
10 | void
|
---|
11 | sigchld_handler(int signum)
|
---|
12 | {
|
---|
13 | puts("SIGCHLD received");
|
---|
14 | }
|
---|
15 |
|
---|
16 | int
|
---|
17 | main(int argc, char **argv)
|
---|
18 | {
|
---|
19 | sigset_t sigchld_sigset, empty_sigset;
|
---|
20 | struct sigaction sigchld_action;
|
---|
21 | fd_set readfds;
|
---|
22 | int psignal_result, psignal_err;
|
---|
23 |
|
---|
24 |
|
---|
25 | /* Install a handler for SIGCHLD (so it isn't ignored) */
|
---|
26 | memset(&sigchld_action, 0, sizeof(sigchld_action));
|
---|
27 | sigchld_action.sa_handler = sigchld_handler;
|
---|
28 | if (sigaction(SIGCHLD, &sigchld_action, NULL) != 0) {
|
---|
29 | fprintf(stderr, "Error setting SIGCHLD handler: %s\n", strerror(errno));
|
---|
30 | return -1;
|
---|
31 | }
|
---|
32 |
|
---|
33 | /* Temporarily block SIGCHLD signals */
|
---|
34 | sigemptyset(&sigchld_sigset);
|
---|
35 | sigaddset(&sigchld_sigset, SIGCHLD);
|
---|
36 | if (sigprocmask(SIG_BLOCK, &sigchld_sigset, NULL) != 0) {
|
---|
37 | fprintf(stderr, "Failed to block SIGCHLD: %s\n", strerror(errno));
|
---|
38 | return -1;
|
---|
39 | }
|
---|
40 |
|
---|
41 | /* Spawn a child process, which will send us the SIGCHLD signal when it
|
---|
42 | exits---as we've blocked SIGCHLD this signal will be pending until the
|
---|
43 | pselect() call below */
|
---|
44 | if (fork() == 0) {
|
---|
45 | puts("Child process is exiting");
|
---|
46 | return 0;
|
---|
47 | }
|
---|
48 |
|
---|
49 | /* Block on reading from STDIN, until the SIGCHLD signal interrupts us */
|
---|
50 | FD_ZERO(&readfds);
|
---|
51 | FD_SET(0, &readfds);
|
---|
52 |
|
---|
53 | /* Unblock all signals during pselect()'s execution */
|
---|
54 | sigemptyset(&empty_sigset);
|
---|
55 |
|
---|
56 | puts("Waiting for Enter or signal...");
|
---|
57 | psignal_result = pselect(1, &readfds, NULL, NULL, NULL, &empty_sigset);
|
---|
58 | psignal_err = errno;
|
---|
59 |
|
---|
60 | printf("pselect() returned %d: %s (%d)\n", psignal_result,
|
---|
61 | strerror(psignal_err), psignal_err);
|
---|
62 |
|
---|
63 | return 0;
|
---|
64 | }
|
---|