Example #1
0
/**
 * Forks and runs the given application, waits for a maximum of timeout seconds for process to finish.
 *
 * @param argv The arguments values, the first one is the application path or name
 */
void bb_run_fork_wait(char** argv, int timeout) {
  check_handler();
  // Fork and attempt to run given application
  pid_t ret = fork();
  if (ret == 0) {
    // Fork went ok, child process replace
    bb_run_exec(argv);
  } else {
    if (ret > 0) {
      // Fork went ok, parent process continues
      bb_log(LOG_DEBUG, "Process %s started, PID %i.\n", argv[0], ret);
      pidlist_add(ret);
      //sleep until process finishes or timeout reached
      int i = 0;
      while (bb_is_running(ret) && ((i < timeout) || (timeout == 0)) && dowait) {
        usleep(1000000);
        i++;
      }
      //make a single attempt to kill the process if timed out, without waiting
      if (bb_is_running(ret)) {
        bb_stop(ret);
      }
    } else {
      // Fork failed
      bb_log(LOG_ERR, "Process %s could not be started. fork() failed.\n", argv[0]);
      return;
    }
  }
  return;
}
Example #2
0
/**
 * Forks and runs the given application, using an optional LD_LIBRARY_PATH. The
 * function then returns immediately.
 * stderr and stdout of the ran application is redirected to the parameter redirect.
 * stdin is redirected to /dev/null always.
 *
 * @param argv The arguments values, the first one is the program
 * @param ldpath The library path to be used if any (may be NULL)
 * @param redirect The file descriptor to redirect stdout/stderr to. Must be valid and open.
 * @return The childs process ID
 */
pid_t bb_run_fork_ld_redirect(char **argv, char *ldpath, int redirect) {
  check_handler();
  // Fork and attempt to run given application
  pid_t ret = fork();
  if (ret == 0) {
    if (ldpath && *ldpath) {
      char *current_path = getenv("LD_LIBRARY_PATH");
      /* Fork went ok, set environment if necessary */
      if (current_path) {
        char *ldpath_new = malloc(strlen(ldpath) + 1 + strlen(current_path) + 1);
        if (ldpath_new) {
          strcpy(ldpath_new, ldpath);
          strcat(ldpath_new, ":");
          strcat(ldpath_new, current_path);
          setenv("LD_LIBRARY_PATH", ldpath_new, 1);
          free(ldpath_new);
        } else {
          bb_log(LOG_WARNING, "Could not allocate memory for LD_LIBRARY_PATH\n");
        }
      } else {
        setenv("LD_LIBRARY_PATH", ldpath, 1);
      }
    }
    //open /dev/null for stdin redirect
    int devnull = open("/dev/null", O_RDWR);
    //fail silently on error, nothing we can do about it anyway...
    if (devnull >= 0){dup2(devnull, STDIN_FILENO);}
    //redirect stdout and stderr to the given filenum.
    dup2(redirect, STDOUT_FILENO);
    dup2(redirect, STDERR_FILENO);
    close(devnull);
    //ok, all ready, now actually execute
    bb_run_exec(argv);
  } else {
    if (ret > 0) {
      // Fork went ok, parent process continues
      bb_log(LOG_DEBUG, "Process %s started, PID %i.\n", argv[0], ret);
      pidlist_add(ret);
    } else {
      // Fork failed
      bb_log(LOG_ERR, "Process %s could not be started. fork() failed.\n", argv[0]);
      return 0;
    }
  }
  return ret;
}
Example #3
0
/**
 * Forks and runs the given application and waits for the process to finish
 *
 * @param argv The arguments values, the first one is the program
 * @param detached non-zero if the std in/output must be redirected to /dev/null, zero otherwise
 * @return Exit code of the program (between 0 and 255) or -1 on failure
 */
int bb_run_fork(char **argv, int detached) {
  int exitcode = -1;

  check_handler();
  /* Fork and attempt to run given application */
  pid_t pid = fork();
  if (pid == 0) {
    /* child process after fork */
    if (detached) {
      bb_run_exec_detached(argv);
    } else {
      bb_run_exec(argv);
    }
  } else if (pid > 0) {
    /* parent process after fork */
    int status = 0;

    bb_log(LOG_DEBUG, "Process %s started, PID %i.\n", argv[0], pid);
    pidlist_add(pid);

    if (waitpid(pid, &status, 0) != -1) {
      if (WIFEXITED(status)) {
        /* program exited normally, return status */
        exitcode = WEXITSTATUS(status);
      } else if (WIFSIGNALED(status)) {
        /* program was terminated by a signal */
        exitcode = 128 + WTERMSIG(status);
      }
    } else {
      bb_log(LOG_ERR, "waitpid(%i) faild with %s\n", pid, strerror(errno));
    }
    pidlist_remove(pid);
  } else {
    /* Fork failed */
    bb_log(LOG_ERR, "Process %s could not be started. fork() failed.\n", argv[0]);
  }

  /* could not determine return value */
  return exitcode;
}
Example #4
0
/**
 * Forks and runs the given application, using an optional LD_LIBRARY_PATH. The
 * function then returns immediately
 *
 * @param argv The arguments values, the first one is the program
 * @param ldpath The library path to be used if any (may be NULL)
 * @return The childs process ID
 */
pid_t bb_run_fork_ld(char **argv, char *ldpath) {
  check_handler();
  // Fork and attempt to run given application
  pid_t ret = fork();
  if (ret == 0) {
    if (ldpath && *ldpath) {
      char *current_path = getenv("LD_LIBRARY_PATH");
      /* Fork went ok, set environment if necessary */
      if (current_path) {
        char *ldpath_new = malloc(strlen(ldpath) + 1 + strlen(current_path) + 1);
        if (ldpath_new) {
          strcpy(ldpath_new, ldpath);
          strcat(ldpath_new, ":");
          strcat(ldpath_new, current_path);
          setenv("LD_LIBRARY_PATH", ldpath_new, 1);
          free(ldpath_new);
        } else {
          bb_log(LOG_WARNING, "Could not allocate memory for LD_LIBRARY_PATH\n");
        }
      } else {
        setenv("LD_LIBRARY_PATH", ldpath, 1);
      }
    }
    bb_run_exec(argv);
  } else {
    if (ret > 0) {
      // Fork went ok, parent process continues
      bb_log(LOG_INFO, "Process %s started, PID %i.\n", argv[0], ret);
      pidlist_add(ret);
    } else {
      // Fork failed
      bb_log(LOG_ERR, "Process %s could not be started. fork() failed.\n", argv[0]);
      return 0;
    }
  }
  return ret;
}