run-command: don't die in child when duping /dev/null

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 db015a284e74b93db9184d39eb0be749e631242d
1 file changed +13 -15
run-command.c
+13 -15
@@ -117,18 +117,6 @@ static inline void close_pair(int fd[2])
117 close(fd[1]);
118 }
119
120 -#ifndef GIT_WINDOWS_NATIVE
121 -static inline void dup_devnull(int to)
122 -{
123 - int fd = open("/dev/null", O_RDWR);
124 - if (fd < 0)
125 - die_errno(_("open /dev/null failed"));
126 - if (dup2(fd, to) < 0)
127 - die_errno(_("dup2(%d,%d) failed"), fd, to);
128 - close(fd);
129 -}
130 -#endif
131 -
120 static char *locate_in_PATH(const char *file)
121 {
122 const char *p = getenv("PATH");
@@ -444,12 +432,20 @@ fail_pipe:
432 #ifndef GIT_WINDOWS_NATIVE
433 {
434 int notify_pipe[2];
435 + int null_fd = -1;
436 char **childenv;
437 struct argv_array argv = ARGV_ARRAY_INIT;
438
439 if (pipe(notify_pipe))
440 notify_pipe[0] = notify_pipe[1] = -1;
441
442 + if (cmd->no_stdin || cmd->no_stdout || cmd->no_stderr) {
443 + null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
444 + if (null_fd < 0)
445 + die_errno(_("open /dev/null failed"));
446 + set_cloexec(null_fd);
447 + }
448 +
449 prepare_cmd(&argv, cmd);
450 childenv = prep_childenv(cmd->env);
451
@@ -473,7 +469,7 @@ fail_pipe:
469 atexit(notify_parent);
470
471 if (cmd->no_stdin)
476 - dup_devnull(0);
472 + dup2(null_fd, 0);
473 else if (need_in) {
474 dup2(fdin[0], 0);
475 close_pair(fdin);
@@ -483,7 +479,7 @@ fail_pipe:
479 }
480
481 if (cmd->no_stderr)
486 - dup_devnull(2);
482 + dup2(null_fd, 2);
483 else if (need_err) {
484 dup2(fderr[1], 2);
485 close_pair(fderr);
@@ -493,7 +489,7 @@ fail_pipe:
489 }
490
491 if (cmd->no_stdout)
496 - dup_devnull(1);
492 + dup2(null_fd, 1);
493 else if (cmd->stdout_to_stderr)
494 dup2(2, 1);
495 else if (need_out) {
@@ -553,6 +549,8 @@ fail_pipe:
549 }
550 close(notify_pipe[0]);
551
552 + if (null_fd >= 0)
553 + close(null_fd);
554 argv_array_clear(&argv);
555 free(childenv);
556 }