File Coverage

blib/lib/Capture/Tiny.pm
Criterion Covered Total %
statement 227 246 92.2
branch 104 128 81.2
condition 53 75 70.6
subroutine 34 35 97.1
pod 8 8 100.0
total 426 492 86.5


line stmt bran cond sub pod time code
1 3306     3306   52302585 use 5.006;
  3306         8390  
2 3306     3306   10488 use strict;
  3306         4189  
  3306         50722  
3 3306     3306   9351 use warnings;
  3306         3629  
  3306         138965  
4             package Capture::Tiny;
5             # ABSTRACT: Capture STDOUT and STDERR from Perl, XS or external programs
6             our $VERSION = '0.46';
7 3306     3306   13456 use Carp ();
  3306         3629  
  3306         42558  
8 3306     3306   8948 use Exporter ();
  3306         3547  
  3306         39575  
9 3306     3306   1584186 use IO::Handle ();
  3306         15681165  
  3306         64089  
10 3306     3306   16124 use File::Spec ();
  3306         3710  
  3306         54360  
11 3306     3306   2285017 use File::Temp qw/tempfile tmpnam/;
  3306         38169527  
  3306         197877  
12 3306     3306   18227 use Scalar::Util qw/reftype blessed/;
  3306         3950  
  3306         227754  
