Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wait for children and grand-children

Tags:

c

unix

signals

How can you wait until all children and grand-children have exited, without blocking in a signal handler? This is my attempt so far.

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int run = 1;

void handler(int sig, siginfo_t *info, void *uap)
{
    int exit_code;

    printf("sigchld pid %d\n", info->si_pid);
    pid_t pid = waitpid(-1, &exit_code, 0);
    if (pid == -1) {
        perror("waitpid()\n");
    } else {
        printf("waitpid returned %d\n", pid);
    }
    // set run = 0 when all children exit

    printf("end of sigchild handler\n");
}

void main() {

    struct sigaction chld;
    chld.sa_sigaction = handler;
    chld.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
    sigaction(SIGCHLD, &chld, NULL);

    //procmask sigchld?
    if (!fork ()) {
        if (!fork ()) {
            sleep(2);
            printf ("grand-son exit: %d\n", getpid());
            exit (0);
        }
        sleep(1);
        printf ("son exit: %d\n", getpid());
        exit (0);
    }

    while(run)
        sleep(1);

    printf("ciao\n");
}
like image 841
elmarco Avatar asked Aug 31 '25 04:08

elmarco


1 Answers

While it is true that SIGCHLD and waitpid, etc., only work for immediate children, on UNIX systems you can often "cheat" a little bit with inherited resources passed from parent to child to grandchild, and closed upon process termination.

For example, the original process might open a pipe, and perhaps set the read end of it close-on-exec, so that children and grandchildren inherit the write end. When the original process is ready to wait for all descendants to terminate, it closes its write end of the pipe and blockingly reads or selects for readability on the remaining descriptor. When the last descendant has terminated, the read end of the pipe will deliver an EOF.

This tactic is not guaranteed — a child or grandchild might cautiously close inherited file descriptors — but it often works well enough.

like image 94
pilcrow Avatar answered Sep 02 '25 17:09

pilcrow