#include /* for errno() */ #include /* for ARG_MAX */ #include /* for signal(), SIG* */ #include /* for sprintf(), stderr, ... */ #include /* for exit() */ #include /* for strerror() */ #include /* for wait() */ #include /* for wait() */ #include /* for time() */ #include /* for sleep(), fork() and execlp() */ #include "funcs.h" /* for infomsg(), errormsg() */ /* * Macros */ #define MAX_CHILDREN 1000 #define CHILDREN 5 #define INTER_CHILD_INTERVAL 10 #define CHILD_RUN_TIME(n) (((n+getpid())*7)%19) /* stupid pseudo RNG */ /* * Type and struct definitions */ struct child { pid_t pid; time_t start; }; /* * Global variables */ struct child children[MAX_CHILDREN]; /* * Forward declarations */ pid_t start_child_sleep(int); void sigchld_handler(int); /* * Functions */ int main( int argc, char *argv[]) { int i, j; int running_children_count; time_t now; /* * Initialise. */ infomsg("parent initialising children status table ..."); for (i=0; i 0) { children[i].pid = pid; children[i].start = time(NULL); return(pid); } /* * Only the child gets here */ sprintf(buf, "echo \"child $$ started ...\";" "sleep %d;" "echo \"child $$ exiting ...\"", period); infomsg("child running for %ds ...", period); execlp("/bin/sh", "sh", "-c", buf, (char *) NULL); errormsg("exec() failed: %s", strerror(errno)); } void sigchld_handler( int sig) { int wstatus; pid_t pid; int i; while ((pid=waitpid(-1, &wstatus, WNOHANG)) > 0) { infomsg("parent received SIGCHLD; reaping and clearing child data ..."); for (i=0; i