13             # Get PerlIO or fake it
14             BEGIN {
15 3306     3306   23787 local $@;
16 3306         11132 eval { require PerlIO; PerlIO->can('get_layers') }
  3306         742893  
17 3306 50       4674 or *PerlIO::get_layers = sub { return () };
  0         0  
18             }
19              
20             #--------------------------------------------------------------------------#
21             # create API subroutines and export them
22             # [do STDOUT flag, do STDERR flag, do merge flag, do tee flag]
23             #--------------------------------------------------------------------------#
24              
25             my %api = (
26             capture => [1,1,0,0],
27             capture_stdout => [1,0,0,0],
28             capture_stderr => [0,1,0,0],
29             capture_merged => [1,1,1,0],
30             tee => [1,1,0,1],
31             tee_stdout => [1,0,0,1],
32             tee_stderr => [0,1,0,1],
33             tee_merged => [1,1,1,1],
34             );
35              
36             for my $sub ( keys %api ) {
37             my $args = join q{, }, @{$api{$sub}};
38 563047     563047 1 982598941 eval "sub $sub(&;@) {unshift \@_, $args; goto \\&_capture_tee;}"; ## no critic
  563047     85211 1 2302032  
  85211     88506 1 100203690  
  85211     85211 1 298528  
  88506     139643 1 9376903  
  88506     12320 1 265170  
  85211     29365 1 2360931  
  85211     40865 1 266494  
  139643         4433549  
  139643         666510  
  12320         396493  
  12320         59596  
  29365         960721  
  29365         143825  
  40865         1312308  
  40865         205227  
39             }
40              
41             our @ISA = qw/Exporter/;
42             our @EXPORT_OK = keys %api;
43             our %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
44              
45             #--------------------------------------------------------------------------#
46             # constants and fixtures
47             #--------------------------------------------------------------------------#
48              
49             my $IS_WIN32 = $^O eq 'MSWin32';
50              
51             ##our $DEBUG = $ENV{PERL_CAPTURE_TINY_DEBUG};
52             ##
53             ##my $DEBUGFH;
54             ##open $DEBUGFH, "> DEBUG" if $DEBUG;
55             ##
56             ##*_debug = $DEBUG ? sub(@) { print {$DEBUGFH} @_ } : sub(){0};
57              
58             our $TIMEOUT = 30;
59              
60             #--------------------------------------------------------------------------#
61             # command to tee output -- the argument is a filename that must
62             # be opened to signal that the process is ready to receive input.
63             # This is annoying, but seems to be the best that can be done
64             # as a simple, portable IPC technique
65             #--------------------------------------------------------------------------#
66             my @cmd = ($^X, '-C0', '-e', <<'HERE');
67             use Fcntl;
68             $SIG{HUP}=sub{exit};
69             if ( my $fn=shift ) {
70             sysopen(my $fh, qq{$fn}, O_WRONLY|O_CREAT|O_EXCL) or die $!;
71             print {$fh} $$;
72             close $fh;
73             }
74             my $buf; while (sysread(STDIN, $buf, 2048)) {
75             syswrite(STDOUT, $buf); syswrite(STDERR, $buf);
76             }
77             HERE
78              
79             #--------------------------------------------------------------------------#
80             # filehandle manipulation
81             #--------------------------------------------------------------------------#
82              
83             sub _relayer {
84 5502797     5502797   5614637 my ($fh, $apply_layers) = @_;
85             # _debug("# requested layers (@{$layers}) for @{[fileno $fh]}\n");
86              
87             # eliminate pseudo-layers
88 5502797         14571951 binmode( $fh, ":raw" );
89             # strip off real layers until only :unix is left
90 5502797         23513721 while ( 1 < ( my $layers =()= PerlIO::get_layers( $fh, output => 1 ) ) ) {
91 5502797         21976173 binmode( $fh, ":pop" );
92             }
93             # apply other layers
94 5502797         10208827 my @to_apply = @$apply_layers;
95 5502797         4368337 shift @to_apply; # eliminate initial :unix
96             # _debug("# applying layers (unix @to_apply) to @{[fileno $fh]}\n");
97 5502797         19630612 binmode($fh, ":" . join(":",@to_apply));
98             }
99              
100             sub _name {
101 0     0   0 my $glob = shift;
102 3306     3306   12663 no strict 'refs'; ## no critic
  3306         3307  
  3306         6194338  
103 0         0 return *{$glob}{NAME};
  0         0  
104             }
105              
106             sub _open {
107 7485730 50   7485730   169619571 open $_[0], $_[1] or Carp::confess "Error from open(" . join(q{, }, @_) . "): $!";
108             # _debug( "# open " . join( ", " , map { defined $_ ? _name($_) : 'undef' } @_ ) . " as " . fileno( $_[0] ) . "\n" );
109             }
110              
111             sub _close {
112             # _debug( "# closing " . ( defined $_[0] ? _name($_[0]) : 'undef' ) . " on " . fileno( $_[0] ) . "\n" );
113 3086260 50   3086260   22343250 close $_[0] or Carp::confess "Error from close(" . join(q{, }, @_) . "): $!";
114             }
115              
116             my %dup; # cache this so STDIN stays fd0
117             my %proxy_count;
118             sub _proxy_std {
119 1044168     1044168   842857 my %proxies;
120 1044168 100       2001850 if ( ! defined fileno STDIN ) {
121 138870         182982 $proxy_count{stdin}++;
122 138870 100       277699 if (defined $dup{stdin}) {
123 31830         99241 _open \*STDIN, "<&=" . fileno($dup{stdin});
124             # _debug( "# restored proxy STDIN as " . (defined fileno STDIN ? fileno STDIN : 'undef' ) . "\n" );
125             }
126             else {
127 107040         1197170 _open \*STDIN, "<" . File::Spec->devnull;
128             # _debug( "# proxied STDIN as " . (defined fileno STDIN ? fileno STDIN : 'undef' ) . "\n" );
129 107040         863988 _open $dup{stdin} = IO::Handle->new, "<&=STDIN";
130             }
131 138870         233679 $proxies{stdin} = \*STDIN;
132 138870 50       681882 binmode(STDIN, ':utf8') if $] >= 5.008; ## no critic
133             }
134 1044168 100       1743876 if ( ! defined fileno STDOUT ) {
135 107040         158933 $proxy_count{stdout}++;
136 107040 50       211849 if (defined $dup{stdout}) {
137 0         0 _open \*STDOUT, ">&=" . fileno($dup{stdout});
138             # _debug( "# restored proxy STDOUT as " . (defined fileno STDOUT ? fileno STDOUT : 'undef' ) . "\n" );
139             }
140             else {
141 107040         1071274 _open \*STDOUT, ">" . File::Spec->devnull;
142             # _debug( "# proxied STDOUT as " . (defined fileno STDOUT ? fileno STDOUT : 'undef' ) . "\n" );
143 107040         969639 _open $dup{stdout} = IO::Handle->new, ">&=STDOUT";
144             }
145 107040         189500 $proxies{stdout} = \*STDOUT;
146 107040 50       547089 binmode(STDOUT, ':utf8') if $] >= 5.008; ## no critic
147             }
148 1044168 100       1626262 if ( ! defined fileno STDERR ) {
149 107040         167652 $proxy_count{stderr}++;
150 107040 50       200759 if (defined $dup{stderr}) {
151 0         0 _open \*STDERR, ">&=" . fileno($dup{stderr});
152             # _debug( "# restored proxy STDERR as " . (defined fileno STDERR ? fileno STDERR : 'undef' ) . "\n" );
153             }
154             else {
155 107040         1087297 _open \*STDERR, ">" . File::Spec->devnull;
156             # _debug( "# proxied STDERR as " . (defined fileno STDERR ? fileno STDERR : 'undef' ) . "\n" );
157 107040         871249 _open $dup{stderr} = IO::Handle->new, ">&=STDERR";
158             }
159 107040         187511 $proxies{stderr} = \*STDERR;
160 107040 50       540136 binmode(STDERR, ':utf8') if $] >= 5.008; ## no critic
161             }
162 1044168         2376227 return %proxies;
163             }
164              
165             sub _unproxy {
166 1037603     1037603   2028320 my (%proxies) = @_;
167             # _debug( "# unproxying: " . join(" ", keys %proxies) . "\n" );
168 1037603         2287434 for my $p ( keys %proxies ) {
169 351270         564138 $proxy_count{$p}--;
170             # _debug( "# unproxied " . uc($p) . " ($proxy_count{$p} left)\n" );
171 351270 100       792016 if ( ! $proxy_count{$p} ) {
172 319680         511833 _close $proxies{$p};
173 319680 50       903379 _close $dup{$p} unless $] < 5.008; # 5.6 will have already closed this as dup
174 319680         1699705 delete $dup{$p};
175             }
176             }
177             }
178              
179             sub _copy_std {
180 1044168     1044168   797989 my %handles;
181 1044168         1934239 for my $h ( qw/stdout stderr stdin/ ) {
182 3132504 100 66     8639279 next if $h eq 'stdin' && ! $IS_WIN32; # WIN32 hangs on tee without STDIN copied
183 2088336 50       3079354 my $redir = $h eq 'stdin' ? "<&" : ">&";
184 2088336         7431324 _open $handles{$h} = IO::Handle->new(), $redir . uc($h); # ">&STDOUT" or "<&STDIN"
185             }
186 1044168         2133870 return \%handles;
187             }
188              
189             # In some cases we open all (prior to forking) and in others we only open
190             # the output handles (setting up redirection)
191             sub _open_std {
192 2081771     2081771   2683935 my ($handles) = @_;
193 2081771 100       4142305 _open \*STDIN, "<&" . fileno $handles->{stdin} if defined $handles->{stdin};
194 2081771 50       11768577 _open \*STDOUT, ">&" . fileno $handles->{stdout} if defined $handles->{stdout};
195 2081771 50       8164298 _open \*STDERR, ">&" . fileno $handles->{stderr} if defined $handles->{stderr};
196             }
197              
198             #--------------------------------------------------------------------------#
199             # private subs
200             #--------------------------------------------------------------------------#
201              
202             sub _start_tee {
203 372925     372925   649927 my ($which, $stash) = @_; # $which is "stdout" or "stderr"
204             # setup pipes
205 372925         3767976 $stash->{$_}{$which} = IO::Handle->new for qw/tee reader/;
206 372925         20592601 pipe $stash->{reader}{$which}, $stash->{tee}{$which};
207             # _debug( "# pipe for $which\: " . _name($stash->{tee}{$which}) . " " . fileno( $stash->{tee}{$which} ) . " => " . _name($stash->{reader}{$which}) . " " . fileno( $stash->{reader}{$which}) . "\n" );
208 372925         3222656 select((select($stash->{tee}{$which}), $|=1)[0]); # autoflush
209             # setup desired redirection for parent and child
210 372925         733506 $stash->{new}{$which} = $stash->{tee}{$which};
211             $stash->{child}{$which} = {
212             stdin => $stash->{reader}{$which},
213             stdout => $stash->{old}{$which},
214 372925         1486658 stderr => $stash->{capture}{$which},
215             };
216             # flag file is used to signal the child is ready
217 372925         1646853 $stash->{flag_files}{$which} = scalar tmpnam();
218             # execute @cmd as a separate process
219 372925 50       61732149 if ( $IS_WIN32 ) {
220 0         0 my $old_eval_err=$@;
221 0         0 undef $@;
222              
223 0         0 eval "use Win32API::File qw/GetOsFHandle SetHandleInformation fileLastError HANDLE_FLAG_INHERIT INVALID_HANDLE_VALUE/ ";
224             # _debug( "# Win32API::File loaded\n") unless $@;
225 0         0 my $os_fhandle = GetOsFHandle( $stash->{tee}{$which} );
226             # _debug( "# Couldn't get OS handle: " . fileLastError() . "\n") if ! defined $os_fhandle || $os_fhandle == INVALID_HANDLE_VALUE();
227 0         0 my $result = SetHandleInformation( $os_fhandle, HANDLE_FLAG_INHERIT(), 0);
228             # _debug( $result ? "# set no-inherit flag on $which tee\n" : ("# can't disable tee handle flag inherit: " . fileLastError() . "\n"));
229 0         0 _open_std( $stash->{child}{$which} );
230 0         0 $stash->{pid}{$which} = system(1, @cmd, $stash->{flag_files}{$which});
231             # not restoring std here as it all gets redirected again shortly anyway
232 0         0 $@=$old_eval_err;
233             }
234             else { # use fork
235 372925         1184621 _fork_exec( $which, $stash );
236             }
237             }
238              
239             sub _fork_exec {
240 372925     372925   457220 my ($which, $stash) = @_; # $which is "stdout" or "stderr"
241 372925         177332156 my $pid = fork;
242 372925 50       4112484 if ( not defined $pid ) {
    100          
243 0         0 Carp::confess "Couldn't fork(): $!";
244             }
245             elsif ($pid == 0) { # child
246             # _debug( "# in child process ...\n" );
247 3282         118081 untie *STDIN; untie *STDOUT; untie *STDERR;
  3282         26822  
  3282         24730  
248 3282         106830 _close $stash->{tee}{$which};
249             # _debug( "# redirecting handles in child ...\n" );
250 3282         48654 _open_std( $stash->{child}{$which} );
251             # _debug( "# calling exec on command ...\n" );
252 3282         0 exec @cmd, $stash->{flag_files}{$which};
253             }
254 369643         17944278 $stash->{pid}{$which} = $pid
255             }
256              
257 3306     3306   1516989 my $have_usleep = eval "use Time::HiRes 'usleep'; 1";
  3306         3432197  
  3306         10162  
