File Coverage

blib/lib/Protocol/ACME/OpenSSL.pm
Criterion Covered Total %
statement 44 54 81.4
branch 13 28 46.4
condition n/a
subroutine 5 5 100.0
pod 0 2 0.0
total 62 89 69.6


line stmt bran cond sub pod time code
1             package Protocol::ACME::OpenSSL;
2              
3 4     4   1082 use strict;
  4         8  
  4         139  
4 4     4   25 use warnings;
  4         7  
  4         2639  
5              
6             our $VERSION = '0.16';
7              
8             sub new
9             {
10 3     3 0 9 my ( $class, $openssl_bin ) = @_;
11              
12 3         42 return bless { _bin => $openssl_bin }, $class;
13             }
14              
15             sub run
16             {
17 5     5 0 24 my ($self, %opts) = @_;
18              
19 5         8 my @cmd = @{ $opts{'command'} };
  5         20  
20              
21 5         82 local( $!, $^E );
22              
23 5 50       28 my ($crdr, $pwtr) = _pipe_or_die() if length $opts{'stdin'};
24              
25 5         10 my ($perr, $cerr) = _pipe_or_die();
26 5         10 my ($prdr, $cwtr) = _pipe_or_die();
27              
28 5         14906 my $pid = fork();
29 5 100       154 if (!$pid)
30             {
31 2 50       98 die "Failed to fork(): $!" if !defined $pid;
32              
33 2         68 close $pwtr;
34 2         35 close $perr;
35 2         27 close $prdr;
36              
37 2 50       48 if (length $opts{'stdin'})
38             {
39             open \*STDIN, '<&=' . fileno($crdr) or do
40 2 50       239 {
41 0         0 warn "dup STDIN failed: $!";
42 0         0 exit $!;
43             };
44             }
45              
46             open \*STDOUT, '>&=' . fileno($cwtr) or do
47 2 50       90 {
48 0         0 warn "dup STDOUT failed: $!";
49 0         0 exit $!;
50             };
51              
52             open \*STDERR, '>&=' . fileno($cerr) or do
53 2 50       66 {
54 0         0 warn "dup STDERR failed: $!";
55 0         0 exit $!;
56             };
57              
58 2         0 exec {$self->{_bin}} $self->{_bin}, @cmd or do
59 2 0       20 {
60 0         0 warn "exec($self->{_bin}) failed: $!";
61 0         0 exit $!;
62             };
63             }
64              
65 3         73 close $crdr;
66 3         87 close $cwtr;
67 3         30 close $cerr;
68              
69 3 50       53 if (length $opts{'stdin'})
70             {
71 3 50       9 print {$pwtr} $opts{'stdin'} or die "Failed to write to $self->{_bin}: $!";
  3         83  
72             }
73              
74 3 50       61 close $pwtr or die "close() on pipe to $self->{_bin} failed: $!";
75              
76 3         45 my ($output, $error) = ( q<>, q<> );
77 3         2236563 $output .= $_ while <$prdr>;
78 3         93 $error .= $_ while <$perr>;
79              
80 3         74 close $prdr;
81 3         22 close $perr;
82              
83 3         118 waitpid $pid, 0;
84              
85 3 50       37 if ($?)
86             {
87 0 0       0 my $failure = ($? & 0xff) ? "signal $?" : sprintf("error %d", $? >> 8);
88 0         0 die "$error\n$self->{_bin} failed: $failure";
89             }
90              
91 3         250 return $output;
92             }
93              
94             sub _pipe_or_die
95             {
96 15 50   15   223 pipe( my ($rdr, $wtr) ) or die "pipe() failed $!";
97              
98 15         28 return ($rdr, $wtr);
99             }
100              
101             1; # End of Protocol::ACME::OpenSSL