csignalswaitpid

Determine pid of terminated process


I'm trying to figure out what the pid is of a process that sent the SIGCHLD signal, and I want to do this in a signal handler I created for SIGCHLD. How would I do this? I'm trying:

int pid = waitpid(-1, NULL, WNOHANG);

because I want to wait for any child process that is spawned.


Solution

  • If you use waitpid() more or less as shown, you will be told the PID of one of the child processes that has died — usually, that will be the only process that has died, but if you get a flurry of them, you might get one signal and many corpses to collect. So, use:

    void sigchld_handler(int signum)
    {
        pid_t pid;
        int   status;
        while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
        {
            unregister_child(pid, status);   // Or whatever you need to do with the PID
        }
    }
    

    You can replace &status with NULL if you don't care about the exit status of the child.

    Different systems document the return value of waitpid() slightly differently. However, POSIX is one of the more careful ones and says:

    If wait() or waitpid() returns because the status of a child process is available, these functions shall return a value equal to the process ID of the child process for which status is reported. If wait() or waitpid() returns due to the delivery of a signal to the calling process, -1 shall be returned and errno set to [EINTR]. If waitpid() was invoked with WNOHANG set in options, it has at least one child process specified by pid for which status is not available, and status is not available for any process specified by pid, 0 is returned. Otherwise, -1 shall be returned, and errno set to indicate the error.