procmgr_guardian()

Let a daemon process take over as a parent

Synopsis:

#include <sys/procmgr.h>

pid_t procmgr_guardian( pid_t pid );

Arguments:

pid
The ID of the child process that you want to become the guardian of the calling process's other children.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The function procmgr_guardian() allows a daemon process to declare a child process to take over as parent to its children in the event of its death:

Figure 1. Specifying a guardian for child processes.

Returns:

-1 on error; any other value on success.

Examples:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <spawn.h>
#include <sys/procmgr.h>
#include <sys/wait.h>

pid_t     child = -1;
pid_t     guardian = -1;

/*
 * Build a list of the currently running children
 */
void check_children(void) {
    if(child > 0) {
        if(kill(child, 0) == -1) {
            child = -1;
        }
    }
    if(guardian > 0) {
        if(kill(guardian, 0) == -1) {
            guardian = -1;
        }
    }
}

void start_needed_children(void) {
    if(guardian == -1) {
        /* Make a child that will just sit around
           and wait for parent to die */
        while((guardian = fork()) == 0) {
            pid_t parent = getppid();

            /* Wait for parent to die.... */
            fprintf(stderr, "guardian %d waiting on parent %d\n",
                    getpid(), parent);

            while(waitpid(parent, 0, 0) != parent);
            /* Then loop around and take over */
        }
        if(guardian == -1) {
            fprintf(stderr, "Unable to start guardian\n");
        } else {
            /* Declare the child a guardian */
            procmgr_guardian(guardian);
        }
    }

    if(child == -1) {
        static char    *args[] = { "sleep", "1000000", 0 };

        if((child = spawnp("sleep", 0, 0, 0, args, 0)) == -1) {
            fprintf(stderr, "Couldn't start child\n");
            child = 0;    /* don't try again */
        }
    }
}

int main(int argc, char *argv[]) {
    fprintf(stderr, "parent %d checking children\n", getpid());
    do {
        fprintf(stderr, "checking children\n");

        /* Learn about the newly adopted children */
        check_children();

        /* If anyone is missing, start them */
        start_needed_children();
    } while(wait(0));     /* Then wait for someone to die... */
    return EXIT_SUCCESS;
}

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes