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>maint
parent
79319b1949
commit
53fa6753b3
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue