I intend the following code to fork and exec "sleep 3" as a child while the parent process sleeps for 10s. I expect the parent process to receive SIGCHLD after 3s, when the "sleep 3" sompletes.
This does not happen, instead I get:
main
parent process
parent sleeping for 10s
child process
child start, command: /bin/sleep, args: 0x7fffc68c8000, env: 0x7fffc68c8020
ps -ef
shows a
chris 10578 10577 0 10:35 pts/25 00:00:00 /bin/sleep 3
followed by a:
chris 10578 10577 0 10:35 pts/25 00:00:00 [sleep] <defunct>
for the next seven seconds (at which point the parent process exits).
The issue is that clean_up_child_process
is never called.
What mistake have I made?
zombietest.c:
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
pid_t child_pid;
sig_atomic_t child_exit_status;
void clean_up_child_process (int signal_number) {
printf("signal received\n");
/* Clean up the child process. */
int status;
wait (&status);
/* Store its exit status in a global variable. */
child_exit_status = status;
printf("child_exit_status %i\n", status);
}
int main(int argc, char **argv) {
printf("main\n");
int pid = fork();
if (pid == 0) {
printf("child process\n");
signal(SIGCHLD, clean_up_child_process);
char *args[] = { "/bin/sleep", "3", NULL };
char *env[] = { NULL };
printf("child start, command: %s, args: %p, env: %p\n", args[0], args, env);
int ret = execve(args[0], args, env);
// if we get here, then the execve has failed
printf("exec of the child process failed %i\n", ret);
} else if (pid > 0) {
printf("parent process\n");
child_pid = pid;
} else {
perror("fork failed\n");
}
printf("parent sleeping for 10s\n");
sleep(10);
return 0;
}
You're telling the child to wait for a child process to finish, and then the child process is calling execve which doesn't create a child process, but instead replaces the current program with the one you're execing
You probably want the parent to intercept the child (i.e. have the signal
call before you execute the fork
call).