258             sub _files_exist {
259 54372557 100   54372557   83788795 return 1 if @_ == grep { -f } @_;
  91591282         787026990  
260 53934735 50       58560263933 Time::HiRes::usleep(1000) if $have_usleep;
261 53934735         320691319 return 0;
262             }
263              
264             sub _wait_for_tees {
265 218911     218911   739630 my ($stash) = @_;
266 218911         389611 my $start = time;
267 218911         359792 my @files = values %{$stash->{flag_files}};
  218911         4413869  
268             my $timeout = defined $ENV{PERL_CAPTURE_TINY_TIMEOUT}
269 218911 50       1530609 ? $ENV{PERL_CAPTURE_TINY_TIMEOUT} : $TIMEOUT;
270 218911   33     815175 1 until _files_exist(@files) || ($timeout && (time - $start > $timeout));
      66        
271 218911 50       623239 Carp::confess "Timed out waiting for subprocesses to start" if ! _files_exist(@files);
272 218911         132291265 unlink $_ for @files;
273             }
274              
275             sub _kill_tees {
276 218911     218911   401393 my ($stash) = @_;
277 218911 50       689441 if ( $IS_WIN32 ) {
278             # _debug( "# closing handles\n");
279 0         0 close($_) for values %{ $stash->{tee} };
  0         0  
280             # _debug( "# waiting for subprocesses to finish\n");
281 0         0 my $start = time;
282 0   0     0 1 until wait == -1 || (time - $start > 30);
283             }
284             else {
285 218911         315344 _close $_ for values %{ $stash->{tee} };
  218911         1225281  
286 218911         385746 waitpid $_, 0 for values %{ $stash->{pid} };
  218911         95861304  
287             }
288             }
289              
290             sub _slurp {
291 1832073     1832073   1808948 my ($name, $stash) = @_;
292 1832073         2235425 my ($fh, $pos) = map { $stash->{$_}{$name} } qw/capture pos/;
  3664146         5850817  
293             # _debug( "# slurping captured $name from " . fileno($fh) . " at pos $pos with layers: @{[PerlIO::get_layers($fh)]}\n");
294 1832073 50       4679522 seek( $fh, $pos, 0 ) or die "Couldn't seek on capture handle for $name\n";
295 1832073         1306029 my $text = do { local $/; scalar readline $fh };
  1832073         4725856  
  1832073         30524546  
296 1832073 100       7690480 return defined($text) ? $text : "";
297             }
298              
299             #--------------------------------------------------------------------------#
300             # _capture_tee() -- generic main sub for capturing or teeing
301             #--------------------------------------------------------------------------#
302              
303             sub _capture_tee {
304             # _debug( "# starting _capture_tee with (@_)...\n" );
305 1044168     1044168   1948642 my ($do_stdout, $do_stderr, $do_merge, $do_tee, $code, @opts) = @_;
306 1044168 100       3878453 my %do = ($do_stdout ? (stdout => 1) : (), $do_stderr ? (stderr => 1) : ());
    100          
307 1044168 50       2730202 Carp::confess("Custom capture options must be given as key/value pairs\n")
308             unless @opts % 2 == 0;
309 1044168         2427014 my $stash = { capture => { @opts } };
310 1044168         1146925 for ( keys %{$stash->{capture}} ) {
  1044168         3131612  
311 10         11 my $fh = $stash->{capture}{$_};
312 10 50 33     87 Carp::confess "Custom handle for $_ must be seekable\n"
      33        
313             unless ref($fh) eq 'GLOB' || (blessed($fh) && $fh->isa("IO::Seekable"));
314             }
315             # save existing filehandles and setup captures
316 1044168         3283013 local *CT_ORIG_STDIN = *STDIN ;
317 1044168         1613314 local *CT_ORIG_STDOUT = *STDOUT;
318 1044168         1412682 local *CT_ORIG_STDERR = *STDERR;
319             # find initial layers
320 1044168         9955895 my %layers = (
321             stdin => [PerlIO::get_layers(\*STDIN) ],
322             stdout => [PerlIO::get_layers(\*STDOUT, output => 1)],
323             stderr => [PerlIO::get_layers(\*STDERR, output => 1)],
324             );
325             # _debug( "# existing layers for $_\: @{$layers{$_}}\n" ) for qw/stdin stdout stderr/;
326             # get layers from underlying glob of tied filehandles if we can
327             # (this only works for things that work like Tie::StdHandle)
328 1044168 100 100     4250105 $layers{stdout} = [PerlIO::get_layers(tied *STDOUT)]
329             if tied(*STDOUT) && (reftype tied *STDOUT eq 'GLOB');
330 1044168 100 100     3182581 $layers{stderr} = [PerlIO::get_layers(tied *STDERR)]
331             if tied(*STDERR) && (reftype tied *STDERR eq 'GLOB');
332             # _debug( "# tied object corrected layers for $_\: @{$layers{$_}}\n" ) for qw/stdin stdout stderr/;
333             # bypass scalar filehandles and tied handles
334             # localize scalar STDIN to get a proxy to pick up FD0, then restore later to CT_ORIG_STDIN
335 1044168         938945 my %localize;
336             $localize{stdin}++, local(*STDIN)
337 1044168 100       820621 if grep { $_ eq 'scalar' } @{$layers{stdin}};
  1927776         3787436  
  1044168         1569396  
338             $localize{stdout}++, local(*STDOUT)
339 1044168 100 100     2548396 if $do_stdout && grep { $_ eq 'scalar' } @{$layers{stdout}};
  1967715         4166699  
  926297         1476954  
340             $localize{stderr}++, local(*STDERR)
341 1044168 100 66     3089438 if ($do_stderr || $do_merge) && grep { $_ eq 'scalar' } @{$layers{stderr}};
  1947046   100     3790672  
  918092         1216804  
342 1044168 100 66     3253597 $localize{stdin}++, local(*STDIN), _open( \*STDIN, "<&=0")
343             if tied *STDIN && $] >= 5.008;
344 1044168 100 100     4773722 $localize{stdout}++, local(*STDOUT), _open( \*STDOUT, ">&=1")
      66        
