Skip to content

Commit d1a29af

Browse files
arobengitster
authored andcommitted
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>
1 parent d8ee483 commit d1a29af

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

perl/Git.pm

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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).
9293
use Carp qw(carp croak); # but croak is bad - throw instead
9394
use Error qw(:try);
9495
use 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

Comments
 (0)