File Coverage

blib/lib/Siebel/Srvrmgr/IPC.pm
Criterion Covered Total %
statement 38 59 64.4
branch 5 16 31.2
condition n/a
subroutine 12 15 80.0
pod 2 2 100.0
total 57 92 61.9


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