File Coverage

lib/IOMux/Pipe/Write.pm
Criterion Covered Total %
statement 64 68 94.1
branch 10 20 50.0
condition 1 2 50.0
subroutine 13 16 81.2
pod 5 6 83.3
total 93 112 83.0


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 6     6   5965 use warnings;
  6         9  
  6         180  
6 6     6   25 use strict;
  6         11  
  6         190  
7              
8             package IOMux::Pipe::Write;
9 6     6   29 use vars '$VERSION';
  6         10  
  6         279  
10             $VERSION = '1.00';
11              
12 6     6   30 use base 'IOMux::Handler::Write';
  6         9  
  6         1364  
13              
14 6     6   33 use Log::Report 'iomux';
  6         11  
  6         35  
15 6     6   1439 use Fcntl;
  6         6  
  6         1935  
16 6     6   33 use POSIX qw/:errno_h :sys_wait_h/;
  6         12  
  6         41  
17 6     6   2923 use File::Spec ();
  6         12  
  6         110  
18 6     6   33 use File::Basename 'basename';
  6         6  
  6         290  
19              
20 6     6   31 use constant PIPE_BUF_SIZE => 4096;
  6         9  
  6         3874  
21              
22              
23             sub init($)
24 3     3 0 9 { my ($self, $args) = @_;
25              
26             my $command = $args->{command}
27 3 50       21 or error __x"no command to run specified in {pkg}", pkg => __PACKAGE__;
28              
29 3 50       27 my ($cmd, @cmdopts) = ref $command eq 'ARRAY' ? @$command : $command;
30 3         183 my $name = $args->{name} = '|'.(basename $cmd);
31              
32 3         6 my ($rh, $wh);
33 3 50       111 pipe $rh, $wh
34             or fault __x"cannot create pipe for {cmd}", cmd => $name;
35              
36 3         4842 my $pid = fork;
37 3 50       342 defined $pid
38             or fault __x"failed to fork for pipe {cmd}", cmd => $name;
39              
40 3 100       121 if($pid==0)
41             { # client
42 1         96 close $wh;
43 1 50       252 open STDIN, '<&', $rh
44             or fault __x"failed to redirect STDIN for pipe {cmd}", cmd => $name;
45 1         304 open STDOUT, '>', File::Spec->devnull;
46 1         61 open STDERR, '>', File::Spec->devnull;
47              
48 1 0       0 exec $cmd, @cmdopts
49             or fault __x"failed to exec for pipe {cmd}", cmd => $name;
50             }
51 2         212 $self->{IMPW_pid} = $pid;
52              
53             # parent
54              
55 2         68 close $rh;
56 2         44 fcntl $wh, F_SETFL, O_NONBLOCK;
57 2         36 $args->{fh} = $wh;
58              
59 2         206 $self->SUPER::init($args);
60 2         130 $self;
61             }
62              
63              
64             sub bare($%)
65 2     2 1 8 { my ($class, %args) = @_;
66 2         4 my $self = bless {}, $class;
67              
68 2         4 my ($rh, $wh);
69 2 50       54 pipe $rh, $wh
70             or fault __x"cannot create bare pipe writer";
71              
72 2   50     12 $args{read_size} ||= 4096;
73              
74 2         8 fcntl $wh, F_SETFL, O_NONBLOCK;
75 2         4 $args{fh} = $wh;
76              
77 2         16 $self->SUPER::init(\%args);
78 2         8 ($self, $rh);
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->{IMPW_mode}}
92 0     0 1 0 sub childPid() {shift->{IMPW_pid}}
93              
94             #-------------------
95              
96             sub close($)
97 4     4 1 17 { my ($self, $cb) = @_;
98             my $pid = $self->{IMPW_pid}
99 4 100       72 or return $self->SUPER::close($cb);
100              
101 2         12 waitpid $pid, WNOHANG;
102 2         24 local $?;
103 2         32 $self->SUPER::close($cb);
104             }
105              
106              
107              
108             1;