summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2013-02-12 15:02:31 +0100
committerJunio C Hamano <gitster@pobox.com>2013-02-12 13:15:11 -0800
commitf4c0035de660f5be4d78b0ba0aa8a7863b89c72f (patch)
treeff3d58a09b6f65e79004b178704b5c245d73cc3b
parent1323dba6afad29d3cd07e9da85b947bfc2b912de (diff)
downloadgit-f4c0035de660f5be4d78b0ba0aa8a7863b89c72f.tar.gz
Git.pm: allow pipes to be closed prior to calling command_close_bidi_pipe
The command_close_bidi_pipe() function will insist on closing both input and output pipes returned by command_bidi_pipe(). With this change it is possible to close one of the pipes in advance and pass undef as an argument. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--perl/Git.pm15
1 files changed, 14 insertions, 1 deletions
diff --git a/perl/Git.pm b/perl/Git.pm
index 2ccb95dc14..620e0f9e51 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -426,12 +426,25 @@ Note that you should not rely on whatever actually is in C<CTX>;
currently it is simply the command name but in future the context might
have more complicated structure.
+C<PIPE_IN> and C<PIPE_OUT> may be C<undef> if they have been closed prior to
+calling this function. This may be useful in a query-response type of
+commands where caller first writes a query and later reads response, eg:
+
+ my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
+ print $out "000000000\n";
+ close $out;
+ while (<$in>) { ... }
+ $r->command_close_bidi_pipe($pid, $in, undef, $ctx);
+
+This idiom may prevent potential dead locks caused by data sent to the output
+pipe not being flushed and thus not reaching the executed command.
+
=cut
sub command_close_bidi_pipe {
local $?;
my ($self, $pid, $in, $out, $ctx) = _maybe_self(@_);
- _cmd_close($ctx, $in, $out);
+ _cmd_close($ctx, (grep { defined } ($in, $out)));
waitpid $pid, 0;
if ($? >> 8) {
throw Git::Error::Command($ctx, $? >>8);