why waitpid is blocked and how can i know last child process's exit-code

431 views Asked by At
int do_fork(int *status)
{
    int pid;
    int check;

    pid = fork();
    if (pid > 0)
    {
        waitpid(pid, status, 0);  // Question
    }
    else if (pid == 0)
    {
        check = execve(command, args, 0);
        if (check == -1)
        {
            exit(errno);
        }
    }
    return (0);
}

int main()
{
    int status = 0;

    for (int i = 0; i < 3; i++)
    {
        do_fork(&status);    
    }
    printf("status : %d\n", status >> 8);
    return (status >> 8);;
}

In Clang, gcc

This is a simplified form of my code.

I wanted to know the exit code of the last child process.

waitpid(pid, status, 0); This resulted in an infinite wait. By the way waitpid(pid, status, WNOHANG); , status is always 0.

How can I get the exit code of the last child process from the parent process?

If the information in my question is not enough Please advise on how to ask the question.

1

There are 1 answers

1
Mafalda Teixeira On

waitpid(pid, status, 0); This resulted in an infinite wait. By the way waitpid(pid, status, WNOHANG); , status is always 0.

waitpid(pid, status, 0) will hang until any child terminates. If there is an infinite wait, that means that your child hasn't finished (or that there are no children). Maybe you can print in your command when you reach the end.

waitpid(pid, status, WNOHANG); will have a status 0 because that is the value that you set to the status before providing it as a pointer. If no child has finished, then you will get no change in status. Status is only updated when the child finishes and returns a value.

You can also check:

int child_pid = waitpid(pid, status, WNOHANG), if child_pid is the value of the pid, it means your child has finished, and status should be the return value of your command. If child_pid is 0, it means that your process has children, but they haven't finished yet (you can call the blocking waitpid() and wait for them). If child_pid is -1 there is an issue: for example, errno == ECHILD, that means that your process has no children. You can read the docs for other errors.

My guess is that there is a child, but the command is something that hangs for a long time. Double check that first.

How can I get the exit code of the last child process from the parent process?

This question is slightly more general than your code. If you want to know the exit code of the last child process from the parent process (i.e., any child process), then you should use -1 instead of pid:

int child_pid = waitpid(-1, status, WNOHANG)

The return value explanation is the same one as above: child_pid>0 will be the pid of the child that terminated , child_pid==0 means there are children, but none terminate, child_pid==-1 there is a problem.