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>
Brandon Williams committed
Apr 19, 2017 at 16:13 UTC
53fa6753b30c4fb4ea768d16d41d723ea19a3b00
1 file changed
+42
-16
run-command.c
+42
-16
@@ -213,6 +213,8 @@ static int child_notifier = -1;
213
214
enum child_errcode {
215
CHILD_ERR_CHDIR,
216
+ CHILD_ERR_DUP2,
217
+ CHILD_ERR_CLOSE,
218
CHILD_ERR_ENOENT,
219
CHILD_ERR_SILENT,
220
CHILD_ERR_ERRNO
@@ -235,6 +237,24 @@ static void child_die(enum child_errcode err)
237
_exit(1);
238
}
239
240
+static void child_dup2(int fd, int to)
241
+{
242
+ if (dup2(fd, to) < 0)
243
+ child_die(CHILD_ERR_DUP2);
244
+}
245
+
246
+static void child_close(int fd)
247
+{
248
+ if (close(fd))
249
+ child_die(CHILD_ERR_CLOSE);
250
+}
251
+
252
+static void child_close_pair(int fd[2])
253
+{
254
+ child_close(fd[0]);
255
+ child_close(fd[1]);
256
+}
257
+
258
/*
259
* parent will make it look like the child spewed a fatal error and died
260
* 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)
297
error_errno("exec '%s': cd to '%s' failed",
298
cmd->argv[0], cmd->dir);
299
break;
300
+ case CHILD_ERR_DUP2:
301
+ error_errno("dup2() in child failed");
302
+ break;
303
+ case CHILD_ERR_CLOSE:
304
+ error_errno("close() in child failed");
305
+ break;
306
case CHILD_ERR_ENOENT:
307
error_errno("cannot run %s", cmd->argv[0]);
308
break;
@@ -527,35 +553,35 @@ fail_pipe:
553
child_notifier = notify_pipe[1];
554
555
if (cmd->no_stdin)
530
- dup2(null_fd, 0);
556
+ child_dup2(null_fd, 0);
557
else if (need_in) {
532
- dup2(fdin[0], 0);
533
- close_pair(fdin);
558
+ child_dup2(fdin[0], 0);
559
+ child_close_pair(fdin);
560
} else if (cmd->in) {
535
- dup2(cmd->in, 0);
536
- close(cmd->in);
561
+ child_dup2(cmd->in, 0);
562
+ child_close(cmd->in);
563
}
564
565
if (cmd->no_stderr)
540
- dup2(null_fd, 2);
566
+ child_dup2(null_fd, 2);
567
else if (need_err) {
542
- dup2(fderr[1], 2);
543
- close_pair(fderr);
568
+ child_dup2(fderr[1], 2);
569
+ child_close_pair(fderr);
570
} else if (cmd->err > 1) {
545
- dup2(cmd->err, 2);
546
- close(cmd->err);
571
+ child_dup2(cmd->err, 2);
572
+ child_close(cmd->err);
573
}
574
575
if (cmd->no_stdout)
550
- dup2(null_fd, 1);
576
+ child_dup2(null_fd, 1);
577
else if (cmd->stdout_to_stderr)
552
- dup2(2, 1);
578
+ child_dup2(2, 1);
579
else if (need_out) {
554
- dup2(fdout[1], 1);
555
- close_pair(fdout);
580
+ child_dup2(fdout[1], 1);
581
+ child_close_pair(fdout);
582
} else if (cmd->out > 1) {
557
- dup2(cmd->out, 1);
558
- close(cmd->out);
583
+ child_dup2(cmd->out, 1);
584
+ child_close(cmd->out);
585
}
586
587
if (cmd->dir && chdir(cmd->dir))