345             if $do_stdout && tied *STDOUT && $] >= 5.008;
346 1044168 100 66     5427038 $localize{stderr}++, local(*STDERR), _open( \*STDERR, ">&=2")
      100        
      66        
347             if ($do_stderr || $do_merge) && tied *STDERR && $] >= 5.008;
348             # _debug( "# localized $_\n" ) for keys %localize;
349             # proxy any closed/localized handles so we don't use fds 0, 1 or 2
350 1044168         1855564 my %proxy_std = _proxy_std();
351             # _debug( "# proxy std: @{ [%proxy_std] }\n" );
352             # update layers after any proxying
353 1044168 100       2346805 $layers{stdout} = [PerlIO::get_layers(\*STDOUT, output => 1)] if $proxy_std{stdout};
354 1044168 100       2099585 $layers{stderr} = [PerlIO::get_layers(\*STDERR, output => 1)] if $proxy_std{stderr};
355             # _debug( "# post-proxy layers for $_\: @{$layers{$_}}\n" ) for qw/stdin stdout stderr/;
356             # store old handles and setup handles for capture
357 1044168         1531753 $stash->{old} = _copy_std();
358 1044168         935331 $stash->{new} = { %{$stash->{old}} }; # default to originals
  1044168         3338995  
359 1044168         2076644 for ( keys %do ) {
360 1843158   66     16241185 $stash->{new}{$_} = ($stash->{capture}{$_} ||= File::Temp->new);
361 1843158 50       626508832 seek( $stash->{capture}{$_}, 0, 2 ) or die "Could not seek on capture handle for $_\n";
362 1843158         4720152 $stash->{pos}{$_} = tell $stash->{capture}{$_};
363             # _debug("# will capture $_ on " . fileno($stash->{capture}{$_})."\n" );
364 1843158 100       5278663 _start_tee( $_ => $stash ) if $do_tee; # tees may change $stash->{new}
365             }
366 1040886 100       6695845 _wait_for_tees( $stash ) if $do_tee;
367             # finalize redirection
368 1040886 100       2101173 $stash->{new}{stderr} = $stash->{new}{stdout} if $do_merge;
369             # _debug( "# redirecting in parent ...\n" );
370 1040886         3137789 _open_std( $stash->{new} );
371             # execute user provided code
372 1040886         1495565 my ($exit_code, $inner_error, $outer_error, $orig_pid, @result);
373             {
374 1040886         1010758 $orig_pid = $$;
  1040886         2334620  
375 1040886 100       2941588 local *STDIN = *CT_ORIG_STDIN if $localize{stdin}; # get original, not proxy STDIN
376             # _debug( "# finalizing layers ...\n" );
377 1040886 100       3644433 _relayer(\*STDOUT, $layers{stdout}) if $do_stdout;
378 1040886 100       2793856 _relayer(\*STDERR, $layers{stderr}) if $do_stderr;
379             # _debug( "# running code $code ...\n" );
380 1040886         1456112 my $old_eval_err=$@;
381 1040886         1258069 undef $@;
382 1040886         1355844 eval { @result = $code->(); $inner_error = $@ };
  1040886         3690926  
  1037602         1020341536  
383 1037603         2937570 $exit_code = $?; # save this for later
384 1037603         1390879 $outer_error = $@; # save this for later
385 1037603 100       7764342 STDOUT->flush if $do_stdout;
386 1037603 100       4835202 STDERR->flush if $do_stderr;
387 1037603         1747373 $@ = $old_eval_err;
388             }
389             # restore prior filehandles and shut down tees
390             # _debug( "# restoring filehandles ...\n" );
391 1037603         3228424 _open_std( $stash->{old} );
392 1037603         1248403 _close( $_ ) for values %{$stash->{old}}; # don't leak fds
  1037603         4769666  
