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
}