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