run-command.con commit Makefile: add quick-install-doc for installing pre-built manpages (6538d1e)
   1#include "cache.h"
   2#include "run-command.h"
   3#include "exec_cmd.h"
   4
   5int run_command_v_opt(int argc, const char **argv, int flags)
   6{
   7        pid_t pid = fork();
   8
   9        if (pid < 0)
  10                return -ERR_RUN_COMMAND_FORK;
  11        if (!pid) {
  12                if (flags & RUN_COMMAND_NO_STDIO) {
  13                        int fd = open("/dev/null", O_RDWR);
  14                        dup2(fd, 0);
  15                        dup2(fd, 1);
  16                        close(fd);
  17                }
  18                if (flags & RUN_GIT_CMD) {
  19                        execv_git_cmd(argv);
  20                } else {
  21                        execvp(argv[0], (char *const*) argv);
  22                }
  23                die("exec %s failed.", argv[0]);
  24        }
  25        for (;;) {
  26                int status, code;
  27                pid_t waiting = waitpid(pid, &status, 0);
  28
  29                if (waiting < 0) {
  30                        if (errno == EINTR)
  31                                continue;
  32                        error("waitpid failed (%s)", strerror(errno));
  33                        return -ERR_RUN_COMMAND_WAITPID;
  34                }
  35                if (waiting != pid)
  36                        return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
  37                if (WIFSIGNALED(status))
  38                        return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
  39
  40                if (!WIFEXITED(status))
  41                        return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
  42                code = WEXITSTATUS(status);
  43                if (code)
  44                        return -code;
  45                return 0;
  46        }
  47}
  48
  49int run_command_v(int argc, const char **argv)
  50{
  51        return run_command_v_opt(argc, argv, 0);
  52}
  53
  54int run_command(const char *cmd, ...)
  55{
  56        int argc;
  57        const char *argv[MAX_RUN_COMMAND_ARGS];
  58        const char *arg;
  59        va_list param;
  60
  61        va_start(param, cmd);
  62        argv[0] = (char*) cmd;
  63        argc = 1;
  64        while (argc < MAX_RUN_COMMAND_ARGS) {
  65                arg = argv[argc++] = va_arg(param, char *);
  66                if (!arg)
  67                        break;
  68        }
  69        va_end(param);
  70        if (MAX_RUN_COMMAND_ARGS <= argc)
  71                return error("too many args to run %s", cmd);
  72        return run_command_v_opt(argc, argv, 0);
  73}