summaryrefslogtreecommitdiffstats
path: root/run-command.c
diff options
context:
space:
mode:
authorBrandon Williams <bmwill@google.com>2017-04-19 16:13:25 -0700
committerJunio C Hamano <gitster@pobox.com>2017-04-20 17:55:32 -0700
commit53fa6753b30c4fb4ea768d16d41d723ea19a3b00 (patch)
tree2a21578a0e354024bef7b6d2b46004e8c69529d5 /run-command.c
parent79319b1949f0055bd42bac7fa398fca8c2f26116 (diff)
downloadgit-53fa6753b30c4fb4ea768d16d41d723ea19a3b00.tar.gz
git-53fa6753b30c4fb4ea768d16d41d723ea19a3b00.tar.xz
run-command: handle dup2 and close errors in child
Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'run-command.c')
-rw-r--r--run-command.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/run-command.c b/run-command.c
index 1f15714b1..615b6e9c9 100644
--- a/run-command.c
+++ b/run-command.c
@@ -213,6 +213,8 @@ static int child_notifier = -1;
enum child_errcode {
CHILD_ERR_CHDIR,
+ CHILD_ERR_DUP2,
+ CHILD_ERR_CLOSE,
CHILD_ERR_ENOENT,
CHILD_ERR_SILENT,
CHILD_ERR_ERRNO
@@ -235,6 +237,24 @@ static void child_die(enum child_errcode err)
_exit(1);
}
+static void child_dup2(int fd, int to)
+{
+ if (dup2(fd, to) < 0)
+ child_die(CHILD_ERR_DUP2);
+}
+
+static void child_close(int fd)
+{
+ if (close(fd))
+ child_die(CHILD_ERR_CLOSE);
+}
+
+static void child_close_pair(int fd[2])
+{
+ child_close(fd[0]);
+ child_close(fd[1]);
+}
+
/*
* parent will make it look like the child spewed a fatal error and died
* this is needed to prevent changes to t0061.
@@ -277,6 +297,12 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
error_errno("exec '%s': cd to '%s' failed",
cmd->argv[0], cmd->dir);
break;
+ case CHILD_ERR_DUP2:
+ error_errno("dup2() in child failed");
+ break;
+ case CHILD_ERR_CLOSE:
+ error_errno("close() in child failed");
+ break;
case CHILD_ERR_ENOENT:
error_errno("cannot run %s", cmd->argv[0]);
break;
@@ -527,35 +553,35 @@ fail_pipe:
child_notifier = notify_pipe[1];
if (cmd->no_stdin)
- dup2(null_fd, 0);
+ child_dup2(null_fd, 0);
else if (need_in) {
- dup2(fdin[0], 0);
- close_pair(fdin);
+ child_dup2(fdin[0], 0);
+ child_close_pair(fdin);
} else if (cmd->in) {
- dup2(cmd->in, 0);
- close(cmd->in);
+ child_dup2(cmd->in, 0);
+ child_close(cmd->in);
}
if (cmd->no_stderr)
- dup2(null_fd, 2);
+ child_dup2(null_fd, 2);
else if (need_err) {
- dup2(fderr[1], 2);
- close_pair(fderr);
+ child_dup2(fderr[1], 2);
+ child_close_pair(fderr);
} else if (cmd->err > 1) {
- dup2(cmd->err, 2);
- close(cmd->err);
+ child_dup2(cmd->err, 2);
+ child_close(cmd->err);
}
if (cmd->no_stdout)
- dup2(null_fd, 1);
+ child_dup2(null_fd, 1);
else if (cmd->stdout_to_stderr)
- dup2(2, 1);
+ child_dup2(2, 1);
else if (need_out) {
- dup2(fdout[1], 1);
- close_pair(fdout);
+ child_dup2(fdout[1], 1);
+ child_close_pair(fdout);
} else if (cmd->out > 1) {
- dup2(cmd->out, 1);
- close(cmd->out);
+ child_dup2(cmd->out, 1);
+ child_close(cmd->out);
}
if (cmd->dir && chdir(cmd->dir))