Reputation: 2843
I have a daemon program fork
s itself, then has an infinite loop checking system conditions, and when certain conditions are met, it runs a command. These commands can be long running which means they need to be asynchronous, so I'm using fork
and execvp
to run the commands. My code looks like this:
int main(int argc, char *argv[])
{
signal(SIGCHLD, SIG_IGN);
pid_t pid, sid;
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
umask(0);
sid = setsid();
if (sid < 0)
{
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0)
{
exit(EXIT_FAILURE);
}
while (1)
{
// Check conditions
...
if (conditions_met)
{
pid_t pid2, sid2;
pid2 = fork();
if (pid2 == 0)
{
sid2 = setsid();
// Define command_argv
...
execvp(command_argv[0], command_argv);
}
}
sleep(60);
}
exit(EXIT_SUCCESS);
}
This all works, and my commands are running fine - however, it's leaving zombie processes. This is my first time trying to use fork
and exec
asynchronously, but I thought that signal(SIGCHLD, SIG_IGN)
should ignore the child and let the init processes reap them. Why are these zombies still lingering?
Upvotes: 0
Views: 531
Reputation: 781741
The SIG_IGN
setting is not retained across fork()
, so you need to call signal(SIGCHLD, SIG_IGN);
in the child process with the loop that spawns all the commands, not the original parent process.
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
pid_t pid, sid;
pid = fork();
if (pid < 0)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
signal(SIGCHLD, SIG_IGN);
umask(0);
sid = setsid();
if (sid < 0)
{
perror("setsid");
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0)
{
perror("chdir");
exit(EXIT_FAILURE);
}
while (1)
{
// Check conditions
if (true)
{
pid_t pid2, sid2;
pid2 = fork();
if (pid2 == 0)
{
sid2 = setsid();
// Define command_argv
execlp("sleep", "sleep", "1", (char*)0);
}
}
sleep(60);
}
exit(EXIT_SUCCESS);
}
Upvotes: 3