summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/unistd/fork.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/test/unistd/fork.c b/test/unistd/fork.c
index 70e9db8f9..8cd5a7803 100644
--- a/test/unistd/fork.c
+++ b/test/unistd/fork.c
@@ -26,29 +26,61 @@
#include <unistd.h>
#include <sys/wait.h>
+#define GOT1 (1 << 1)
+#define GOT2 (1 << 2)
+#define GOT3 (1 << 3)
+
+void child_handler(int sig)
+{
+ fprintf(stderr, "I got a SIGCHLD\n");
+}
+
int main(void)
{
- pid_t pid;
- int status, wpid;
+ pid_t pid1, pid2, pid3;
+ int status, result, wpid;
+
+ signal(SIGCHLD, child_handler);
- if ((pid = fork()) == 0) {
- printf("The child process sleeps 5 seconds...\n");
- sleep(5);
- printf("Child exiting.\n");
+ if ((pid1 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 2 seconds...\n");
+ sleep(4);
+ fprintf(stderr, "Child exiting.\n");
+ exit(-1);
+ }
+ if ((pid2 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 3 seconds...\n");
+ sleep(3);
+ fprintf(stderr, "Child exiting.\n");
+ exit(-1);
+ }
+ if ((pid3 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 4 seconds...\n");
+ sleep(2);
+ fprintf(stderr, "Child exiting.\n");
exit(-1);
}
- printf("Parent: waiting for the child to die.\n");
+ fprintf(stderr, "Parent: waiting for the child to die.\n");
+ status = 0;
while (1) {
- wpid = wait(&status);
- if (wpid > 0 && wpid != pid) {
- continue;
- }
- if (wpid == pid)
+ wpid = waitpid(pid1, &result, WNOHANG);
+ if (wpid == pid1)
+ status |= GOT1;
+
+ wpid = waitpid(pid2, &result, WNOHANG);
+ if (wpid == pid2)
+ status |= GOT2;
+
+ wpid = waitpid(pid3, &result, WNOHANG);
+ if (wpid == pid3)
+ status |= GOT3;
+
+ if (status == (GOT1 | GOT2 | GOT3))
break;
}
- printf("Child process exited.\nGoodbye.\n");
+ fprintf(stderr, "Child process exited.\nGoodbye.\n");
return EXIT_SUCCESS;
}