Let a daemon process take over as a parent
#include <sys/procmgr.h> pid_t procmgr_guardian( pid_t pid );
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
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.-1 on error; any other value on success.
#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;
}
| Safety: | |
|---|---|
| Cancellation point | No |
| Interrupt handler | No |
| Signal handler | Yes |
| Thread | Yes |