File Coverage

blib/lib/Test2/Util.pm
Criterion Covered Total %
statement 100 112 89.2
branch 23 48 47.9
condition 8 25 32.0
subroutine 29 29 100.0
pod 4 5 80.0
total 164 219 74.8


line stmt bran cond sub pod time code
1             package Test2::Util;
2 247     247   12513 use strict;
  247         584  
  247         7049  
3 247     247   1201 use warnings;
  247         508  
  247         9194  
4              
5             our $VERSION = '1.302180';
6              
7 247     247   129503 use POSIX();
  247         2017628  
  247         8041  
8 247     247   1805 use Config qw/%Config/;
  247         465  
  247         12607  
9 247     247   1591 use Carp qw/croak/;
  247         471  
  247         27509  
10              
11             BEGIN {
12 247     247   2767 local ($@, $!, $SIG{__DIE__});
13 247 50       605 *HAVE_PERLIO = eval { require PerlIO; PerlIO->VERSION(1.02); } ? sub() { 1 } : sub() { 0 };
  247         151066  
  247         27636  
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             clone_io
37             };
38 247     247   1683 BEGIN { require Exporter; our @ISA = qw(Exporter) }
  247         18153  
39              
40             BEGIN {
41 247 50   247   55780 *IS_WIN32 = ($^O eq 'MSWin32') ? sub() { 1 } : sub() { 0 };
42             }
43              
44             sub _can_thread {
45 247 50   247   1403 return 0 unless $] >= 5.008001;
46 247 50       20310 return 0 unless $Config{'useithreads'};
47              
48             # Threads are broken on perl 5.10.0 built with gcc 4.8+
49 0 0 0     0 if ($] == 5.010000 && $Config{'ccname'} eq 'gcc' && $Config{'gccversion'}) {
      0        
50 0         0 my @parts = split /\./, $Config{'gccversion'};
51 0 0 0     0 return 0 if $parts[0] > 4 || ($parts[0] == 4 && $parts[1] >= 8);
      0        
52             }
53              
54             # Change to a version check if this ever changes
55 0 0       0 return 0 if $INC{'Devel/Cover.pm'};
56 0         0 return 1;
57             }
58              
59             sub _can_fork {
60 27 50   27   2188 return 1 if $Config{d_fork};
61 0 0       0 return 0 unless IS_WIN32 || $^O eq 'NetWare';
62 0 0       0 return 0 unless $Config{useithreads};
63 0 0       0 return 0 unless $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/;
64              
65 0         0 return _can_thread();
66             }
67              
68             BEGIN {
69 247     247   2051 no warnings 'once';
  247         677  
  247         20690  
70 247 50   247   1159 *CAN_THREAD = _can_thread() ? sub() { 1 } : sub() { 0 };
71             }
72             my $can_fork;
73             sub CAN_FORK () {
74 39 100   39 1 1494 return $can_fork
75             if defined $can_fork;
76 27         369 $can_fork = !!_can_fork();
77 247     247   1818 no warnings 'redefine';
  247         478  
  247         30017  
78 27 50       974 *CAN_FORK = $can_fork ? sub() { 1 } : sub() { 0 };
79 27         204 $can_fork;
80             }
81             my $can_really_fork;
82             sub CAN_REALLY_FORK () {
83 24 100   24 1 235 return $can_really_fork
84             if defined $can_really_fork;
85 17         1028 $can_really_fork = !!$Config{d_fork};
86 247     247   1716 no warnings 'redefine';
  247         522  
  247         57524  
87 17 50       161 *CAN_REALLY_FORK = $can_really_fork ? sub() { 1 } : sub() { 0 };
88 17         57 $can_really_fork;
89             }
90              
91             sub _manual_try(&;@) {
92 2     2   18 my $code = shift;
93 2         3 my $args = \@_;
94 2         4 my $err;
95              
96 2         10 my $die = delete $SIG{__DIE__};
97              
98 2 100 50     5 eval { $code->(@$args); 1 } or $err = $@ || "Error was squashed!\n";
  2         6  
  1         4  
99              
100 2 50       19 $die ? $SIG{__DIE__} = $die : delete $SIG{__DIE__};
101              
102 2         9 return (!defined($err), $err);
103             }
104              
105             sub _local_try(&;@) {
106 218     218   2608 my $code = shift;
107 218         507 my $args = \@_;
108 218         394 my $err;
109              
110 247     247   1835 no warnings;
  247         548  
  247         37509  
111 218         1091 local $SIG{__DIE__};
112 218 100 50     487 eval { $code->(@$args); 1 } or $err = $@ || "Error was squashed!\n";
  218         748  
  207         1055  
113              
114 218         2456 return (!defined($err), $err);
115             }
116              
117             # Older versions of perl have a nasty bug on win32 when localizing a variable
118             # before forking or starting a new thread. So for those systems we use the
119             # non-local form. When possible though we use the faster 'local' form.
120             BEGIN {
121 247     247   2134 if (IS_WIN32 && $] < 5.020002) {
122             *try = \&_manual_try;
123             }
124             else {
125 247         48431 *try = \&_local_try;
126             }
127             }
128              
129             BEGIN {
130 247     247   879 if (CAN_THREAD) {
131             if ($INC{'threads.pm'}) {
132             # Threads are already loaded, so we do not need to check if they
133             # are loaded each time
134             *USE_THREADS = sub() { 1 };
135             *get_tid = sub() { threads->tid() };
136             }
137             else {
138             # :-( Need to check each time to see if they have been loaded.
139             *USE_THREADS = sub() { $INC{'threads.pm'} ? 1 : 0 };
140             *get_tid = sub() { $INC{'threads.pm'} ? threads->tid() : 0 };
141             }
142             }
143             else {
144             # No threads, not now, not ever!
145 247         712 *USE_THREADS = sub() { 0 };
146 247         64193 *get_tid = sub() { 0 };
147             }
148             }
149              
150             sub pkg_to_file {
151 844     844 1 1358 my $pkg = shift;
152 844         1189 my $file = $pkg;
153 844         5550 $file =~ s{(::|')}{/}g;
154 844         1656 $file .= '.pm';
155 844         2016 return $file;
156             }
157              
158             sub ipc_separator() { "~" }
159              
160             my $UID = 1;
161 15112     15112 1 149816 sub gen_uid() { join ipc_separator() => ($$, get_tid(), time, $UID++) }
162              
163             sub _check_for_sig_sys {
164 252     252   25503 my $sig_list = shift;
165 252         2323 return $sig_list =~ m/\bSYS\b/;
166             }
167              
168             BEGIN {
169 247 50   247   1695 if (_check_for_sig_sys($Config{sig_name})) {
170 247         141058 *CAN_SIGSYS = sub() { 1 };
171             }
172             else {
173 0         0 *CAN_SIGSYS = sub() { 0 };
174             }
175             }
176              
177             my %PERLIO_SKIP = (
178             unix => 1,
179             via => 1,
180             );
181              
182             sub clone_io {
183 1200     1200 0 4105 my ($fh) = @_;
184 1200         3008 my $fileno = eval { fileno($fh) };
  1200         4096  
185              
186 1200 100 33     9977 return $fh if !defined($fileno) || !length($fileno) || $fileno < 0;
      66        
187              
188 1199 50       35422 open(my $out, '>&' . $fileno) or die "Can't dup fileno $fileno: $!";
189              
190 1199         3683 my %seen;
191 1199   100     9676 my @layers = HAVE_PERLIO ? grep { !$PERLIO_SKIP{$_} and !$seen{$_}++ } PerlIO::get_layers($fh) : ();
  3112         17446  
192 1199         13433 binmode($out, join(":", "", "raw", @layers));
193              
194 1199         6575 my $old = select $fh;
195 1199         3822 my $af = $|;
196 1199         2828 select $out;
197 1199         2613 $| = $af;
198 1199         3165 select $old;
199              
200 1199         5337 return $out;
201             }
202              
203             BEGIN {
204 247     247   1062 if (IS_WIN32) {
205             my $max_tries = 5;
206              
207             *do_rename = sub {
208             my ($from, $to) = @_;
209              
210             my $err;
211             for (1 .. $max_tries) {
212             return (1) if rename($from, $to);
213             $err = "$!";
214             last if $_ == $max_tries;
215             sleep 1;
216             }
217              
218             return (0, $err);
219             };
220             *do_unlink = sub {
221             my ($file) = @_;
222              
223             my $err;
224             for (1 .. $max_tries) {
225             return (1) if unlink($file);
226             $err = "$!";
227             last if $_ == $max_tries;
228             sleep 1;
229             }
230              
231             return (0, "$!");
232             };
233             }
234             else {
235             *do_rename = sub {
236 37     37   219 my ($from, $to) = @_;
237 37 50       2261 return (1) if rename($from, $to);
238 0         0 return (0, "$!");
239 247         1618 };
240             *do_unlink = sub {
241 70     70   217 my ($file) = @_;
242 70 50       4208 return (1) if unlink($file);
243 0         0 return (0, "$!");
244 247         8580 };
245             }
246             }
247              
248             1;
249              
250             __END__