393             # shouldn't need relayering originals, but see rt.perl.org #114404
394 1037603 100       3484743 _relayer(\*STDOUT, $layers{stdout}) if $do_stdout;
395 1037603 100       2732597 _relayer(\*STDERR, $layers{stderr}) if $do_stderr;
396 1037603         3032800 _unproxy( %proxy_std );
397             # _debug( "# killing tee subprocesses ...\n" ) if $do_tee;
398 1037603 100       2515563 _kill_tees( $stash ) if $do_tee;
399             # return captured output, but shortcut in void context
400             # unless we have to echo output to tied/scalar handles;
401 1037603         1222831 my %got;
402 1037603 100 66     6302042 if ( $orig_pid == $$ and ( defined wantarray or ($do_tee && keys %localize) ) ) {
      33        
403 1037600         2913411 for ( keys %do ) {
404 1832073         3728111 _relayer($stash->{capture}{$_}, $layers{$_});
405 1832073         3118676 $got{$_} = _slurp($_, $stash);
406             # _debug("# slurped " . length($got{$_}) . " bytes from $_\n");
407             }
408             print CT_ORIG_STDOUT $got{stdout}
409 1037600 50 100     5530351 if $do_stdout && $do_tee && $localize{stdout};
      66        
410             print CT_ORIG_STDERR $got{stderr}
411 1037600 50 100     4246976 if $do_stderr && $do_tee && $localize{stderr};
      66        
412             }
413 1037603         1300319 $? = $exit_code;
414 1037603 100       1554677 $@ = $inner_error if $inner_error;
415 1037603 100       1405236 die $outer_error if $outer_error;
416             # _debug( "# ending _capture_tee with (@_)...\n" );
417 1037602 100       1593084 return unless defined wantarray;
418 1037599         859342 my @return;
419 1037599 100       2208979 push @return, $got{stdout} if $do_stdout;
420 1037599 100 100     3836561 push @return, $got{stderr} if $do_stderr && ! $do_merge;
421 1037599         1052393 push @return, @result;
422 1037599 100       20775831 return wantarray ? @return : $return[0];
423             }
424              
425             1;
426              
427             __END__