aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbert Dvornik <dvornik+git@gmail.com>2010-05-20 20:57:52 +0200
committerJunio C Hamano <gitster@pobox.com>2010-05-20 16:11:29 -0700
commitfc012c2810c237dd2299a3fc85b18c2beb60b730 (patch)
tree41bc04928e0a2ab24f2c28b8f8c2da153de0820e
parent60890cc60ccfc7000791a47f1f3d69fdb8884dd7 (diff)
downloadgit-fc012c2810c237dd2299a3fc85b18c2beb60b730.tar.gz
git-fc012c2810c237dd2299a3fc85b18c2beb60b730.tar.xz
start_command: close cmd->err descriptor when fork/spawn fails
Fix the problem where the cmd->err passed into start_command wasn't being properly closed when certain types of errors occurr. (Compare the affected code with the clean shutdown code later in the function.) On Windows, this problem would be triggered if mingw_spawnvpe() failed, which would happen if the command to be executed was malformed (e.g. a text file that didn't start with a #! line). If cmd->err was a pipe, the failure to close it could result in a hang while the other side was waiting (forever) for either input or pipe close, e.g. while trying to shove the output into the side band. On msysGit, this problem was causing a hang in t5516-fetch-push. [J6t: With a slight adjustment of the test case, the hang is also observed on Linux.] Signed-off-by: bert Dvornik <dvornik+git@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--run-command.c2
-rwxr-xr-xt/t5516-fetch-push.sh2
2 files changed, 3 insertions, 1 deletions
diff --git a/run-command.c b/run-command.c
index eb5c57562..c7793f50f 100644
--- a/run-command.c
+++ b/run-command.c
@@ -383,6 +383,8 @@ fail_pipe:
close(cmd->out);
if (need_err)
close_pair(fderr);
+ else if (cmd->err)
+ close(cmd->err);
errno = failed_errno;
return -1;
}
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 2de98e656..6a37a4d99 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -528,7 +528,7 @@ test_expect_success 'push does not update local refs on failure' '
mk_test heads/master &&
mk_child child &&
mkdir testrepo/.git/hooks &&
- echo exit 1 >testrepo/.git/hooks/pre-receive &&
+ echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
chmod +x testrepo/.git/hooks/pre-receive &&
(cd child &&
git pull .. master