File Coverage

blib/lib/Siebel/Srvrmgr/IPC.pm
Criterion Covered Total %
statement 30 52 57.6
branch 3 14 21.4
condition n/a
subroutine 10 13 76.9
pod 2 2 100.0
total 45 81 55.5


line stmt bran cond sub pod time code
1             package Siebel::Srvrmgr::IPC;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Siebel::Srvrmgr::IPC - IPC functionality for Siebel::Srvrmgr classes.
8              
9             =head1 SYNOPSIS
10              
11             use Siebel::Srvrmgr::IPC qw(safe_open3);
12              
13             my ( $pid, $write_h, $read_h, $error_h ) = safe_open3( \@params );
14              
15             =head1 DESCRIPTION
16              
17             This module exports a single function (C<safe_open3>) used for running a external program, reading it's STDOUT, STDERR and writing to STDIN by
18             using IPC.
19              
20             This module is based on L<IPC::Open3::Callback> from Lucas Theisen (see SEE ALSO section).
21              
22             =cut
23              
24             require Exporter;
25             our @ISA = qw(Exporter);
26             our @EXPORT = qw(safe_open3 check_system);
27              
28 4     4   3432 use IPC::Open3;
  4         17671  
  4         259  
29 4     4   31 use Symbol 'gensym';
  4         9  
  4         195  
30 4     4   3806 use IO::Socket;
  4         85201  
  4         19  
31 4     4   2735 use Config;
  4         9  
  4         172  
32 4     4   755 use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WIFSTOPPED);
  4         7277  
  4         55  
33 4     4   3065 use warnings;
  4         11  
  4         184  
34 4     4   23 use strict;
  4         11  
  4         2378  
35              
36             =pod
37              
38             =head1 EXPORTS
39              
40             =head2 safe_open3
41              
42             C<safe_open3> functions executes a "safe" version of L<IPC::Open3> that will execute additional processing required for using C<select> in Microsoft
43             Windows OS (if automatically detected). For other OS's, the default functionality of L<IPC::Open3> is used.
44              
45             Expects as parameter an array reference with the external program to execute, including the arguments for it.
46              
47             Returns (in this order):
48              
49             =over
50              
51             =item 1.
52              
53             The PID of the child process executing the external program.
54              
55             =item 2.
56              
57             The writer handle to the child process.
58              
59             =item 3.
60              
61             The reader handle to the child process.
62              
63             =item 4.
64              
65             The error handle for the child process.
66              
67             =back
68              
69             =cut
70              
71             sub safe_open3 {
72              
73 2 50   2 1 52 return ( $Config{osname} eq 'MSWin32' )
74             ? Siebel::Srvrmgr::IPC::_mswin_open3( $_[0] )
75             : Siebel::Srvrmgr::IPC::_default_open3( $_[0] );
76              
77             }
78              
79             sub _mswin_open3 {
80              
81 0     0   0 my $cmd_ref = shift;
82              
83 0         0 my ( $inRead, $inWrite ) = Siebel::Srvrmgr::IPC::_mswin_pipe();
84 0         0 my ( $outRead, $outWrite ) = Siebel::Srvrmgr::IPC::_mswin_pipe();
85 0         0 my ( $errRead, $errWrite ) = Siebel::Srvrmgr::IPC::_mswin_pipe();
86              
87             my $pid = open3(
88             '>&' . fileno($inRead),
89             '<&' . fileno($outWrite),
90             '<&' . fileno($errWrite),
91 0         0 @{$cmd_ref}
  0         0  
92             );
93              
94 0         0 return ( $pid, $inWrite, $outRead, $errRead );
95             }
96              
97             sub _mswin_pipe {
98              
99 0     0   0 my ( $read, $write ) =
100             IO::Socket->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC );
101              
102 0         0 Siebel::Srvrmgr::IPC::_check_shutdown( 'read', $read->shutdown(SHUT_WR) )
103             ; # No more writing for reader
104 0         0 Siebel::Srvrmgr::IPC::_check_shutdown( 'write', $write->shutdown(SHUT_RD) )
105             ; # No more reading for writer
106              
107 0         0 return ( $read, $write );
108              
109             }
110              
111             sub _check_shutdown {
112              
113 0     0   0 my $which = shift; # which handle name will be partly shutdown
114 0         0 my $ret = shift;
115              
116 0 0       0 unless ( defined($ret) ) {
117              
118 0         0 die "first argument of shutdown($which) is not a valid filehandle";
119              
120             }
121             else {
122              
123 0 0       0 die "An error ocurred when trying shutdown($which): $!"
124             if ( $ret == 0 );
125              
126             }
127              
128             }
129              
130             sub _default_open3 {
131              
132 2     2   7 my $cmd_ref = shift;
133              
134 2         16 my ( $inFh, $outFh, $errFh ) = ( gensym(), gensym(), gensym() );
135 2         79 return ( open3( $inFh, $outFh, $errFh, @{$cmd_ref} ), $inFh, $outFh,
  2         26  
136             $errFh );
137             }
138              
139             =head2 check_system
140              
141             For non-Windows systems, returns additional information about the child process created by a C<system> call as a string. Also, it returns a boolean (in Perl sense)
142             indicating if this is a error (1) or not (0);
143              
144             Expects as parameter the environment variable C<${^CHILD_ERROR_NATIVE}> value, available right after the C<system> call.
145              
146             =cut
147              
148             # :TODO:22-09-2014 13:26:35:: should implement exceptions to this
149             sub check_system {
150              
151 3     3 1 18 my $child_error = shift;
152              
153 3 50       185 unless ( $Config{osname} eq 'MSWin32' ) {
154              
155 3 50       53 if ( WIFEXITED($child_error) ) {
156              
157             return
158 3         106 'Child process terminate with call to exit() with return code = '
159             . WEXITSTATUS($child_error), 0;
160              
161             }
162              
163 0 0         if ( WIFSIGNALED($child_error) ) {
164              
165 0           return 'Child process terminated due signal: '
166             . WTERMSIG($child_error), 1;
167              
168             }
169              
170 0 0         if ( WIFSTOPPED($child_error) ) {
171              
172 0           return 'Child process was stopped with ' . WSTOPSIG($child_error),
173             1;
174              
175             }
176             else {
177              
178 0           return 'Not able to check child process information', undef;
179              
180             }
181              
182             }
183             else {
184              
185 0           return undef, undef;
186              
187             }
188              
189             }
190              
191             =pod
192              
193             =head1 SEE ALSO
194              
195             =over
196              
197             =item *
198              
199             L<https://github.com/lucastheisen/ipc-open3-callback>
200              
201             =item *
202              
203             L<IPC::Open3>
204              
205             =item *
206              
207             L<IO::Socket>
208              
209             =back
210              
211             =head1 AUTHOR
212              
213             Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>
214              
215             =head1 COPYRIGHT AND LICENSE
216              
217             This software is copyright (c) 2013 of Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>
218              
219             This file is part of Siebel Monitoring Tools.
220              
221             Siebel Monitoring Tools is free software: you can redistribute it and/or modify
222             it under the terms of the GNU General Public License as published by
223             the Free Software Foundation, either version 3 of the License, or
224             (at your option) any later version.
225              
226             Siebel Monitoring Tools is distributed in the hope that it will be useful,
227             but WITHOUT ANY WARRANTY; without even the implied warranty of
228             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
229             GNU General Public License for more details.
230              
231             You should have received a copy of the GNU General Public License
232             along with Siebel Monitoring Tools. If not, see <http://www.gnu.org/licenses/>.
233              
234             =cut
235              
236             1;