Krish Krish - 4 months ago 30
Linux Question

In C++, fork and kill not killing all the child processes

I have below code which executes a binary in child process, wait for 1 sec and if it's not done then kill it.

pid_t pid;
pid=fork();
if (pid == 0)
{
//In child
execl("/bin/sh", "sh", "-c", "/opt/qcom/bin/version.out > /tmp/version", (char *)NULL);
exit(0);
}
else
{
// In parent, wait for 1 second
sleep(1);
int status;
if (waitpid(pid, &status, WNOHANG) != pid)
{
//kill(pid, SIGTERM); //--> tried this too
kill(pid, SIGKILL);
}
fsmverDir("/tmp/version");
system("rm /tmp/version");
}


But it's not killing completely, I see below ps output after running my program 3 times (it created 3 version.out's), and "sh" appear as zombie...

# ps | grep "version.out\|sh"
2012 root 0 Z [sh]
2013 root 13236 S /opt/qcom/bin/version.out
2058 root 0 Z [sh]
2059 root 13236 S /opt/qcom/bin/version.out
2092 root 0 Z [sh]
2093 root 13236 S /opt/qcom/bin/version.out
2100 root 2360 S grep version.out\|sh
#


Or, is there a way to run the command with timeout in busybox Linux?

Something like:

execlp("timeout","timeout","1","sh","-c","/opt/qcom/bin/version.out > /tmp/version",NULL);


There is no timeout in my busybox version, is there an alternative?

Answer

You are creating a shell (the child) which in turn runs "version.out" (the grandchild).

You kill the child thereby making it a zombie and orphaning the grandchild. You can collect the child by calling wait a second time (it error-ed out the first time or you would never have called kill) but you still won't accomplish the goal of killing the grandchild from the parent.