46 #include <sys/types.h> 
   49 #include <sys/resource.h> 
   61 char safe_process_name[32]= {0};
 
   69   fprintf(stderr, 
"%s: ", safe_process_name);
 
   71   vfprintf(stderr, fmt, args);
 
   72   fprintf(stderr, 
"\n");
 
   78 static void die(
const char* fmt, ...)
 
   81   fprintf(stderr, 
"%s: FATAL ERROR, ", safe_process_name);
 
   83   vfprintf(stderr, fmt, args);
 
   84   fprintf(stderr, 
"\n");
 
   86   if (
int last_err= errno)
 
   87     fprintf(stderr, 
"error: %d, %s\n", last_err, strerror(last_err));
 
   92 static void kill_child(
void)
 
   96   message(
"Killing child: %d", child_pid);
 
   98   kill(-child_pid, SIGKILL);
 
  100   pid_t ret_pid= waitpid(child_pid, &status, 0);
 
  101   if (ret_pid == child_pid)
 
  104     if (WIFEXITED(status))
 
  107       exit_code= WEXITSTATUS(status);
 
  108       message(
"Child exit: %d", exit_code);
 
  113     if (WIFSIGNALED(status))
 
  114       message(
"Child killed by signal: %d", WTERMSIG(status));
 
  122 extern "C" void handle_abort(
int sig)
 
  124     message(
"Got signal %d, child_pid: %d, sending ABRT", sig, child_pid);
 
  127         kill (-child_pid, SIGABRT);     
 
  132 extern "C" void handle_signal(
int sig)
 
  134   message(
"Got signal %d, child_pid: %d", sig, child_pid);
 
  141   signal(SIGTERM, SIG_IGN);
 
  142   signal(SIGINT,  SIG_IGN);
 
  149 int main(
int argc, 
char* 
const argv[] )
 
  151   char* 
const* child_argv= 0;
 
  152   pid_t own_pid= getpid();
 
  153   pid_t parent_pid= getppid();
 
  157   sa.sa_handler= handle_signal;
 
  158   sa.sa_flags= SA_NOCLDSTOP;
 
  159   sigemptyset(&sa.sa_mask);
 
  161   sa_abort.sa_handler= handle_abort;
 
  162   sigemptyset(&sa_abort.sa_mask);
 
  169   sprintf(safe_process_name, 
"safe_process[%ld]", (
long) own_pid);
 
  174   for (
int i= 1; 
i < argc; 
i++) {
 
  175     const char* arg= argv[
i];
 
  176     if (strcmp(arg, 
"--") == 0 && strlen(arg) == 2) {
 
  179         die(
"No real args -> nothing to do");
 
  180       child_argv= &argv[
i+1];
 
  183       if ( strcmp(arg, 
"--verbose") == 0 )
 
  185       else if ( strncmp(arg, 
"--parent-pid", 12) == 0 )
 
  189         if ((start= strstr(arg, 
"=")) == NULL)
 
  190           die(
"Could not find start of option value in '%s'", arg);
 
  192         if ((parent_pid= atoi(start)) == 0)
 
  193           die(
"Invalid value '%s' passed to --parent-id", start);
 
  195       else if ( strcmp(arg, 
"--nocore") == 0 )
 
  199       else if ( strncmp (arg, 
"--env ", 6) == 0 )
 
  201         putenv(strdup(arg+6));
 
  204         die(
"Unknown option: %s", arg);
 
  207   if (!child_argv || *child_argv == 0)
 
  208     die(
"nothing to do");
 
  210   message(
"parent_pid: %d", parent_pid);
 
  211   if (parent_pid == own_pid)
 
  212     die(
"parent_pid is equal to own pid!");
 
  217     die(
"Failed to create pipe");
 
  220   while((child_pid= fork()) == -1)
 
  231     signal(SIGTERM, SIG_DFL);
 
  232     signal(SIGINT,  SIG_DFL);
 
  233     signal(SIGCHLD, SIG_DFL);
 
  241       struct rlimit corelim = { 0, 0 };
 
  242       if (setrlimit (RLIMIT_CORE, &corelim) < 0)
 
  244         message(
"setrlimit failed, errno=%d", errno);
 
  250     if ((write(pfd[1], &buf, 1)) < 1)
 
  251       die(
"Failed to signal that child is ready");
 
  255     if (execvp(child_argv[0], child_argv) < 0)
 
  256       die(
"Failed to exec child");
 
  262   if ((read(pfd[0], &buf, 1)) < 1)
 
  263     die(
"Failed to read signal from child");
 
  266     die(
"Didn't get 37 from pipe");
 
  270   message(
"Started child %d, terminated: %d", child_pid, terminated);
 
  275     if (
kill(parent_pid, 0) != 0){
 
  276       message(
"Parent is not alive anymore");
 
  283     pid_t ret_pid= waitpid(child_pid, &status, WNOHANG);
 
  284     if (ret_pid == child_pid)
 
  287       if (WIFEXITED(status))
 
  290         ret_code= WEXITSTATUS(status);
 
  291         message(
"Child exit: %d", ret_code);
 
  296       if (WIFSIGNALED(status))
 
  297         message(
"Child killed by signal: %d", WTERMSIG(status));