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   720 use strict;
  4         5  
  4         113  
4 4     4   19 use warnings;
  4         7  
  4         3152  
5              
6             our $VERSION = '1.01';
7              
8             sub new
9             {
10 3     3 0 6 my ( $class, $openssl_bin ) = @_;
11              
12 3         36 return bless { _bin => $openssl_bin }, $class;
13             }
14              
15             sub run
16             {
17 5     5 0 21 my ($self, %opts) = @_;
18              
19 5         9 my @cmd = @{ $opts{'command'} };
  5         17  
20              
21 5         71 local( $!, $^E );
22              
23 5 50       21 my ($crdr, $pwtr) = _pipe_or_die() if length $opts{'stdin'};
24              
25 5         7 my ($perr, $cerr) = _pipe_or_die();
26 5         15 my ($prdr, $cwtr) = _pipe_or_die();
27              
28 5         7344 my $pid = fork();
29 5 100       142 if (!$pid)
30             {
31 2 50       127 die "Failed to fork(): $!" if !defined $pid;
32              
33 2         126 close $pwtr;
34 2         20 close $perr;
35 2         38 close $prdr;
36              
37 2 50       46 if (length $opts{'stdin'})
38             {
39             open \*STDIN, '<&=' . fileno($crdr) or do
40 2 50       256 {
41 0         0 warn "dup STDIN failed: $!";
42 0         0 exit $!;
43             };
44             }
45              
46             open \*STDOUT, '>&=' . fileno($cwtr) or do
47 2 50       97 {
48 0         0 warn "dup STDOUT failed: $!";
49 0         0 exit $!;
50             };
51              
52             open \*STDERR, '>&=' . fileno($cerr) or do
53 2 50       84 {
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       10 {
60 0         0 warn "exec($self->{_bin}) failed: $!";
61 0         0 exit $!;
62             };
63             }
64              
65 3         58 close $crdr;
66 3         47 close $cwtr;
67 3         26 close $cerr;
68              
69 3 50       73 if (length $opts{'stdin'})
70             {
71 3 50       13 print {$pwtr} $opts{'stdin'} or die "Failed to write to $self->{_bin}: $!";
  3         90  
72             }
73              
74 3 50       37 close $pwtr or die "close() on pipe to $self->{_bin} failed: $!";
75              
76 3         35 my ($output, $error) = ( q<>, q<> );
77 3         1328368 $output .= $_ while <$prdr>;
78 3         51 $error .= $_ while <$perr>;
79              
80 3         37 close $prdr;
81 3         19 close $perr;
82              
83 3         45 waitpid $pid, 0;
84              
85 3 50       30 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         211 return $output;
92             }
93              
94             sub _pipe_or_die
95             {
96 15 50   15   204 pipe( my ($rdr, $wtr) ) or die "pipe() failed $!";
97              
98 15         29 return ($rdr, $wtr);
99             }
100              
101             1; # End of Protocol::ACME::OpenSSL