Ticket #15193: pselect-test.c

File pselect-test.c, 1.6 KB (added by simonsouth, 5 years ago)

Sample program demonstrating pselect()'s incorrect behaviour

Line 
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
10void
11sigchld_handler(int signum)
12{
13 puts("SIGCHLD received");
14}
15
16int
17main(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}