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; |