use POSIX qw(dup2);
require IO::Handle;
use PublicInbox::Spawn qw(spawn popen_rd);
+use IO::File;
+use Fcntl qw(:seek);
# Documentation/SubmittingPatches recommends 12 (Linux v4.4)
my $abbrev = `git config core.abbrev` || 12;
sub new {
my ($class, $git_dir) = @_;
- bless { git_dir => $git_dir }, $class
+ bless { git_dir => $git_dir, err => IO::File->new_tmpfile }, $class
+}
+
+sub err_begin ($) {
+ my $err = $_[0]->{err};
+ sysseek($err, 0, SEEK_SET) or die "sysseek failed: $!";
+ truncate($err, 0) or die "truncate failed: $!";
+ my $ret = fileno($err);
+ defined $ret or die "fileno failed: $!";
+ $ret;
+}
+
+sub err ($) {
+ my $err = $_[0]->{err};
+ sysseek($err, 0, SEEK_SET) or die "sysseek failed: $!";
+ defined(sysread($err, my $buf, -s $err)) or die "sysread failed: $!";
+ sysseek($err, 0, SEEK_SET) or die "sysseek failed: $!";
+ truncate($err, 0) or die "truncate failed: $!";
+ $buf;
}
sub _bidi_pipe {
{
my $git = PublicInbox::Git->new($dir);
- open my $tmperr, '>&', \*STDERR or die "dup stderr failed: $!\n";
- open STDERR, '>', '/dev/null' or die "redirect stderr failed: $!\n";
- my $err = $git->popen(qw(cat-file blob non-existent));
+ my $err = $git->popen([qw(cat-file blob non-existent)], undef,
+ { 2 => $git->err_begin });
my @out = <$err>;
my $close_ret = close $err;
my $close_err = $?;
- open STDERR, '>&', $tmperr or die "restore stderr failed: $!\n";
is(join('', @out), '', 'no output on stdout on error');
isnt($close_err, 0, 'close set $? on bad command');
ok(!$close_ret, 'close returned error on bad command');
+ isnt($git->err, '', 'got stderr output');
- open STDERR, '>', '/dev/null' or die "redirect stderr failed: $!\n";
- $err = $git->popen(qw(tag -l));
+ $err = $git->popen([qw(tag -l)], undef, { 2 => $git->err_begin });
@out = <$err>;
$close_ret = close $err;
$close_err = $?;
- open STDERR, '>&', $tmperr or die "restore stderr failed: $!\n";
is(join('', @out), '', 'no output on stdout on error');
ok(!$close_err, 'close clobbered $? on empty output');
ok($close_ret, 'close returned error on empty output');
+ is($git->err, '', 'no stderr output');
}
done_testing();