run-command.con commit Start defining a more sophisticated run_command (f100089)
   1#include "cache.h"
   2#include "run-command.h"
   3#include "exec_cmd.h"
   4
   5int run_command(struct child_process *cmd)
   6{
   7        pid_t pid = fork();
   8
   9        if (pid < 0)
  10                return -ERR_RUN_COMMAND_FORK;
  11        if (!pid) {
  12                if (cmd->no_stdin) {
  13                        int fd = open("/dev/null", O_RDWR);
  14                        dup2(fd, 0);
  15                        close(fd);
  16                }
  17                if (cmd->stdout_to_stderr)
  18                        dup2(2, 1);
  19                if (cmd->git_cmd) {
  20                        execv_git_cmd(cmd->argv);
  21                } else {
  22                        execvp(cmd->argv[0], (char *const*) cmd->argv);
  23                }
  24                die("exec %s failed.", cmd->argv[0]);
  25        }
  26        for (;;) {
  27                int status, code;
  28                pid_t waiting = waitpid(pid, &status, 0);
  29
  30                if (waiting < 0) {
  31                        if (errno == EINTR)
  32                                continue;
  33                        error("waitpid failed (%s)", strerror(errno));
  34                        return -ERR_RUN_COMMAND_WAITPID;
  35                }
  36                if (waiting != pid)
  37                        return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
  38                if (WIFSIGNALED(status))
  39                        return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
  40
  41                if (!WIFEXITED(status))
  42                        return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
  43                code = WEXITSTATUS(status);
  44                if (code)
  45                        return -code;
  46                return 0;
  47        }
  48}
  49
  50int run_command_v_opt(const char **argv, int opt)
  51{
  52        struct child_process cmd;
  53        memset(&cmd, 0, sizeof(cmd));
  54        cmd.argv = argv;
  55        cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
  56        cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
  57        cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
  58        return run_command(&cmd);
  59}