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 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 6     6   5646 use warnings;
  6         12  
  6         201  
6 6     6   32 use strict;
  6         12  
  6         268  
7              
8             package IOMux::Pipe::Write;
9 6     6   31 use vars '$VERSION';
  6         10  
  6         313  
10             $VERSION = '0.12';
11              
12 6     6   35 use base 'IOMux::Handler::Write';
  6         31  
  6         1506  
13              
14 6     6   37 use Log::Report 'iomux';
  6         14  
  6         36  
15 6     6   1575 use Fcntl;
  6         11  
  6         2526  
16 6     6   35 use POSIX qw/:errno_h :sys_wait_h/;
  6         9  
  6         42  
17 6     6   3458 use File::Spec ();
  6         13  
  6         142  
18 6     6   32 use File::Basename 'basename';
  6         11  
  6         285  
19              
20 6     6   33 use constant PIPE_BUF_SIZE => 4096;
  6         13  
  6         4058  
21              
22              
23             sub init($)
24 3     3 0 9 { my ($self, $args) = @_;
25              
26 3 50       15 my $command = $args->{command}
27             or error __x"no command to run specified in {pkg}", pkg => __PACKAGE__;
28              
29 3 50       21 my ($cmd, @cmdopts) = ref $command eq 'ARRAY' ? @$command : $command;
30 3         174 my $name = $args->{name} = '|'.(basename $cmd);
31              
32 3         9 my ($rh, $wh);
33 3 50       120 pipe $rh, $wh
34             or fault __x"cannot create pipe for {cmd}", cmd => $name;
35              
36 3         3516 my $pid = fork;
37 3 50       257 defined $pid
38             or fault __x"failed to fork for pipe {cmd}", cmd => $name;
39              
40 3 100       112 if($pid==0)
41             { # client
42 1         54 close $wh;
43 1 50       194 open STDIN, '<&', $rh
44             or fault __x"failed to redirect STDIN for pipe {cmd}", cmd => $name;
45 1         234 open STDOUT, '>', File::Spec->devnull;
46 1         49 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         124 $self->{IMPW_pid} = $pid;
52              
53             # parent
54              
55 2         54 close $rh;
56 2         66 fcntl $wh, F_SETFL, O_NONBLOCK;
57 2         38 $args->{fh} = $wh;
58              
59 2         202 $self->SUPER::init($args);
60 2         138 $self;
61             }
62              
63              
64             sub bare($%)
65 2     2 1 14 { my ($class, %args) = @_;
66 2         8 my $self = bless {}, $class;
67              
68 2         4 my ($rh, $wh);
69 2 50       76 pipe $rh, $wh
70             or fault __x"cannot create bare pipe writer";
71              
72 2   50     12 $args{read_size} ||= 4096;
73              
74 2         10 fcntl $wh, F_SETFL, O_NONBLOCK;
75 2         6 $args{fh} = $wh;
76              
77 2         20 $self->SUPER::init(\%args);
78 2         6 ($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 24 { my ($self, $cb) = @_;
98 4 100       46 my $pid = $self->{IMPW_pid}
99             or return $self->SUPER::close($cb);
100              
101 2         20 waitpid $pid, WNOHANG;
102 2         24 local $?;
103 2         30 $self->SUPER::close($cb);
104             }
105              
106              
107              
108             1;