summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-03-22 23:54:05 -0400
committerJunio C Hamano <gitster@pobox.com>2015-03-22 21:39:22 -0700
commitc29b3962af3df80a43fab4ead4875bd2ca275e4c (patch)
treec78c409f1fde1425843d2b53bfc58d14be589274
parentc5eadcaab1d3969a4fbc009c65be622271edddd9 (diff)
downloadgit-jk/run-command-capture.tar.gz
run-command: forbid using run_command with piped outputjk/run-command-capture
Because run_command both spawns and wait()s for the command before returning control to the caller, any reads from the pipes we open must necessarily happen after wait() returns. This can lead to deadlock, as the child process may block on writing to us while we are blocked waiting for it to exit. Worse, it only happens when the child fills the pipe buffer, which means that the problem may come and go depending on the platform and the size of the output produced by the child. Let's detect and flag this dangerous construct so that we can catch potential bugs early in the test suite rather than having them happen in the field. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--run-command.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/run-command.c b/run-command.c
index 65ecbe31d7..4184e8d9f3 100644
--- a/run-command.c
+++ b/run-command.c
@@ -561,7 +561,12 @@ int finish_command(struct child_process *cmd)
int run_command(struct child_process *cmd)
{
- int code = start_command(cmd);
+ int code;
+
+ if (cmd->out < 0 || cmd->err < 0)
+ die("BUG: run_command with a pipe can cause deadlock");
+
+ code = start_command(cmd);
if (code)
return code;
return finish_command(cmd);