I am trying to write a program in which I am forking a child from a parent, and handling SIGCHLD signals using a handler, in which I use waitpid(). When I execute it, however, I am sometimes getting a return value of 0 from waitpid, along with errno being set to EINTR. What does that mean?
Here is my SIGCHLD handler:
pid_t pid;
int status;
while((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0)
{
printf("Handler reaped child %d\n", (int)pid);
if(WIFEXITED(status))
{
deletejob(job_list, pid);
}
else if(WIFSIGNALED(status))
{
deletejob(job_list, pid);
}
else if(WIFSTOPPED(status))
{
struct job_t *job = getjobpid(job_list, pid);
job->state = ST;
}
}
printf("%d %d\n", pid, errno);
if(errno != ECHILD)
{
unix_error("waitpid error");
}
return;
Here is the parent function, in which I fork the child:
pid_t pid;
sigset_t block_set;
int file_descriptor;
if(tok.outfile == NULL)
{
file_descriptor = STDOUT_FILENO;
}
else
{
file_descriptor = open(tok.outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
}
sigemptyset(&block_set);
sigaddset(&block_set, SIGCHLD);
sigaddset(&block_set, SIGINT);
sigaddset(&block_set, SIGTSTP);
sigprocmask(SIG_BLOCK, &block_set, NULL);
pid = fork();
if(pid == 0)
{
sigprocmask(SIG_UNBLOCK, &block_set, NULL);
setpgid(0, 0);
dup2(file_descriptor, 1);
while(execve(tok.argv[0], tok.argv, environ) < 0)
{
exit(0);
}
}
else
{
if(bg == 1)
{
addjob(job_list, pid, BG, cmdline);
sigprocmask(SIG_UNBLOCK, &block_set, NULL);
int jid = pid2jid(pid);
printf("[%d] (%d) %s\n", jid, pid, cmdline);
}
else if(bg == 0)
{
addjob(job_list, pid, FG, cmdline);
sigprocmask(SIG_UNBLOCK, &block_set, NULL);
}
if(bg == 0)
{
struct job_t *job = getjobpid(job_list, pid);
while(pid == fgpid(job_list))
{
sleep(1);
}
}
}
}
return;