procmgr_guardian()
QNX SDP8.0C Library ReferenceAPIDeveloper
Let a 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 should become the guardian of the calling process's other children, in the event of the demise of the calling process.
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 process to declare a child process to take over as parent to its children in the event of its death:
Note:
If a process is a guardian it may wait on processes that are not its children (e.g., in a call to waitpid()). Specifically, using the diagram above as reference:
- Process B can't do a waitpid() on process A. This is expected behavior, and has nothing to do with C being the designated guardian of B; it is because A is the parent of B.
However, once process C is designated as the guardian of B:
- C can do a waitpidin() on B.
- C can do a waitpid() on A, even though A is the parent of C.
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:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |
Page updated: