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 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 1.07.
5 3     3   5916 use warnings;
  3         6  
  3         131  
6 3     3   18 use strict;
  3         8  
  3         142  
7              
8             package IOMux::IPC;
9 3     3   16 use vars '$VERSION';
  3         6  
  3         165  
10             $VERSION = '0.12';
11              
12 3     3   18 use base 'IOMux::Bundle';
  3         4  
  3         1041  
13              
14 3     3   17 use Log::Report 'iomux';
  3         4  
  3         15  
15              
16 3     3   1651 use IOMux::Pipe::Read ();
  3         8  
  3         66  
17 3     3   822 use IOMux::Pipe::Write ();
  3         8  
  3         70  
18              
19 3     3   15 use POSIX qw/:errno_h :sys_wait_h/;
  3         7  
  3         18  
20 3     3   1945 use File::Basename 'basename';
  3         7  
  3         2095  
21              
22              
23             sub init($)
24 2     2 0 6 { my ($self, $args) = @_;
25 2 50       10 my $command = $args->{command}
26             or error __x"no command to run specified in {pkg}", pkg => __PACKAGE__;
27              
28 2 50       12 my ($cmd, @cmdopts) = ref $command eq 'ARRAY' ? @$command : $command;
29 2         126 my $name = $args->{name} = '|'.(basename $cmd).'|';
30              
31 2   50     22 my $mode = $args->{mode} || '|-|';
32 2         4 my $errors = $args->{errors};
33 2 50 0     12 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         10 ($args->{stdin}, my $in_rh)
41             = IOMux::Pipe::Write->bare(name => 'stdin');
42 2         14 ($args->{stdout}, my $out_wh)
43             = IOMux::Pipe::Read->bare(name => 'stdout');
44 2 50       10 ($args->{stderr}, my $err_wh)
45             = $errors ? IOMux::Pipe::Read->bare(name => 'stderr') : ();
46              
47 2         3069 my $pid = fork;
48 2 50       235 defined $pid
49             or fault __x"failed to fork for ipc {cmd}", cmd => $name;
50              
51 2 100       111 if($pid==0)
52             { # client
53 1 50       544 open STDIN, '<&', $in_rh
54             or fault __x"failed to redirect STDIN for ipc {cmd}", cmd=>$name;
55 1 50       40 open STDOUT, '>&', $out_wh
56             or fault __x"failed to redirect STDOUT for ipc {cmd}", cmd=>$name;
57 1 50       151 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         377 { 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         49 close $in_rh;
73 1         20 close $out_wh;
74 1 50       16 close $err_wh if $err_wh;
75              
76 1         75 $self->{IMI_pid} = $pid;
77 1         154 $self->SUPER::init($args);
78 1         97 $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 1312 { my ($self, $cb) = @_;
98 1         64 waitpid $self->{IMI_pid}, WNOHANG;
99 1         8 local $?;
100 1         13 $self->SUPER::close($cb);
101             }
102              
103             1;