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:
-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 |
procmgr_daemon(), procmgr_event_notify(), procmgr_event_trigger()