X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=run-command.c;h=7e779d33ee9ea5f7d2e6aedc8c3a0a0476e87135;hb=be6042cfa59358b733b6f9ba05bcbc317998d9fe;hp=d20a6ef80c08bcf51ab5e650875ba8994917ca70;hpb=f4bba25bdc0ecb4ac338de81a2a65af487701833;p=git.git diff --git a/run-command.c b/run-command.c index d20a6ef80..7e779d33e 100644 --- a/run-command.c +++ b/run-command.c @@ -8,12 +8,19 @@ static inline void close_pair(int fd[2]) close(fd[1]); } +static inline void dup_devnull(int to) +{ + int fd = open("/dev/null", O_RDWR); + dup2(fd, to); + close(fd); +} + int start_command(struct child_process *cmd) { - int need_in = !cmd->no_stdin && cmd->in < 0; - int need_out = !cmd->stdout_to_stderr && cmd->out < 0; + int need_in, need_out; int fdin[2], fdout[2]; + need_in = !cmd->no_stdin && cmd->in < 0; if (need_in) { if (pipe(fdin) < 0) return -ERR_RUN_COMMAND_PIPE; @@ -21,6 +28,9 @@ int start_command(struct child_process *cmd) cmd->close_in = 1; } + need_out = !cmd->no_stdout + && !cmd->stdout_to_stderr + && cmd->out < 0; if (need_out) { if (pipe(fdout) < 0) { if (need_in) @@ -41,11 +51,9 @@ int start_command(struct child_process *cmd) } if (!cmd->pid) { - if (cmd->no_stdin) { - int fd = open("/dev/null", O_RDWR); - dup2(fd, 0); - close(fd); - } else if (need_in) { + if (cmd->no_stdin) + dup_devnull(0); + else if (need_in) { dup2(fdin[0], 0); close_pair(fdin); } else if (cmd->in) { @@ -53,7 +61,9 @@ int start_command(struct child_process *cmd) close(cmd->in); } - if (cmd->stdout_to_stderr) + if (cmd->no_stdout) + dup_devnull(1); + else if (cmd->stdout_to_stderr) dup2(2, 1); else if (need_out) { dup2(fdout[1], 1); @@ -63,6 +73,17 @@ int start_command(struct child_process *cmd) close(cmd->out); } + if (cmd->dir && chdir(cmd->dir)) + die("exec %s: cd to %s failed (%s)", cmd->argv[0], + cmd->dir, strerror(errno)); + if (cmd->env) { + for (; *cmd->env; cmd->env++) { + if (strchr(*cmd->env, '=')) + putenv((char*)*cmd->env); + else + unsetenv(*cmd->env); + } + } if (cmd->git_cmd) { execv_git_cmd(cmd->argv); } else { @@ -123,13 +144,37 @@ int run_command(struct child_process *cmd) return finish_command(cmd); } +static void prepare_run_command_v_opt(struct child_process *cmd, + const char **argv, + int opt) +{ + memset(cmd, 0, sizeof(*cmd)); + cmd->argv = argv; + cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; + cmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0; + cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; +} + int run_command_v_opt(const char **argv, int opt) { struct child_process cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.argv = argv; - cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; - cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0; - cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; + prepare_run_command_v_opt(&cmd, argv, opt); + return run_command(&cmd); +} + +int run_command_v_opt_cd(const char **argv, int opt, const char *dir) +{ + struct child_process cmd; + prepare_run_command_v_opt(&cmd, argv, opt); + cmd.dir = dir; + return run_command(&cmd); +} + +int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env) +{ + struct child_process cmd; + prepare_run_command_v_opt(&cmd, argv, opt); + cmd.dir = dir; + cmd.env = env; return run_command(&cmd); }