summaryrefslogtreecommitdiff
path: root/perl/Git.pm
diff options
context:
space:
mode:
authorAdam Roben <aroben@apple.com>2008-05-23 14:19:39 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-05-23 19:06:51 (GMT)
commitd1a29af98e61de72841657bcaa86a93b38cda1c2 (patch)
treebf274e113845af9fa133278eba74679a83c9538a /perl/Git.pm
parentd8ee4832509dd2d7448a49920f5cba2fc979283d (diff)
downloadgit-d1a29af98e61de72841657bcaa86a93b38cda1c2.zip
git-d1a29af98e61de72841657bcaa86a93b38cda1c2.tar.gz
git-d1a29af98e61de72841657bcaa86a93b38cda1c2.tar.bz2
Git.pm: Add command_bidi_pipe and command_close_bidi_pipe
command_bidi_pipe hands back the stdin and stdout file handles from the executed command. command_close_bidi_pipe closes these handles and terminates the process. Signed-off-by: Adam Roben <aroben@apple.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'perl/Git.pm')
-rw-r--r--perl/Git.pm56
1 files changed, 56 insertions, 0 deletions
diff --git a/perl/Git.pm b/perl/Git.pm
index 2e7f896..d766974 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,6 +51,7 @@ require Exporter;
# Methods which can be called as standalone functions as well:
@EXPORT_OK = qw(command command_oneline command_noisy
command_output_pipe command_input_pipe command_close_pipe
+ command_bidi_pipe command_close_bidi_pipe
version exec_path hash_object git_cmd_try);
@@ -92,6 +93,7 @@ increate nonwithstanding).
use Carp qw(carp croak); # but croak is bad - throw instead
use Error qw(:try);
use Cwd qw(abs_path);
+use IPC::Open2 qw(open2);
}
@@ -375,6 +377,60 @@ sub command_close_pipe {
_cmd_close($fh, $ctx);
}
+=item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command_output_pipe()
+does but return both an input pipe filehandle and an output pipe filehandle.
+
+The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
+See C<command_close_bidi_pipe()> for details.
+
+=cut
+
+sub command_bidi_pipe {
+ my ($pid, $in, $out);
+ $pid = open2($in, $out, 'git', @_);
+ return ($pid, $in, $out, join(' ', @_));
+}
+
+=item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )
+
+Close the C<PIPE_IN> and C<PIPE_OUT> as returned from C<command_bidi_pipe()>,
+checking whether the command finished successfully. The optional C<CTX>
+argument is required if you want to see the command name in the error message,
+and it is the fourth value returned by C<command_bidi_pipe()>. The call idiom
+is:
+
+ my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
+ print "000000000\n" $out;
+ while (<$in>) { ... }
+ $r->command_close_bidi_pipe($pid, $in, $out, $ctx);
+
+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.
+
+=cut
+
+sub command_close_bidi_pipe {
+ my ($pid, $in, $out, $ctx) = @_;
+ foreach my $fh ($in, $out) {
+ unless (close $fh) {
+ if ($!) {
+ carp "error closing pipe: $!";
+ } elsif ($? >> 8) {
+ throw Git::Error::Command($ctx, $? >>8);
+ }
+ }
+ }
+
+ waitpid $pid, 0;
+
+ if ($? >> 8) {
+ throw Git::Error::Command($ctx, $? >>8);
+ }
+}
+
=item command_noisy ( COMMAND [, ARGUMENTS... ] )