File Coverage

lib/IOMux/IPC.pm
Criterion Covered Total %
statement 56 63 88.8
branch 13 30 43.3
condition 1 4 25.0
subroutine 11 14 78.5
pod 4 5 80.0
total 85 116 73.2


line stmt bran cond sub pod time code
1             # Copyrights 2011-2015 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5 3     3   3611 use warnings;
  3         4  
  3         90  
6 3     3   13 use strict;
  3         6  
  3         95  
7              
8             package IOMux::IPC;
9 3     3   15 use vars '$VERSION';
  3         5  
  3         136  
10             $VERSION = '1.00';
11              
12 3     3   14 use base 'IOMux::Bundle';
  3         58  
  3         803  
13              
14 3     3   21 use Log::Report 'iomux';
  3         6  
  3         18  
15              
16 3     3   1460 use IOMux::Pipe::Read ();
  3         7  
  3         59  
17 3     3   701 use IOMux::Pipe::Write ();
  3         6  
  3         62  
18              
19 3     3   17 use POSIX qw/:errno_h :sys_wait_h/;
  3         8  
  3         26  
20 3     3   1464 use File::Basename 'basename';
  3         4  
  3         1912  
21              
22              
23             sub init($)
24 2     2 0 4 { my ($self, $args) = @_;
25             my $command = $args->{command}
26 2 50       12 or error __x"no command to run specified in {pkg}", pkg => __PACKAGE__;
27              
28 2 50       10 my ($cmd, @cmdopts) = ref $command eq 'ARRAY' ? @$command : $command;
29 2         100 my $name = $args->{name} = '|'.(basename $cmd).'|';
30              
31 2   50     20 my $mode = $args->{mode} || '|-|';
32 2         4 my $errors = $args->{errors};
33 2 50 0     14 if($mode eq '|=|') { $errors //= 1 }
  0 50       0  
34 2 50       6 elsif($mode eq '|-|') { $mode = '|=|' if $errors }
35             else
36 0         0 { error __x"unknown mode {mode} for {pkg}"
37             , mode => $mode, pkg => __PACKAGE__;
38             }
39              
40 2         8 ($args->{stdin}, my $in_rh)
41             = IOMux::Pipe::Write->bare(name => 'stdin');
42 2         12 ($args->{stdout}, my $out_wh)
43             = IOMux::Pipe::Read->bare(name => 'stdout');
44 2 50       8 ($args->{stderr}, my $err_wh)
45             = $errors ? IOMux::Pipe::Read->bare(name => 'stderr') : ();
46              
47 2         3053 my $pid = fork;
48 2 50       109 defined $pid
49             or fault __x"failed to fork for ipc {cmd}", cmd => $name;
50              
51 2 100       61 if($pid==0)
52             { # client
53 1 50       150 open STDIN, '<&', $in_rh
54             or fault __x"failed to redirect STDIN for ipc {cmd}", cmd=>$name;
55 1 50       25 open STDOUT, '>&', $out_wh
56             or fault __x"failed to redirect STDOUT for ipc {cmd}", cmd=>$name;
57 1 50       45 if($err_wh)
58 0 0       0 { open STDERR, '>&', $err_wh
59             or fault __x"failed to redirect STDERR for ipc {cmd}"
60             , cmd => $name;
61             }
62             else
63 1         197 { open STDERR, '>', File::Spec->devnull;
64             }
65              
66 1 0       0 exec $cmd, @cmdopts
67             or fault __x"failed to exec for pipe {cmd}", cmd => $name;
68             }
69              
70             # parent
71              
72 1         29 close $in_rh;
73 1         17 close $out_wh;
74 1 50       16 close $err_wh if $err_wh;
75              
76 1         68 $self->{IMI_pid} = $pid;
77 1         142 $self->SUPER::init($args);
78 1         72 $self;
79             }
80              
81              
82             sub open($$@)
83 0     0 1 0 { my ($class, $mode, $cmd) = (shift, shift, shift);
84 0 0       0 ref $cmd eq 'ARRAY'
85             ? $class->new(command => $cmd, mode => $mode, @_)
86             : $class->new(command => [$cmd, @_] , mode => $mode);
87             }
88              
89             #-------------------
90              
91 0     0 1 0 sub mode() {shift->{IMI_mode}}
92 0     0 1 0 sub childPid() {shift->{IMI_pid}}
93              
94             #-------------------
95              
96             sub close($)
97 1     1 1 1659 { my ($self, $cb) = @_;
98 1         39 waitpid $self->{IMI_pid}, WNOHANG;
99 1         10 local $?;
100 1         19 $self->SUPER::close($cb);
101             }
102              
103             1;