blob: 0d11a809a072c306e6a59009bc55c3dbf4d23c95 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <errno.h>
2#include <signal.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <sys/select.h>
6#include <sys/wait.h>
7#include <stdlib.h>
8
9
10static volatile int handler_called;
11
12static void
13handler (int sig)
14{
15 handler_called = 1;
16}
17
18
19static int
20do_test (void)
21{
22 struct sigaction sa;
23 sa.sa_handler = handler;
24 sa.sa_flags = 0;
25 sigemptyset (&sa.sa_mask);
26
27 if (sigaction (SIGUSR1, &sa, NULL) != 0)
28 {
29 puts ("sigaction failed");
30 return 1;
31 }
32
33 sa.sa_handler = SIG_IGN;
34 if (sigaction (SIGCHLD, &sa, NULL) != 0)
35 {
36 puts ("2nd sigaction failed");
37 return 1;
38 }
39
40 sigset_t ss_usr1;
41 sigemptyset (&ss_usr1);
42 sigaddset (&ss_usr1, SIGUSR1);
43 if (sigprocmask (SIG_BLOCK, &ss_usr1, NULL) != 0)
44 {
45 puts ("sigprocmask failed");
46 return 1;
47 }
48
49 int fds[2][2];
50
51 if (pipe (fds[0]) != 0 || pipe (fds[1]) != 0)
52 {
53 puts ("pipe failed");
54 return 1;
55 }
56
57 fd_set rfds;
58 FD_ZERO (&rfds);
59
60 sigset_t ss;
61 sigprocmask (SIG_SETMASK, NULL, &ss);
62 sigdelset (&ss, SIGUSR1);
63
64 struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
65
66 pid_t parent = getpid ();
67 pid_t p = fork ();
68 if (p == 0)
69 {
70 close (fds[0][1]);
71 close (fds[1][0]);
72
73 FD_SET (fds[0][0], &rfds);
74
75 int e;
76 do
77 {
78 if (getppid () != parent)
79 exit (2);
80
81 errno = 0;
82 e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss);
83 }
84 while (e == 0);
85
86 if (e != -1)
87 {
88 puts ("child: pselect did not fail");
89 return 0;
90 }
91 if (errno != EINTR)
92 {
93 puts ("child: pselect did not set errno to EINTR");
94 return 0;
95 }
96
97 TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3));
98
99 exit (0);
100 }
101
102 close (fds[0][0]);
103 close (fds[1][1]);
104
105 FD_SET (fds[1][0], &rfds);
106
107 kill (p, SIGUSR1);
108
109 int e = pselect (fds[1][0] + 1, &rfds, NULL, NULL, NULL, &ss);
110 if (e == -1)
111 {
112 puts ("parent: pselect failed");
113 return 1;
114 }
115 if (e != 1)
116 {
117 puts ("parent: pselect did not report readable fd");
118 return 1;
119 }
120 if (!FD_ISSET (fds[1][0], &rfds))
121 {
122 puts ("parent: pselect reports wrong fd");
123 return 1;
124 }
125
126 return 0;
127}
128
129#define TEST_FUNCTION do_test ()
130#include "../test-skeleton.c"