From 33240cf8df597a67eb859547f497215fe16b3158 Mon Sep 17 00:00:00 2001 From: Ignas Mikalajunas Date: Wed, 6 Mar 2019 17:42:33 +0200 Subject: [PATCH 1/2] Set FD_CLOEXEC on stdin/out/err pipe fds in start_command This makes it possible to run more than one command started using start_command at the same time. When invoked start_command would create a set of pipes that it uses to communicate with the subprocess that was spawned, the git process that invoked start_command would own the file descriptors corresponding to the ends of the pipes pointing at stdout, stdin and stderr respectivelly. Which meant that if another process is spawned via fork + exec it would inherit all of those file descriptors from the git process, file descriptors that whatever process just got spawned by exec has no idea what to do with, which in some cases would cause the process that got spawned first to hang. For example, if git spawns two subprocesses A and B, and tries to shut down process A first, git closes the corresponding file descriptors, but as process B still has those same file descriptors pointing at the same pipes open, process A is still trying to read from those two pipes and not getting an EOF. Once this fix is applied - the process B does not inherit pipe descriptions, because this flag specifies that the file descriptor should be closed when an exec function is invoked. This makes running multiple commands safe. Signed-off-by: Ignas Mikalajunas --- run-command.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/run-command.c b/run-command.c index 296e2c4d487f4c..ad803274ea9a51 100644 --- a/run-command.c +++ b/run-command.c @@ -967,18 +967,24 @@ int start_command(struct child_process *cmd) return -1; } - if (need_in) + if (need_in) { close(fdin[0]); + set_cloexec(fdin[1]); + } else if (cmd->in) close(cmd->in); - if (need_out) + if (need_out) { close(fdout[1]); + set_cloexec(fdout[0]); + } else if (cmd->out) close(cmd->out); - if (need_err) + if (need_err) { close(fderr[1]); + set_cloexec(fderr[0]); + } else if (cmd->err) close(cmd->err); From 987df9e6ce8cff8d442ba742e3f093be9888429f Mon Sep 17 00:00:00 2001 From: Ignas Mikalajunas Date: Wed, 13 Mar 2019 18:11:18 +0200 Subject: [PATCH 2/2] fixup! send-pack: do not check for sha1 file when GVFS_MISSING_OK set --- send-pack.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/send-pack.c b/send-pack.c index 4cce09534509e6..9ff928e2f77bf0 100644 --- a/send-pack.c +++ b/send-pack.c @@ -15,7 +15,6 @@ #include "sha1-array.h" #include "gpg-interface.h" #include "cache.h" -#include "gvfs.h" int option_parse_push_signed(const struct option *opt, const char *arg, int unset) @@ -51,7 +50,7 @@ static int send_pack_config(const char *var, const char *value, void *unused) static void feed_object(const struct object_id *oid, FILE *fh, int negative) { - if (negative && !gvfs_config_is_set(GVFS_MISSING_OK) && !has_sha1_file(oid->hash)) + if (negative && !has_sha1_file(oid->hash)) return; if (negative)