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-2020 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             # This code is part of distribution IOMux. Meta-POD processed with OODoc
6             # into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package IOMux::Pipe::Write;
10 6     6   5399 use vars '$VERSION';
  6         10  
  6         290  
11             $VERSION = '1.01';
12              
13 6     6   30 use base 'IOMux::Handler::Write';
  6         6  
  6         1333  
14              
15 6     6   34 use warnings;
  6         6  
  6         167  
16 6     6   30 use strict;
  6         9  
  6         114  
17              
18 6     6   48 use Log::Report 'iomux';
  6         9  
  6         26  
19 6     6   1275 use Fcntl;
  6         9  
  6         1250  
20 6     6   38 use POSIX qw/:errno_h :sys_wait_h/;
  6         9  
  6         25  
21 6     6   1969 use File::Spec ();
  6         9  
  6         140  
22 6     6   41 use File::Basename 'basename';
  6         10  
  6         269  
23              
24 6     6   32 use constant PIPE_BUF_SIZE => 4096;
  6         7  
  6         3408  
25              
26              
27             sub init($)
28 3     3 0 9 { my ($self, $args) = @_;
29              
30             my $command = $args->{command}
31 3 50       12 or error __x"no command to run specified in {pkg}", pkg => __PACKAGE__;
32              
33 3 50       15 my ($cmd, @cmdopts) = ref $command eq 'ARRAY' ? @$command : $command;
34 3         234 my $name = $args->{name} = '|'.(basename $cmd);
35              
36 3         12 my ($rh, $wh);
37 3 50       117 pipe $rh, $wh
38             or fault __x"cannot create pipe for {cmd}", cmd => $name;
39              
40 3         3970 my $pid = fork;
41 3 50       252 defined $pid
42             or fault __x"failed to fork for pipe {cmd}", cmd => $name;
43              
44 3 100       107 if($pid==0)
45             { # client
46 1         39 close $wh;
47 1 50       119 open STDIN, '<&', $rh
48             or fault __x"failed to redirect STDIN for pipe {cmd}", cmd => $name;
49 1         165 open STDOUT, '>', File::Spec->devnull;
50 1         57 open STDERR, '>', File::Spec->devnull;
51              
52 1 0       0 exec $cmd, @cmdopts
53             or fault __x"failed to exec for pipe {cmd}", cmd => $name;
54             }
55 2         204 $self->{IMPW_pid} = $pid;
56              
57             # parent
58              
59 2         54 close $rh;
60 2         38 fcntl $wh, F_SETFL, O_NONBLOCK;
61 2         30 $args->{fh} = $wh;
62              
63 2         158 $self->SUPER::init($args);
64 2         114 $self;
65             }
66              
67              
68             sub bare($%)
69 2     2 1 6 { my ($class, %args) = @_;
70 2         4 my $self = bless {}, $class;
71              
72 2         2 my ($rh, $wh);
73 2 50       66 pipe $rh, $wh
74             or fault __x"cannot create bare pipe writer";
75              
76 2   50     16 $args{read_size} ||= 4096;
77              
78 2         12 fcntl $wh, F_SETFL, O_NONBLOCK;
79 2         4 $args{fh} = $wh;
80              
81 2         14 $self->SUPER::init(\%args);
82 2         8 ($self, $rh);
83             }
84              
85              
86             sub open($$@)
87 0     0 1 0 { my ($class, $mode, $cmd) = (shift, shift, shift);
88 0 0       0 ref $cmd eq 'ARRAY'
89             ? $class->new(command => $cmd, mode => $mode, @_)
90             : $class->new(command => [$cmd, @_] , mode => $mode);
91             }
92              
93             #-------------------
94              
95 0     0 1 0 sub mode() {shift->{IMPW_mode}}
96 0     0 1 0 sub childPid() {shift->{IMPW_pid}}
97              
98             #-------------------
99              
100             sub close($)
101 4     4 1 18 { my ($self, $cb) = @_;
102             my $pid = $self->{IMPW_pid}
103 4 100       27 or return $self->SUPER::close($cb);
104              
105 2         16 waitpid $pid, WNOHANG;
106 2         24 local $?;
107 2         28 $self->SUPER::close($cb);
108             }
109              
110              
111              
112             1;