@@ -51,6 +51,7 @@ require Exporter;
5151# Methods which can be called as standalone functions as well:
5252@EXPORT_OK = qw( command command_oneline command_noisy
5353 command_output_pipe command_input_pipe command_close_pipe
54+ command_bidi_pipe command_close_bidi_pipe
5455 version exec_path hash_object git_cmd_try) ;
5556
5657
@@ -92,6 +93,7 @@ increate nonwithstanding).
9293use Carp qw( carp croak) ; # but croak is bad - throw instead
9394use Error qw( :try) ;
9495use Cwd qw( abs_path) ;
96+ use IPC::Open2 qw( open2) ;
9597
9698}
9799
@@ -375,6 +377,60 @@ sub command_close_pipe {
375377 _cmd_close($fh , $ctx );
376378}
377379
380+ =item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )
381+
382+ Execute the given C<COMMAND > in the same way as command_output_pipe()
383+ does but return both an input pipe filehandle and an output pipe filehandle.
384+
385+ The function will return return C<($pid, $pipe_in, $pipe_out, $ctx) > .
386+ See C<command_close_bidi_pipe() > for details.
387+
388+ =cut
389+
390+ sub command_bidi_pipe {
391+ my ($pid , $in , $out );
392+ $pid = open2($in , $out , ' git' , @_ );
393+ return ($pid , $in , $out , join (' ' , @_ ));
394+ }
395+
396+ =item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )
397+
398+ Close the C<PIPE_IN > and C<PIPE_OUT > as returned from C<command_bidi_pipe() > ,
399+ checking whether the command finished successfully. The optional C<CTX >
400+ argument is required if you want to see the command name in the error message,
401+ and it is the fourth value returned by C<command_bidi_pipe() > . The call idiom
402+ is:
403+
404+ my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
405+ print "000000000\n" $out;
406+ while (<$in>) { ... }
407+ $r->command_close_bidi_pipe($pid, $in, $out, $ctx);
408+
409+ Note that you should not rely on whatever actually is in C<CTX > ;
410+ currently it is simply the command name but in future the context might
411+ have more complicated structure.
412+
413+ =cut
414+
415+ sub command_close_bidi_pipe {
416+ my ($pid , $in , $out , $ctx ) = @_ ;
417+ foreach my $fh ($in , $out ) {
418+ unless (close $fh ) {
419+ if ($! ) {
420+ carp " error closing pipe: $! " ;
421+ } elsif ($? >> 8) {
422+ throw Git::Error::Command($ctx , $? >>8);
423+ }
424+ }
425+ }
426+
427+ waitpid $pid , 0;
428+
429+ if ($? >> 8) {
430+ throw Git::Error::Command($ctx , $? >>8);
431+ }
432+ }
433+
378434
379435=item command_noisy ( COMMAND [, ARGUMENTS... ] )
380436
0 commit comments