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