]>
Commit | Line | Data |
---|---|---|
43300667 | 1 | /* Tests for waitid. |
04277e02 | 2 | Copyright (C) 2004-2019 Free Software Foundation, Inc. |
43300667 RM |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
43300667 RM |
18 | |
19 | #include <errno.h> | |
bb677c95 | 20 | #include <stdio.h> |
43300667 RM |
21 | #include <stdlib.h> |
22 | #include <unistd.h> | |
23 | #include <sys/wait.h> | |
24 | #include <signal.h> | |
25 | ||
43300667 RM |
26 | static void |
27 | test_child (void) | |
28 | { | |
f9e1a251 RM |
29 | /* Wait a second to be sure the parent set his variables before we |
30 | produce a SIGCHLD. */ | |
31 | sleep (1); | |
32 | ||
43300667 RM |
33 | /* First thing, we stop ourselves. */ |
34 | raise (SIGSTOP); | |
35 | ||
36 | /* Hey, we got continued! */ | |
37 | while (1) | |
38 | pause (); | |
39 | } | |
40 | ||
41 | #ifndef WEXITED | |
42 | # define WEXITED 0 | |
43 | # define WCONTINUED 0 | |
44 | # define WSTOPPED WUNTRACED | |
45 | #endif | |
46 | ||
f9e1a251 RM |
47 | static sig_atomic_t expecting_sigchld, spurious_sigchld; |
48 | #ifdef SA_SIGINFO | |
49 | static siginfo_t sigchld_info; | |
50 | ||
51 | static void | |
52 | sigchld (int signo, siginfo_t *info, void *ctx) | |
53 | { | |
54 | if (signo != SIGCHLD) | |
55 | { | |
bb677c95 | 56 | printf ("SIGCHLD handler got signal %d instead!\n", signo); |
f9e1a251 RM |
57 | _exit (EXIT_FAILURE); |
58 | } | |
59 | ||
60 | if (! expecting_sigchld) | |
61 | { | |
62 | spurious_sigchld = 1; | |
bb677c95 UD |
63 | printf ("spurious SIGCHLD: signo %d code %d status %d pid %d\n", |
64 | info->si_signo, info->si_code, info->si_status, info->si_pid); | |
f9e1a251 RM |
65 | } |
66 | else | |
67 | { | |
68 | sigchld_info = *info; | |
69 | expecting_sigchld = 0; | |
70 | } | |
71 | } | |
72 | ||
73 | static void | |
74 | check_sigchld (const char *phase, int *ok, int code, int status, pid_t pid) | |
75 | { | |
76 | if (expecting_sigchld) | |
77 | { | |
bb677c95 | 78 | printf ("missing SIGCHLD on %s\n", phase); |
f9e1a251 RM |
79 | *ok = EXIT_FAILURE; |
80 | expecting_sigchld = 0; | |
81 | return; | |
82 | } | |
83 | ||
84 | if (sigchld_info.si_signo != SIGCHLD) | |
85 | { | |
bb677c95 | 86 | printf ("SIGCHLD for %s signal %d\n", phase, sigchld_info.si_signo); |
f9e1a251 RM |
87 | *ok = EXIT_FAILURE; |
88 | } | |
89 | if (sigchld_info.si_code != code) | |
90 | { | |
bb677c95 | 91 | printf ("SIGCHLD for %s code %d\n", phase, sigchld_info.si_code); |
f9e1a251 RM |
92 | *ok = EXIT_FAILURE; |
93 | } | |
94 | if (sigchld_info.si_status != status) | |
95 | { | |
bb677c95 | 96 | printf ("SIGCHLD for %s status %d\n", phase, sigchld_info.si_status); |
f9e1a251 RM |
97 | *ok = EXIT_FAILURE; |
98 | } | |
99 | if (sigchld_info.si_pid != pid) | |
100 | { | |
bb677c95 | 101 | printf ("SIGCHLD for %s pid %d\n", phase, sigchld_info.si_pid); |
f9e1a251 RM |
102 | *ok = EXIT_FAILURE; |
103 | } | |
104 | } | |
105 | # define CHECK_SIGCHLD(phase, code_check, status_check) \ | |
106 | check_sigchld ((phase), &status, (code_check), (status_check), pid) | |
107 | #else | |
108 | # define CHECK_SIGCHLD(phase, code, status) ((void) 0) | |
109 | #endif | |
110 | ||
43300667 RM |
111 | static int |
112 | do_test (int argc, char *argv[]) | |
113 | { | |
f9e1a251 RM |
114 | #ifdef SA_SIGINFO |
115 | struct sigaction sa; | |
116 | sa.sa_flags = SA_SIGINFO|SA_RESTART; | |
117 | sa.sa_sigaction = &sigchld; | |
118 | if (sigemptyset (&sa.sa_mask) < 0 || sigaction (SIGCHLD, &sa, NULL) < 0) | |
119 | { | |
bb677c95 | 120 | printf ("setting SIGCHLD handler: %m\n"); |
f9e1a251 RM |
121 | return EXIT_FAILURE; |
122 | } | |
123 | #endif | |
124 | ||
125 | expecting_sigchld = 1; | |
126 | ||
43300667 RM |
127 | pid_t pid = fork (); |
128 | if (pid < 0) | |
129 | { | |
bb677c95 | 130 | printf ("fork: %m\n"); |
43300667 RM |
131 | return EXIT_FAILURE; |
132 | } | |
133 | else if (pid == 0) | |
134 | { | |
135 | test_child (); | |
136 | _exit (127); | |
137 | } | |
138 | ||
44219bd9 | 139 | int status = EXIT_SUCCESS; |
f9e1a251 RM |
140 | #define RETURN(ok) \ |
141 | do { if (status == EXIT_SUCCESS) status = (ok); goto out; } while (0) | |
44219bd9 | 142 | |
43300667 | 143 | /* Give the child a chance to stop. */ |
f9e1a251 RM |
144 | sleep (3); |
145 | ||
a58ad3f8 | 146 | CHECK_SIGCHLD ("stopped (before waitid)", CLD_STOPPED, SIGSTOP); |
43300667 RM |
147 | |
148 | /* Now try a wait that should not succeed. */ | |
149 | siginfo_t info; | |
150 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ | |
151 | int fail = waitid (P_PID, pid, &info, WEXITED|WCONTINUED|WNOHANG); | |
152 | switch (fail) | |
153 | { | |
154 | default: | |
bb677c95 | 155 | printf ("waitid returned bogus value %d\n", fail); |
44219bd9 | 156 | RETURN (EXIT_FAILURE); |
43300667 | 157 | case -1: |
bb677c95 | 158 | printf ("waitid WNOHANG on stopped: %m\n"); |
44219bd9 | 159 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
43300667 RM |
160 | case 0: |
161 | if (info.si_signo == 0) | |
162 | break; | |
163 | if (info.si_signo == SIGCHLD) | |
bb677c95 | 164 | printf ("waitid WNOHANG on stopped status %d\n", info.si_status); |
43300667 | 165 | else |
bb677c95 | 166 | printf ("waitid WNOHANG on stopped signal %d\n", info.si_signo); |
44219bd9 | 167 | RETURN (EXIT_FAILURE); |
43300667 RM |
168 | } |
169 | ||
170 | /* Next the wait that should succeed right away. */ | |
171 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ | |
172 | info.si_pid = -1; | |
173 | info.si_status = -1; | |
174 | fail = waitid (P_PID, pid, &info, WSTOPPED|WNOHANG); | |
175 | switch (fail) | |
176 | { | |
177 | default: | |
bb677c95 | 178 | printf ("waitid WSTOPPED|WNOHANG returned bogus value %d\n", fail); |
44219bd9 | 179 | RETURN (EXIT_FAILURE); |
43300667 | 180 | case -1: |
bb677c95 | 181 | printf ("waitid WSTOPPED|WNOHANG on stopped: %m\n"); |
44219bd9 | 182 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
43300667 RM |
183 | case 0: |
184 | if (info.si_signo != SIGCHLD) | |
185 | { | |
bb677c95 UD |
186 | printf ("waitid WSTOPPED|WNOHANG on stopped signal %d\n", |
187 | info.si_signo); | |
44219bd9 | 188 | RETURN (EXIT_FAILURE); |
43300667 RM |
189 | } |
190 | if (info.si_code != CLD_STOPPED) | |
191 | { | |
bb677c95 UD |
192 | printf ("waitid WSTOPPED|WNOHANG on stopped code %d\n", |
193 | info.si_code); | |
44219bd9 | 194 | RETURN (EXIT_FAILURE); |
43300667 RM |
195 | } |
196 | if (info.si_status != SIGSTOP) | |
197 | { | |
bb677c95 UD |
198 | printf ("waitid WSTOPPED|WNOHANG on stopped status %d\n", |
199 | info.si_status); | |
44219bd9 | 200 | RETURN (EXIT_FAILURE); |
43300667 RM |
201 | } |
202 | if (info.si_pid != pid) | |
203 | { | |
bb677c95 UD |
204 | printf ("waitid WSTOPPED|WNOHANG on stopped pid %d != %d\n", |
205 | info.si_pid, pid); | |
44219bd9 | 206 | RETURN (EXIT_FAILURE); |
43300667 RM |
207 | } |
208 | } | |
209 | ||
f9e1a251 RM |
210 | expecting_sigchld = WCONTINUED != 0; |
211 | ||
43300667 RM |
212 | if (kill (pid, SIGCONT) != 0) |
213 | { | |
bb677c95 | 214 | printf ("kill (%d, SIGCONT): %m\n", pid); |
44219bd9 | 215 | RETURN (EXIT_FAILURE); |
43300667 RM |
216 | } |
217 | ||
218 | /* Wait for the child to have continued. */ | |
219 | sleep (2); | |
220 | ||
44219bd9 | 221 | #if WCONTINUED != 0 |
f9e1a251 RM |
222 | if (expecting_sigchld) |
223 | { | |
bb677c95 | 224 | printf ("no SIGCHLD seen for SIGCONT (optional)\n"); |
f9e1a251 RM |
225 | expecting_sigchld = 0; |
226 | } | |
227 | else | |
a58ad3f8 | 228 | CHECK_SIGCHLD ("continued (before waitid)", CLD_CONTINUED, SIGCONT); |
f9e1a251 RM |
229 | |
230 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ | |
231 | info.si_pid = -1; | |
232 | info.si_status = -1; | |
233 | fail = waitid (P_PID, pid, &info, WCONTINUED|WNOWAIT); | |
234 | switch (fail) | |
235 | { | |
236 | default: | |
bb677c95 | 237 | printf ("waitid WCONTINUED|WNOWAIT returned bogus value %d\n", fail); |
f9e1a251 RM |
238 | RETURN (EXIT_FAILURE); |
239 | case -1: | |
bb677c95 | 240 | printf ("waitid WCONTINUED|WNOWAIT on continued: %m\n"); |
f9e1a251 RM |
241 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
242 | case 0: | |
243 | if (info.si_signo != SIGCHLD) | |
244 | { | |
bb677c95 UD |
245 | printf ("waitid WCONTINUED|WNOWAIT on continued signal %d\n", |
246 | info.si_signo); | |
f9e1a251 RM |
247 | RETURN (EXIT_FAILURE); |
248 | } | |
249 | if (info.si_code != CLD_CONTINUED) | |
250 | { | |
bb677c95 UD |
251 | printf ("waitid WCONTINUED|WNOWAIT on continued code %d\n", |
252 | info.si_code); | |
f9e1a251 RM |
253 | RETURN (EXIT_FAILURE); |
254 | } | |
255 | if (info.si_status != SIGCONT) | |
256 | { | |
bb677c95 UD |
257 | printf ("waitid WCONTINUED|WNOWAIT on continued status %d\n", |
258 | info.si_status); | |
f9e1a251 RM |
259 | RETURN (EXIT_FAILURE); |
260 | } | |
261 | if (info.si_pid != pid) | |
262 | { | |
bb677c95 UD |
263 | printf ("waitid WCONTINUED|WNOWAIT on continued pid %d != %d\n", |
264 | info.si_pid, pid); | |
f9e1a251 RM |
265 | RETURN (EXIT_FAILURE); |
266 | } | |
267 | } | |
268 | ||
269 | /* That should leave the CLD_CONTINUED state waiting to be seen again. */ | |
43300667 RM |
270 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ |
271 | info.si_pid = -1; | |
272 | info.si_status = -1; | |
273 | fail = waitid (P_PID, pid, &info, WCONTINUED); | |
274 | switch (fail) | |
275 | { | |
276 | default: | |
bb677c95 | 277 | printf ("waitid WCONTINUED returned bogus value %d\n", fail); |
44219bd9 | 278 | RETURN (EXIT_FAILURE); |
43300667 | 279 | case -1: |
bb677c95 | 280 | printf ("waitid WCONTINUED on continued: %m\n"); |
44219bd9 | 281 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
43300667 RM |
282 | case 0: |
283 | if (info.si_signo != SIGCHLD) | |
284 | { | |
bb677c95 | 285 | printf ("waitid WCONTINUED on continued signal %d\n", info.si_signo); |
44219bd9 | 286 | RETURN (EXIT_FAILURE); |
43300667 RM |
287 | } |
288 | if (info.si_code != CLD_CONTINUED) | |
289 | { | |
bb677c95 | 290 | printf ("waitid WCONTINUED on continued code %d\n", info.si_code); |
44219bd9 | 291 | RETURN (EXIT_FAILURE); |
43300667 RM |
292 | } |
293 | if (info.si_status != SIGCONT) | |
294 | { | |
bb677c95 UD |
295 | printf ("waitid WCONTINUED on continued status %d\n", |
296 | info.si_status); | |
44219bd9 | 297 | RETURN (EXIT_FAILURE); |
43300667 RM |
298 | } |
299 | if (info.si_pid != pid) | |
300 | { | |
bb677c95 UD |
301 | printf ("waitid WCONTINUED on continued pid %d != %d\n", |
302 | info.si_pid, pid); | |
44219bd9 | 303 | RETURN (EXIT_FAILURE); |
43300667 RM |
304 | } |
305 | } | |
f9e1a251 RM |
306 | |
307 | /* Now try a wait that should not succeed. */ | |
308 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ | |
309 | fail = waitid (P_PID, pid, &info, WCONTINUED|WNOHANG); | |
310 | switch (fail) | |
311 | { | |
312 | default: | |
bb677c95 | 313 | printf ("waitid returned bogus value %d\n", fail); |
f9e1a251 RM |
314 | RETURN (EXIT_FAILURE); |
315 | case -1: | |
bb677c95 | 316 | printf ("waitid WCONTINUED|WNOHANG on waited continued: %m\n"); |
f9e1a251 RM |
317 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
318 | case 0: | |
319 | if (info.si_signo == 0) | |
320 | break; | |
321 | if (info.si_signo == SIGCHLD) | |
bb677c95 UD |
322 | printf ("waitid WCONTINUED|WNOHANG on waited continued status %d\n", |
323 | info.si_status); | |
f9e1a251 | 324 | else |
bb677c95 UD |
325 | printf ("waitid WCONTINUED|WNOHANG on waited continued signal %d\n", |
326 | info.si_signo); | |
f9e1a251 RM |
327 | RETURN (EXIT_FAILURE); |
328 | } | |
a044c713 RM |
329 | |
330 | /* Now stop him again and test waitpid with WCONTINUED. */ | |
331 | expecting_sigchld = 1; | |
332 | if (kill (pid, SIGSTOP) != 0) | |
333 | { | |
bb677c95 | 334 | printf ("kill (%d, SIGSTOP): %m\n", pid); |
a044c713 RM |
335 | RETURN (EXIT_FAILURE); |
336 | } | |
a58ad3f8 RM |
337 | |
338 | /* Give the child a chance to stop. The waitpid call below will block | |
339 | until it has stopped, but if we are real quick and enter the waitpid | |
340 | system call before the SIGCHLD has been generated, then it will be | |
341 | discarded and never delivered. */ | |
342 | sleep (3); | |
343 | ||
a044c713 RM |
344 | pid_t wpid = waitpid (pid, &fail, WUNTRACED); |
345 | if (wpid < 0) | |
346 | { | |
bb677c95 | 347 | printf ("waitpid WUNTRACED on stopped: %m\n"); |
a044c713 RM |
348 | RETURN (EXIT_FAILURE); |
349 | } | |
350 | else if (wpid != pid) | |
351 | { | |
bb677c95 UD |
352 | printf ("waitpid WUNTRACED on stopped returned %d != %d (status %x)\n", |
353 | wpid, pid, fail); | |
a044c713 RM |
354 | RETURN (EXIT_FAILURE); |
355 | } | |
356 | else if (!WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail) | |
357 | || WIFCONTINUED (fail) || WSTOPSIG (fail) != SIGSTOP) | |
358 | { | |
bb677c95 | 359 | printf ("waitpid WUNTRACED on stopped: status %x\n", fail); |
a044c713 RM |
360 | RETURN (EXIT_FAILURE); |
361 | } | |
a58ad3f8 | 362 | CHECK_SIGCHLD ("stopped (after waitpid)", CLD_STOPPED, SIGSTOP); |
a044c713 RM |
363 | |
364 | expecting_sigchld = 1; | |
365 | if (kill (pid, SIGCONT) != 0) | |
366 | { | |
bb677c95 | 367 | printf ("kill (%d, SIGCONT): %m\n", pid); |
a044c713 RM |
368 | RETURN (EXIT_FAILURE); |
369 | } | |
370 | ||
371 | /* Wait for the child to have continued. */ | |
372 | sleep (2); | |
373 | ||
374 | if (expecting_sigchld) | |
375 | { | |
bb677c95 | 376 | printf ("no SIGCHLD seen for SIGCONT (optional)\n"); |
a044c713 RM |
377 | expecting_sigchld = 0; |
378 | } | |
379 | else | |
a58ad3f8 | 380 | CHECK_SIGCHLD ("continued (before waitpid)", CLD_CONTINUED, SIGCONT); |
a044c713 RM |
381 | |
382 | wpid = waitpid (pid, &fail, WCONTINUED); | |
383 | if (wpid < 0) | |
384 | { | |
385 | if (errno == EINVAL) | |
bb677c95 | 386 | printf ("waitpid does not support WCONTINUED\n"); |
a044c713 RM |
387 | else |
388 | { | |
bb677c95 | 389 | printf ("waitpid WCONTINUED on continued: %m\n"); |
a044c713 RM |
390 | RETURN (EXIT_FAILURE); |
391 | } | |
392 | } | |
393 | else if (wpid != pid) | |
394 | { | |
bb677c95 UD |
395 | printf ("\ |
396 | waitpid WCONTINUED on continued returned %d != %d (status %x)\n", | |
a044c713 RM |
397 | wpid, pid, fail); |
398 | RETURN (EXIT_FAILURE); | |
399 | } | |
400 | else if (WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail) | |
401 | || !WIFCONTINUED (fail)) | |
402 | { | |
bb677c95 | 403 | printf ("waitpid WCONTINUED on continued: status %x\n", fail); |
a044c713 RM |
404 | RETURN (EXIT_FAILURE); |
405 | } | |
43300667 RM |
406 | #endif |
407 | ||
f9e1a251 RM |
408 | expecting_sigchld = 1; |
409 | ||
43300667 RM |
410 | /* Die, child, die! */ |
411 | if (kill (pid, SIGKILL) != 0) | |
412 | { | |
bb677c95 | 413 | printf ("kill (%d, SIGKILL): %m\n", pid); |
44219bd9 | 414 | RETURN (EXIT_FAILURE); |
43300667 RM |
415 | } |
416 | ||
417 | #ifdef WNOWAIT | |
418 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ | |
419 | info.si_pid = -1; | |
420 | info.si_status = -1; | |
421 | fail = waitid (P_PID, pid, &info, WEXITED|WNOWAIT); | |
422 | switch (fail) | |
423 | { | |
424 | default: | |
bb677c95 | 425 | printf ("waitid WNOWAIT returned bogus value %d\n", fail); |
44219bd9 | 426 | RETURN (EXIT_FAILURE); |
43300667 | 427 | case -1: |
bb677c95 | 428 | printf ("waitid WNOWAIT on killed: %m\n"); |
44219bd9 | 429 | RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE); |
43300667 RM |
430 | case 0: |
431 | if (info.si_signo != SIGCHLD) | |
432 | { | |
bb677c95 | 433 | printf ("waitid WNOWAIT on killed signal %d\n", info.si_signo); |
44219bd9 | 434 | RETURN (EXIT_FAILURE); |
43300667 RM |
435 | } |
436 | if (info.si_code != CLD_KILLED) | |
437 | { | |
bb677c95 | 438 | printf ("waitid WNOWAIT on killed code %d\n", info.si_code); |
44219bd9 | 439 | RETURN (EXIT_FAILURE); |
43300667 RM |
440 | } |
441 | if (info.si_status != SIGKILL) | |
442 | { | |
bb677c95 | 443 | printf ("waitid WNOWAIT on killed status %d\n", info.si_status); |
44219bd9 | 444 | RETURN (EXIT_FAILURE); |
43300667 RM |
445 | } |
446 | if (info.si_pid != pid) | |
447 | { | |
bb677c95 | 448 | printf ("waitid WNOWAIT on killed pid %d != %d\n", info.si_pid, pid); |
44219bd9 | 449 | RETURN (EXIT_FAILURE); |
43300667 RM |
450 | } |
451 | } | |
452 | #else | |
453 | /* Allow enough time to be sure the child died; we didn't synchronize. */ | |
454 | sleep (2); | |
455 | #endif | |
456 | ||
f9e1a251 RM |
457 | CHECK_SIGCHLD ("killed", CLD_KILLED, SIGKILL); |
458 | ||
43300667 RM |
459 | info.si_signo = 0; /* A successful call sets it to SIGCHLD. */ |
460 | info.si_pid = -1; | |
461 | info.si_status = -1; | |
462 | fail = waitid (P_PID, pid, &info, WEXITED|WNOHANG); | |
463 | switch (fail) | |
464 | { | |
465 | default: | |
bb677c95 | 466 | printf ("waitid WNOHANG returned bogus value %d\n", fail); |
44219bd9 | 467 | RETURN (EXIT_FAILURE); |
43300667 | 468 | case -1: |
bb677c95 | 469 | printf ("waitid WNOHANG on killed: %m\n"); |
44219bd9 | 470 | RETURN (EXIT_FAILURE); |
43300667 RM |
471 | case 0: |
472 | if (info.si_signo != SIGCHLD) | |
473 | { | |
bb677c95 | 474 | printf ("waitid WNOHANG on killed signal %d\n", info.si_signo); |
44219bd9 | 475 | RETURN (EXIT_FAILURE); |
43300667 RM |
476 | } |
477 | if (info.si_code != CLD_KILLED) | |
478 | { | |
bb677c95 | 479 | printf ("waitid WNOHANG on killed code %d\n", info.si_code); |
44219bd9 | 480 | RETURN (EXIT_FAILURE); |
43300667 RM |
481 | } |
482 | if (info.si_status != SIGKILL) | |
483 | { | |
bb677c95 | 484 | printf ("waitid WNOHANG on killed status %d\n", info.si_status); |
44219bd9 | 485 | RETURN (EXIT_FAILURE); |
43300667 RM |
486 | } |
487 | if (info.si_pid != pid) | |
488 | { | |
bb677c95 | 489 | printf ("waitid WNOHANG on killed pid %d != %d\n", info.si_pid, pid); |
44219bd9 | 490 | RETURN (EXIT_FAILURE); |
43300667 RM |
491 | } |
492 | } | |
493 | ||
494 | fail = waitid (P_PID, pid, &info, WEXITED); | |
495 | if (fail == -1) | |
496 | { | |
497 | if (errno != ECHILD) | |
498 | { | |
bb677c95 | 499 | printf ("waitid WEXITED on killed: %m\n"); |
44219bd9 | 500 | RETURN (EXIT_FAILURE); |
43300667 RM |
501 | } |
502 | } | |
503 | else | |
504 | { | |
bb677c95 | 505 | printf ("waitid WEXITED returned bogus value %d\n", fail); |
44219bd9 | 506 | RETURN (EXIT_FAILURE); |
43300667 RM |
507 | } |
508 | ||
44219bd9 RM |
509 | #undef RETURN |
510 | out: | |
f9e1a251 RM |
511 | if (spurious_sigchld) |
512 | status = EXIT_FAILURE; | |
47544448 | 513 | signal (SIGCHLD, SIG_IGN); |
44219bd9 RM |
514 | kill (pid, SIGKILL); /* Make sure it's dead if we bailed early. */ |
515 | return status; | |
43300667 RM |
516 | } |
517 | ||
518 | #include "../test-skeleton.c" |