Esempio n. 1
0
void
double_fork() {
  pid_t child, grandchild, wresult;
  int status;

  /* Fork once, then again, to disassociate the child from the command
     shell process group. */
  child = fork();
  if (child < 0) {
    /* Failure to fork. */
    perror("fork");
    exit(1);
  }

  if (child == 0) {
    /* Child.  Fork again. */
    grandchild = fork();
    if (grandchild < 0) {
      perror("fork");
      exit(1);
    }

    if (grandchild == 0) {
      /* Grandchild.  Begin useful work. */
      do_autorestart();
      /* Shouldn't get here. */
      exit(1);
    }

    /* Child.  Report the new pid, then terminate gracefully. */
    fprintf(stderr, "Spawned, monitoring pid is %d.\n", grandchild);
    exit(0);
  }

  /* Parent.  Wait for the child to terminate, then return. */
  wresult = waitpid(child, &status, 0);
  if (wresult < 0) {
    perror("waitpid");
    exit(1);
  }

  if (!WIFEXITED(status)) {
    if (WIFSIGNALED(status)) {
      fprintf(stderr, "child caught signal %d unexpectedly.\n", WTERMSIG(status));
    } else {
      fprintf(stderr, "child exited with status %d.\n", WEXITSTATUS(status));
    }
    exit(1);
  }
}
Esempio n. 2
0
int 
main(int argc, char *argv[]) {
  extern char *optarg;
  extern int optind;
  /* The initial '+' instructs GNU getopt not to reorder switches. */
  static const char *optflags = "+l:p:fntr:s:c:d:W:U:G:D:h";
  int flag;

  flag = getopt(argc, argv, optflags);
  while (flag != EOF) {
    switch (flag) {
    case 'l':
      logfile_name = optarg;
      break;

    case 'p':
      pidfile_name = optarg;
      break;

    case 'f':
      dont_fork = 1;
      break;

    case 'n':
      stop_always = 1;
      break;

    case 't':
      stop_on_terminate = 1;
      break;

    case 'r':
      parse_int_triplet(optarg, &spam_respawn_count, &spam_respawn_time, &spam_restart_delay_time);
      break;

    case 's':
      respawn_script = optarg;
      break;

    case 'c':
      respawn_count_time = atoi(optarg);
      break;

    case 'd':
      respawn_delay_time = atoi(optarg);
      break;

    case 'W':
      parse_watchdog(optarg);
      break;

    case 'U':
      startup_username = optarg;
      break;

    case 'G':
      startup_groupname = optarg;
      break;

    case 'D':
      startup_chdir = optarg;
      break;
      
    case 'h':
      help();
      return 1;

    case '?':
    case '+':
      usage();
      return 1;

    default:
      fprintf(stderr, "Unhandled switch: -%c\n", flag);
      return 1;
    }
    flag = getopt(argc, argv, optflags);
  }

  argc -= (optind - 1);
  argv += (optind - 1);

  if (argc < 2) {
    fprintf(stderr, "No program to execute given.\n");
    usage();
    return 1;
  }

  params = &argv[1];

  if (logfile_name != NULL) {
    logfile_fd = open(logfile_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (logfile_fd < 0) {
      fprintf(stderr, "Cannot write to logfile %s: %s\n", 
              logfile_name, strerror(errno));
      return 1;
    }
    fprintf(stderr, "Generating output to %s.\n", logfile_name);
  }

  if (startup_chdir != NULL) {
    if (chdir(startup_chdir) != 0) {
      perror(startup_chdir);
      return 1;
    }
  }

  if (startup_groupname != NULL) {
    struct group *grp;
    grp = getgrnam(startup_groupname);
    if (grp == NULL) {
      perror(startup_groupname);
      return 1;
    }

    if (setgid(grp->gr_gid) != 0) {
      perror(startup_groupname);
      return 1;
    }
  }

  if (startup_username != NULL) {
    struct passwd *pwd;
    pwd = getpwnam(startup_username);
    if (pwd == NULL) {
      perror(startup_username);
      return 1;
    }

    if (setuid(pwd->pw_uid) != 0) {
      perror(startup_username);
      return 1;
    }
  }

  if (dont_fork) {
    do_autorestart();
  } else {
    double_fork();
  }

  return 0;
}