diff options
Diffstat (limited to 'test/unistd/fork.c')
-rw-r--r-- | test/unistd/fork.c | 58 |
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; } |