line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test2::Util; |
2
|
247
|
|
|
247
|
|
12086
|
use strict; |
|
247
|
|
|
|
|
571
|
|
|
247
|
|
|
|
|
6998
|
|
3
|
247
|
|
|
247
|
|
1236
|
use warnings; |
|
247
|
|
|
|
|
444
|
|
|
247
|
|
|
|
|
9074
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '1.302181'; |
6
|
|
|
|
|
|
|
|
7
|
247
|
|
|
247
|
|
127004
|
use POSIX(); |
|
247
|
|
|
|
|
2001687
|
|
|
247
|
|
|
|
|
8060
|
|
8
|
247
|
|
|
247
|
|
1728
|
use Config qw/%Config/; |
|
247
|
|
|
|
|
441
|
|
|
247
|
|
|
|
|
12280
|
|
9
|
247
|
|
|
247
|
|
1473
|
use Carp qw/croak/; |
|
247
|
|
|
|
|
441
|
|
|
247
|
|
|
|
|
26742
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
BEGIN { |
12
|
247
|
|
|
247
|
|
2844
|
local ($@, $!, $SIG{__DIE__}); |
13
|
247
|
50
|
|
|
|
595
|
*HAVE_PERLIO = eval { require PerlIO; PerlIO->VERSION(1.02); } ? sub() { 1 } : sub() { 0 }; |
|
247
|
|
|
|
|
149668
|
|
|
247
|
|
|
|
|
26257
|
|
14
|
|
|
|
|
|
|
} |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our @EXPORT_OK = qw{ |
17
|
|
|
|
|
|
|
try |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
pkg_to_file |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
get_tid USE_THREADS |
22
|
|
|
|
|
|
|
CAN_THREAD |
23
|
|
|
|
|
|
|
CAN_REALLY_FORK |
24
|
|
|
|
|
|
|
CAN_FORK |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
CAN_SIGSYS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
IS_WIN32 |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
ipc_separator |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
gen_uid |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
do_rename do_unlink |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
try_sig_mask |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
clone_io |
39
|
|
|
|
|
|
|
}; |
40
|
247
|
|
|
247
|
|
1584
|
BEGIN { require Exporter; our @ISA = qw(Exporter) } |
|
247
|
|
|
|
|
17916
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
BEGIN { |
43
|
247
|
50
|
|
247
|
|
55321
|
*IS_WIN32 = ($^O eq 'MSWin32') ? sub() { 1 } : sub() { 0 }; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub _can_thread { |
47
|
247
|
50
|
|
247
|
|
1320
|
return 0 unless $] >= 5.008001; |
48
|
247
|
50
|
|
|
|
20181
|
return 0 unless $Config{'useithreads'}; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Threads are broken on perl 5.10.0 built with gcc 4.8+ |
51
|
0
|
0
|
0
|
|
|
0
|
if ($] == 5.010000 && $Config{'ccname'} eq 'gcc' && $Config{'gccversion'}) { |
|
|
|
0
|
|
|
|
|
52
|
0
|
|
|
|
|
0
|
my @parts = split /\./, $Config{'gccversion'}; |
53
|
0
|
0
|
0
|
|
|
0
|
return 0 if $parts[0] > 4 || ($parts[0] == 4 && $parts[1] >= 8); |
|
|
|
0
|
|
|
|
|
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Change to a version check if this ever changes |
57
|
0
|
0
|
|
|
|
0
|
return 0 if $INC{'Devel/Cover.pm'}; |
58
|
0
|
|
|
|
|
0
|
return 1; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub _can_fork { |
62
|
27
|
50
|
|
27
|
|
1914
|
return 1 if $Config{d_fork}; |
63
|
0
|
0
|
|
|
|
0
|
return 0 unless IS_WIN32 || $^O eq 'NetWare'; |
64
|
0
|
0
|
|
|
|
0
|
return 0 unless $Config{useithreads}; |
65
|
0
|
0
|
|
|
|
0
|
return 0 unless $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/; |
66
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
0
|
return _can_thread(); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
BEGIN { |
71
|
247
|
|
|
247
|
|
1868
|
no warnings 'once'; |
|
247
|
|
|
|
|
640
|
|
|
247
|
|
|
|
|
20569
|
|
72
|
247
|
50
|
|
247
|
|
1046
|
*CAN_THREAD = _can_thread() ? sub() { 1 } : sub() { 0 }; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
my $can_fork; |
75
|
|
|
|
|
|
|
sub CAN_FORK () { |
76
|
39
|
100
|
|
39
|
1
|
1486
|
return $can_fork |
77
|
|
|
|
|
|
|
if defined $can_fork; |
78
|
27
|
|
|
|
|
298
|
$can_fork = !!_can_fork(); |
79
|
247
|
|
|
247
|
|
1798
|
no warnings 'redefine'; |
|
247
|
|
|
|
|
603
|
|
|
247
|
|
|
|
|
30135
|
|
80
|
27
|
50
|
|
|
|
617
|
*CAN_FORK = $can_fork ? sub() { 1 } : sub() { 0 }; |
81
|
27
|
|
|
|
|
187
|
$can_fork; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
my $can_really_fork; |
84
|
|
|
|
|
|
|
sub CAN_REALLY_FORK () { |
85
|
24
|
100
|
|
24
|
1
|
223
|
return $can_really_fork |
86
|
|
|
|
|
|
|
if defined $can_really_fork; |
87
|
17
|
|
|
|
|
945
|
$can_really_fork = !!$Config{d_fork}; |
88
|
247
|
|
|
247
|
|
1692
|
no warnings 'redefine'; |
|
247
|
|
|
|
|
516
|
|
|
247
|
|
|
|
|
57493
|
|
89
|
17
|
50
|
|
|
|
164
|
*CAN_REALLY_FORK = $can_really_fork ? sub() { 1 } : sub() { 0 }; |
90
|
17
|
|
|
|
|
59
|
$can_really_fork; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub _manual_try(&;@) { |
94
|
2
|
|
|
2
|
|
19
|
my $code = shift; |
95
|
2
|
|
|
|
|
5
|
my $args = \@_; |
96
|
2
|
|
|
|
|
3
|
my $err; |
97
|
|
|
|
|
|
|
|
98
|
2
|
|
|
|
|
10
|
my $die = delete $SIG{__DIE__}; |
99
|
|
|
|
|
|
|
|
100
|
2
|
100
|
50
|
|
|
5
|
eval { $code->(@$args); 1 } or $err = $@ || "Error was squashed!\n"; |
|
2
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
4
|
|
101
|
|
|
|
|
|
|
|
102
|
2
|
50
|
|
|
|
18
|
$die ? $SIG{__DIE__} = $die : delete $SIG{__DIE__}; |
103
|
|
|
|
|
|
|
|
104
|
2
|
|
|
|
|
9
|
return (!defined($err), $err); |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _local_try(&;@) { |
108
|
218
|
|
|
218
|
|
2762
|
my $code = shift; |
109
|
218
|
|
|
|
|
508
|
my $args = \@_; |
110
|
218
|
|
|
|
|
403
|
my $err; |
111
|
|
|
|
|
|
|
|
112
|
247
|
|
|
247
|
|
1794
|
no warnings; |
|
247
|
|
|
|
|
523
|
|
|
247
|
|
|
|
|
37633
|
|
113
|
218
|
|
|
|
|
1138
|
local $SIG{__DIE__}; |
114
|
218
|
100
|
50
|
|
|
472
|
eval { $code->(@$args); 1 } or $err = $@ || "Error was squashed!\n"; |
|
218
|
|
|
|
|
743
|
|
|
207
|
|
|
|
|
1174
|
|
115
|
|
|
|
|
|
|
|
116
|
218
|
|
|
|
|
2402
|
return (!defined($err), $err); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# Older versions of perl have a nasty bug on win32 when localizing a variable |
120
|
|
|
|
|
|
|
# before forking or starting a new thread. So for those systems we use the |
121
|
|
|
|
|
|
|
# non-local form. When possible though we use the faster 'local' form. |
122
|
|
|
|
|
|
|
BEGIN { |
123
|
247
|
|
|
247
|
|
1966
|
if (IS_WIN32 && $] < 5.020002) { |
124
|
|
|
|
|
|
|
*try = \&_manual_try; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
else { |
127
|
247
|
|
|
|
|
48349
|
*try = \&_local_try; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
BEGIN { |
132
|
247
|
|
|
247
|
|
877
|
if (CAN_THREAD) { |
133
|
|
|
|
|
|
|
if ($INC{'threads.pm'}) { |
134
|
|
|
|
|
|
|
# Threads are already loaded, so we do not need to check if they |
135
|
|
|
|
|
|
|
# are loaded each time |
136
|
|
|
|
|
|
|
*USE_THREADS = sub() { 1 }; |
137
|
|
|
|
|
|
|
*get_tid = sub() { threads->tid() }; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
else { |
140
|
|
|
|
|
|
|
# :-( Need to check each time to see if they have been loaded. |
141
|
|
|
|
|
|
|
*USE_THREADS = sub() { $INC{'threads.pm'} ? 1 : 0 }; |
142
|
|
|
|
|
|
|
*get_tid = sub() { $INC{'threads.pm'} ? threads->tid() : 0 }; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
else { |
146
|
|
|
|
|
|
|
# No threads, not now, not ever! |
147
|
247
|
|
|
|
|
651
|
*USE_THREADS = sub() { 0 }; |
148
|
247
|
|
|
|
|
64420
|
*get_tid = sub() { 0 }; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub pkg_to_file { |
153
|
844
|
|
|
844
|
1
|
1404
|
my $pkg = shift; |
154
|
844
|
|
|
|
|
1287
|
my $file = $pkg; |
155
|
844
|
|
|
|
|
5281
|
$file =~ s{(::|')}{/}g; |
156
|
844
|
|
|
|
|
1649
|
$file .= '.pm'; |
157
|
844
|
|
|
|
|
2125
|
return $file; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub ipc_separator() { "~" } |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
my $UID = 1; |
163
|
15120
|
|
|
15120
|
1
|
151701
|
sub gen_uid() { join ipc_separator() => ($$, get_tid(), time, $UID++) } |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub _check_for_sig_sys { |
166
|
252
|
|
|
252
|
|
25678
|
my $sig_list = shift; |
167
|
252
|
|
|
|
|
2283
|
return $sig_list =~ m/\bSYS\b/; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
BEGIN { |
171
|
247
|
50
|
|
247
|
|
1622
|
if (_check_for_sig_sys($Config{sig_name})) { |
172
|
247
|
|
|
|
|
139516
|
*CAN_SIGSYS = sub() { 1 }; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
else { |
175
|
0
|
|
|
|
|
0
|
*CAN_SIGSYS = sub() { 0 }; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
my %PERLIO_SKIP = ( |
180
|
|
|
|
|
|
|
unix => 1, |
181
|
|
|
|
|
|
|
via => 1, |
182
|
|
|
|
|
|
|
); |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub clone_io { |
185
|
1200
|
|
|
1200
|
0
|
4532
|
my ($fh) = @_; |
186
|
1200
|
|
|
|
|
2943
|
my $fileno = eval { fileno($fh) }; |
|
1200
|
|
|
|
|
4035
|
|
187
|
|
|
|
|
|
|
|
188
|
1200
|
100
|
33
|
|
|
9594
|
return $fh if !defined($fileno) || !length($fileno) || $fileno < 0; |
|
|
|
66
|
|
|
|
|
189
|
|
|
|
|
|
|
|
190
|
1199
|
50
|
|
|
|
34025
|
open(my $out, '>&' . $fileno) or die "Can't dup fileno $fileno: $!"; |
191
|
|
|
|
|
|
|
|
192
|
1199
|
|
|
|
|
3661
|
my %seen; |
193
|
1199
|
|
100
|
|
|
9269
|
my @layers = HAVE_PERLIO ? grep { !$PERLIO_SKIP{$_} and !$seen{$_}++ } PerlIO::get_layers($fh) : (); |
|
3112
|
|
|
|
|
16853
|
|
194
|
1199
|
|
|
|
|
13033
|
binmode($out, join(":", "", "raw", @layers)); |
195
|
|
|
|
|
|
|
|
196
|
1199
|
|
|
|
|
6150
|
my $old = select $fh; |
197
|
1199
|
|
|
|
|
3800
|
my $af = $|; |
198
|
1199
|
|
|
|
|
2606
|
select $out; |
199
|
1199
|
|
|
|
|
2564
|
$| = $af; |
200
|
1199
|
|
|
|
|
3046
|
select $old; |
201
|
|
|
|
|
|
|
|
202
|
1199
|
|
|
|
|
4939
|
return $out; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
BEGIN { |
206
|
247
|
|
|
247
|
|
1065
|
if (IS_WIN32) { |
207
|
|
|
|
|
|
|
my $max_tries = 5; |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
*do_rename = sub { |
210
|
|
|
|
|
|
|
my ($from, $to) = @_; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
my $err; |
213
|
|
|
|
|
|
|
for (1 .. $max_tries) { |
214
|
|
|
|
|
|
|
return (1) if rename($from, $to); |
215
|
|
|
|
|
|
|
$err = "$!"; |
216
|
|
|
|
|
|
|
last if $_ == $max_tries; |
217
|
|
|
|
|
|
|
sleep 1; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
return (0, $err); |
221
|
|
|
|
|
|
|
}; |
222
|
|
|
|
|
|
|
*do_unlink = sub { |
223
|
|
|
|
|
|
|
my ($file) = @_; |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
my $err; |
226
|
|
|
|
|
|
|
for (1 .. $max_tries) { |
227
|
|
|
|
|
|
|
return (1) if unlink($file); |
228
|
|
|
|
|
|
|
$err = "$!"; |
229
|
|
|
|
|
|
|
last if $_ == $max_tries; |
230
|
|
|
|
|
|
|
sleep 1; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
return (0, "$!"); |
234
|
|
|
|
|
|
|
}; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
|
|
|
|
|
|
*do_rename = sub { |
238
|
37
|
|
|
37
|
|
162
|
my ($from, $to) = @_; |
239
|
37
|
50
|
|
|
|
2183
|
return (1) if rename($from, $to); |
240
|
0
|
|
|
|
|
0
|
return (0, "$!"); |
241
|
247
|
|
|
|
|
1610
|
}; |
242
|
|
|
|
|
|
|
*do_unlink = sub { |
243
|
70
|
|
|
70
|
|
202
|
my ($file) = @_; |
244
|
70
|
50
|
|
|
|
4334
|
return (1) if unlink($file); |
245
|
0
|
|
|
|
|
0
|
return (0, "$!"); |
246
|
247
|
|
|
|
|
40943
|
}; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub try_sig_mask(&) { |
251
|
36
|
|
|
36
|
1
|
108
|
my $code = shift; |
252
|
|
|
|
|
|
|
|
253
|
36
|
|
|
|
|
124
|
my ($old, $blocked); |
254
|
36
|
|
|
|
|
86
|
unless(IS_WIN32) { |
255
|
36
|
|
|
|
|
819
|
my $to_block = POSIX::SigSet->new( |
256
|
|
|
|
|
|
|
POSIX::SIGINT(), |
257
|
|
|
|
|
|
|
POSIX::SIGALRM(), |
258
|
|
|
|
|
|
|
POSIX::SIGHUP(), |
259
|
|
|
|
|
|
|
POSIX::SIGTERM(), |
260
|
|
|
|
|
|
|
POSIX::SIGUSR1(), |
261
|
|
|
|
|
|
|
POSIX::SIGUSR2(), |
262
|
|
|
|
|
|
|
); |
263
|
36
|
|
|
|
|
215
|
$old = POSIX::SigSet->new; |
264
|
36
|
|
|
|
|
1014
|
$blocked = POSIX::sigprocmask(POSIX::SIG_BLOCK(), $to_block, $old); |
265
|
|
|
|
|
|
|
# Silently go on if we failed to log signals, not much we can do. |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
36
|
|
|
|
|
396
|
my ($ok, $err) = &try($code); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# If our block was successful we want to restore the old mask. |
271
|
36
|
50
|
|
|
|
608
|
POSIX::sigprocmask(POSIX::SIG_SETMASK(), $old, POSIX::SigSet->new()) if defined $blocked; |
272
|
|
|
|
|
|
|
|
273
|
36
|
|
|
|
|
338
|
return ($ok, $err); |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
1; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
__END__ |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=pod |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=encoding UTF-8 |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head1 NAME |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Test2::Util - Tools used by Test2 and friends. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 DESCRIPTION |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Collection of tools used by L<Test2> and friends. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 EXPORTS |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
All exports are optional. You must specify subs to import. |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=over 4 |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item ($success, $error) = try { ... } |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Eval the codeblock, return success or failure, and the error message. This code |
301
|
|
|
|
|
|
|
protects $@ and $!, they will be restored by the end of the run. This code also |
302
|
|
|
|
|
|
|
temporarily blocks $SIG{DIE} handlers. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=item protect { ... } |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
Similar to try, except that it does not catch exceptions. The idea here is to |
307
|
|
|
|
|
|
|
protect $@ and $! from changes. $@ and $! will be restored to whatever they |
308
|
|
|
|
|
|
|
were before the run so long as it is successful. If the run fails $! will still |
309
|
|
|
|
|
|
|
be restored, but $@ will contain the exception being thrown. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=item CAN_FORK |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
True if this system is capable of true or pseudo-fork. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item CAN_REALLY_FORK |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
True if the system can really fork. This will be false for systems where fork |
318
|
|
|
|
|
|
|
is emulated. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=item CAN_THREAD |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
True if this system is capable of using threads. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=item USE_THREADS |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Returns true if threads are enabled, false if they are not. |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item get_tid |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
This will return the id of the current thread when threads are enabled, |
331
|
|
|
|
|
|
|
otherwise it returns 0. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=item my $file = pkg_to_file($package) |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Convert a package name to a filename. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=item $string = ipc_separator() |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
Get the IPC separator. Currently this is always the string C<'~'>. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=item $string = gen_uid() |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Generate a unique id (NOT A UUID). This will typically be the process id, the |
344
|
|
|
|
|
|
|
thread id, the time, and an incrementing integer all joined with the |
345
|
|
|
|
|
|
|
C<ipc_separator()>. |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
These ID's are unique enough for most purposes. For identical ids to be |
348
|
|
|
|
|
|
|
generated you must have 2 processes with the same PID generate IDs at the same |
349
|
|
|
|
|
|
|
time with the same current state of the incrementing integer. This is a |
350
|
|
|
|
|
|
|
perfectly reasonable thing to expect to happen across multiple machines, but is |
351
|
|
|
|
|
|
|
quite unlikely to happen on one machine. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
This can fail to be unique if a process generates an id, calls exec, and does |
354
|
|
|
|
|
|
|
it again after the exec and it all happens in less than a second. It can also |
355
|
|
|
|
|
|
|
happen if the systems process id's cycle in less than a second allowing 2 |
356
|
|
|
|
|
|
|
different programs that use this generator to run with the same PID in less |
357
|
|
|
|
|
|
|
than a second. Both these cases are sufficiently unlikely. If you need |
358
|
|
|
|
|
|
|
universally unique ids, or ids that are unique in these conditions, look at |
359
|
|
|
|
|
|
|
L<Data::UUID>. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=item ($ok, $err) = do_rename($old_name, $new_name) |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Rename a file, this wraps C<rename()> in a way that makes it more reliable |
364
|
|
|
|
|
|
|
cross-platform when trying to rename files you recently altered. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=item ($ok, $err) = do_unlink($filename) |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
Unlink a file, this wraps C<unlink()> in a way that makes it more reliable |
369
|
|
|
|
|
|
|
cross-platform when trying to unlink files you recently altered. |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=item ($ok, $err) = try_sig_mask { ... } |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Complete an action with several signals masked, they will be unmasked at the |
374
|
|
|
|
|
|
|
end allowing any signals that were intercepted to get handled. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
This is primarily used when you need to make several actions atomic (against |
377
|
|
|
|
|
|
|
some signals anyway). |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
Signals that are intercepted: |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=over 4 |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=item SIGINT |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=item SIGALRM |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=item SIGHUP |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item SIGTERM |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=item SIGUSR1 |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=item SIGUSR2 |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=back |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=back |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head1 NOTES && CAVEATS |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=over 4 |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=item 5.10.0 |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Perl 5.10.0 has a bug when compiled with newer gcc versions. This bug causes a |
406
|
|
|
|
|
|
|
segfault whenever a new thread is launched. Test2 will attempt to detect |
407
|
|
|
|
|
|
|
this, and note that the system is not capable of forking when it is detected. |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item Devel::Cover |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Devel::Cover does not support threads. CAN_THREAD will return false if |
412
|
|
|
|
|
|
|
Devel::Cover is loaded before the check is first run. |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=back |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head1 SOURCE |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
The source code repository for Test2 can be found at |
419
|
|
|
|
|
|
|
F<http://github.com/Test-More/test-more/>. |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=head1 MAINTAINERS |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=over 4 |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item Chad Granum E<lt>exodist@cpan.orgE<gt> |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=back |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=head1 AUTHORS |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=over 4 |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=item Chad Granum E<lt>exodist@cpan.orgE<gt> |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=item Kent Fredric E<lt>kentnl@cpan.orgE<gt> |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=back |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head1 COPYRIGHT |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Copyright 2020 Chad Granum E<lt>exodist@cpan.orgE<gt>. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or |
444
|
|
|
|
|
|
|
modify it under the same terms as Perl itself. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
See F<http://dev.perl.org/licenses/> |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=cut |