Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Capture / Tiny.pm
1 # Copyright (c) 2009 by David Golden. All rights reserved.
2 # Licensed under Apache License, Version 2.0 (the "License").
3 # You may not use this file except in compliance with the License.
4 # A copy of the License was distributed with this file or you may obtain a 
5 # copy of the License from http://www.apache.org/licenses/LICENSE-2.0
6
7 package Capture::Tiny;
8 use 5.006;
9 use strict;
10 use warnings;
11 use Carp ();
12 use Exporter ();
13 use IO::Handle ();
14 use File::Spec ();
15 use File::Temp qw/tempfile tmpnam/;
16 # Get PerlIO or fake it
17 BEGIN { eval { require PerlIO; 1 } or *PerlIO::get_layers = sub { return () }; }
18
19 our $VERSION = '0.06';
20 $VERSION = eval $VERSION; ## no critic
21 our @ISA = qw/Exporter/;
22 our @EXPORT_OK = qw/capture capture_merged tee tee_merged/;
23 our %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
24
25 my $IS_WIN32 = $^O eq 'MSWin32';
26
27 our $DEBUG = $ENV{PERL_CAPTURE_TINY_DEBUG};
28 my $DEBUGFH;
29 open $DEBUGFH, ">&STDERR" if $DEBUG;
30
31 *_debug = $DEBUG ? sub(@) { print {$DEBUGFH} @_ } : sub(){0};
32
33 #--------------------------------------------------------------------------#
34 # command to tee output -- the argument is a filename that must
35 # be opened to signal that the process is ready to receive input.
36 # This is annoying, but seems to be the best that can be done
37 # as a simple, portable IPC technique
38 #--------------------------------------------------------------------------#
39 my @cmd = ($^X, '-e', '$SIG{HUP}=sub{exit}; ' 
40   . 'if( my $fn=shift ){ open my $fh, qq{>$fn}; print {$fh} $$; close $fh;} '
41   . 'my $buf; while (sysread(STDIN, $buf, 2048)) { '
42   . 'syswrite(STDOUT, $buf); syswrite(STDERR, $buf)}' 
43 );
44
45 #--------------------------------------------------------------------------#
46 # filehandle manipulation
47 #--------------------------------------------------------------------------#
48
49 sub _relayer {
50   my ($fh, $layers) = @_;
51   _debug("# requested layers (@{$layers}) to $fh\n");
52   my %seen;
53   my @unique = grep { $_ ne 'unix' and $_ ne 'perlio' and !$seen{$_}++ } @$layers;
54   _debug("# applying unique layers (@unique) to $fh\n");
55   binmode($fh, join(":", "", "raw", @unique));
56 }
57
58 sub _name {
59   my $glob = shift;
60   no strict 'refs'; ## no critic
61   return *{$glob}{NAME};
62 }
63
64 sub _open {
65   open $_[0], $_[1] or Carp::confess "Error from open(" . join(q{, }, @_) . "): $!";
66   _debug( "# open " . join( ", " , map { defined $_ ? _name($_) : 'undef' } @_ ) . " as " . fileno( $_[0] ) . "\n" );
67 }
68
69 sub _close {
70   close $_[0] or Carp::confess "Error from close(" . join(q{, }, @_) . "): $!";
71   _debug( "# closed " . ( defined $_[0] ? _name($_[0]) : 'undef' ) . "\n" );
72 }
73
74 my %dup; # cache this so STDIN stays fd0
75 my %proxy_count;  
76 sub _proxy_std {
77   my %proxies;
78   if ( ! defined fileno STDIN ) {
79     $proxy_count{stdin}++;
80     if (defined $dup{stdin}) {
81       _open \*STDIN, "<&=" . fileno($dup{stdin});
82       _debug( "# restored proxy STDIN as " . (defined fileno STDIN ? fileno STDIN : 'undef' ) . "\n" );
83     }
84     else {
85       _open \*STDIN, "<" . File::Spec->devnull;
86       _debug( "# proxied STDIN as " . (defined fileno STDIN ? fileno STDIN : 'undef' ) . "\n" );
87       _open $dup{stdin} = IO::Handle->new, "<&=STDIN";
88     }
89     $proxies{stdin} = \*STDIN;
90     binmode(STDIN, ':utf8') if $] >= 5.008;
91   }
92   if ( ! defined fileno STDOUT ) {
93     $proxy_count{stdout}++;
94     if (defined $dup{stdout}) {
95       _open \*STDOUT, ">&=" . fileno($dup{stdout});
96       _debug( "# restored proxy STDOUT as " . (defined fileno STDOUT ? fileno STDOUT : 'undef' ) . "\n" );
97     }
98     else {
99       _open \*STDOUT, ">" . File::Spec->devnull;
100       _debug( "# proxied STDOUT as " . (defined fileno STDOUT ? fileno STDOUT : 'undef' ) . "\n" );
101       _open $dup{stdout} = IO::Handle->new, ">&=STDOUT";
102     }
103     $proxies{stdout} = \*STDOUT;
104     binmode(STDOUT, ':utf8') if $] >= 5.008;
105   }
106   if ( ! defined fileno STDERR ) {
107     $proxy_count{stderr}++;
108     if (defined $dup{stderr}) {
109       _open \*STDERR, ">&=" . fileno($dup{stderr});
110       _debug( "# restored proxy STDERR as " . (defined fileno STDERR ? fileno STDERR : 'undef' ) . "\n" );
111     }
112     else {
113       _open \*STDERR, ">" . File::Spec->devnull;
114       _debug( "# proxied STDERR as " . (defined fileno STDERR ? fileno STDERR : 'undef' ) . "\n" );
115       _open $dup{stderr} = IO::Handle->new, ">&=STDERR";
116     }
117     $proxies{stderr} = \*STDERR;
118     binmode(STDERR, ':utf8') if $] >= 5.008;
119   }
120   return %proxies;
121 }
122
123 sub _unproxy {
124   my (%proxies) = @_;
125   _debug( "# unproxing " . join(" ", keys %proxies) . "\n" ); 
126   for my $p ( keys %proxies ) {
127     $proxy_count{$p}--;
128     _debug( "# unproxied " . uc($p) . " ($proxy_count{$p} left)\n" );
129     if ( ! $proxy_count{$p} ) {
130       _close $proxies{$p};
131       _close $dup{$p} unless $] < 5.008; # 5.6 will have already closed this as dup 
132       delete $dup{$p};
133     }
134   }
135 }
136
137 sub _copy_std {
138   my %handles = map { $_, IO::Handle->new } qw/stdin stdout stderr/;
139   _debug( "# copying std handles ...\n" ); 
140   _open $handles{stdin},   "<&STDIN"; 
141   _open $handles{stdout},  ">&STDOUT";
142   _open $handles{stderr},  ">&STDERR";
143   return \%handles;
144 }
145
146 sub _open_std {
147   my ($handles) = @_;
148   _open \*STDIN, "<&" . fileno $handles->{stdin};
149   _open \*STDOUT, ">&" . fileno $handles->{stdout};
150   _open \*STDERR, ">&" . fileno $handles->{stderr};
151 }
152
153 #--------------------------------------------------------------------------#
154 # private subs
155 #--------------------------------------------------------------------------#
156
157 sub _start_tee {
158   my ($which, $stash) = @_;
159   # setup pipes
160   $stash->{$_}{$which} = IO::Handle->new for qw/tee reader/;
161   pipe $stash->{reader}{$which}, $stash->{tee}{$which};
162   _debug( "# pipe for $which\: " .  _name($stash->{tee}{$which}) . " "  
163     . fileno( $stash->{tee}{$which} ) . " => " . _name($stash->{reader}{$which}) 
164     . " " . fileno( $stash->{reader}{$which}) . "\n" );
165   select((select($stash->{tee}{$which}), $|=1)[0]); # autoflush
166   # setup desired redirection for parent and child
167   $stash->{new}{$which} = $stash->{tee}{$which};
168   $stash->{child}{$which} = {
169     stdin   => $stash->{reader}{$which},
170     stdout  => $stash->{old}{$which},
171     stderr  => $stash->{capture}{$which},
172   };
173   # flag file is used to signal the child is ready
174   $stash->{flag_files}{$which} = scalar tmpnam();
175   # execute @cmd as a separate process
176   if ( $IS_WIN32 ) {
177     eval "use Win32API::File qw/CloseHandle GetOsFHandle SetHandleInformation fileLastError HANDLE_FLAG_INHERIT INVALID_HANDLE_VALUE/ ";
178     _debug( "# Win32API::File loaded\n") unless $@;
179     my $os_fhandle = GetOsFHandle( $stash->{tee}{$which} );
180     _debug( "# Couldn't get OS handle: " . fileLastError() . "\n") if ! defined $os_fhandle || $os_fhandle == INVALID_HANDLE_VALUE();
181     if ( SetHandleInformation( $os_fhandle, HANDLE_FLAG_INHERIT(), 0) ) {
182       _debug( "# set no-inherit flag on $which tee\n" );
183     }
184     else {
185       _debug( "# can't disable tee handle flag inherit: " . fileLastError() . "\n");
186     }
187     _open_std( $stash->{child}{$which} );
188     $stash->{pid}{$which} = system(1, @cmd, $stash->{flag_files}{$which});
189     # not restoring std here as it all gets redirected again shortly anyway
190   }
191   else { # use fork
192     _fork_exec( $which, $stash );
193   }
194 }
195
196 sub _fork_exec {
197   my ($which, $stash) = @_;
198   my $pid = fork; 
199   if ( not defined $pid ) {
200     Carp::confess "Couldn't fork(): $!";
201   }
202   elsif ($pid == 0) { # child
203     _debug( "# in child process ...\n" ); 
204     untie *STDIN; untie *STDOUT; untie *STDERR;
205     _close $stash->{tee}{$which};
206     _debug( "# redirecting handles in child ...\n" ); 
207     _open_std( $stash->{child}{$which} );
208     _debug( "# calling exec on command ...\n" ); 
209     exec @cmd, $stash->{flag_files}{$which};
210   }
211   $stash->{pid}{$which} = $pid
212 }
213
214 sub _files_exist { -f $_ || return 0 for @_; return 1 }
215
216 sub _wait_for_tees { 
217   my ($stash) = @_;
218   my $start = time;
219   my @files = values %{$stash->{flag_files}};
220   1 until _files_exist(@files) || (time - $start > 30);
221   Carp::confess "Timed out waiting for subprocesses to start" if ! _files_exist(@files);
222   unlink $_ for @files; 
223 }
224
225 sub _kill_tees {
226   my ($stash) = @_;
227   if ( $IS_WIN32 ) {
228     _debug( "# closing handles with CloseHandle\n");
229     CloseHandle( GetOsFHandle($_) ) for values %{ $stash->{tee} };
230     _debug( "# waiting for subprocesses to finish\n");
231     my $start = time;
232     1 until wait == -1 || (time - $start > 30);
233   }
234   else {
235     _close $_ for values %{ $stash->{tee} };
236     waitpid $_, 0 for values %{ $stash->{pid} };
237   }
238 }
239
240 sub _slurp { 
241   seek $_[0],0,0; local $/; return scalar readline $_[0]; 
242 }
243
244 #--------------------------------------------------------------------------#
245 # _capture_tee() -- generic main sub for capturing or teeing
246 #--------------------------------------------------------------------------#
247
248 sub _capture_tee {
249   _debug( "# starting _capture_tee with (@_)...\n" ); 
250   my ($tee_stdout, $tee_stderr, $merge, $code) = @_;
251   # save existing filehandles and setup captures
252   local *CT_ORIG_STDIN  = *STDIN ;
253   local *CT_ORIG_STDOUT = *STDOUT;
254   local *CT_ORIG_STDERR = *STDERR;
255   # find initial layers
256   my %layers = (
257     stdin   => [PerlIO::get_layers(\*STDIN) ],
258     stdout  => [PerlIO::get_layers(\*STDOUT)],
259     stderr  => [PerlIO::get_layers(\*STDERR)],
260   );
261   _debug( "# existing layers for $_\: @{$layers{$_}}\n" ) for qw/stdin stdout stderr/;
262   # bypass scalar filehandles and tied handles
263   my %localize;
264   $localize{stdin}++,  local(*STDIN)  if grep { $_ eq 'scalar' } @{$layers{stdin}};
265   $localize{stdout}++, local(*STDOUT) if grep { $_ eq 'scalar' } @{$layers{stdout}};
266   $localize{stderr}++, local(*STDERR) if grep { $_ eq 'scalar' } @{$layers{stderr}};
267   $localize{stdout}++, local(*STDOUT), _open( \*STDOUT, ">&=1") if tied *STDOUT && $] >= 5.008;
268   $localize{stderr}++, local(*STDERR), _open( \*STDERR, ">&=2") if tied *STDERR && $] >= 5.008;
269   _debug( "# localized $_\n" ) for keys %localize; 
270   my %proxy_std = _proxy_std();
271   _debug( "# proxy std is @{ [%proxy_std] }\n" );
272   my $stash = { old => _copy_std() };
273   # update layers after any proxying
274   %layers = (
275     stdin   => [PerlIO::get_layers(\*STDIN) ],
276     stdout  => [PerlIO::get_layers(\*STDOUT)],
277     stderr  => [PerlIO::get_layers(\*STDERR)],
278   );
279   _debug( "# post-proxy layers for $_\: @{$layers{$_}}\n" ) for qw/stdin stdout stderr/;
280   # get handles for capture and apply existing IO layers
281   $stash->{new}{$_} = $stash->{capture}{$_} = File::Temp->new for qw/stdout stderr/;
282   _debug("# will capture $_ on " .fileno($stash->{capture}{$_})."\n" ) for qw/stdout stderr/;
283   # tees may change $stash->{new}
284   _start_tee( stdout => $stash ) if $tee_stdout;
285   _start_tee( stderr => $stash ) if $tee_stderr;
286   _wait_for_tees( $stash ) if $tee_stdout || $tee_stderr;
287   # finalize redirection
288   $stash->{new}{stderr} = $stash->{new}{stdout} if $merge;
289   $stash->{new}{stdin} = $stash->{old}{stdin};
290   _debug( "# redirecting in parent ...\n" ); 
291   _open_std( $stash->{new} );
292   # execute user provided code
293   my $exit_code;
294   {
295     local *STDIN = *CT_ORIG_STDIN if $localize{stdin}; # get original, not proxy STDIN
296     local *STDERR = *STDOUT if $merge; # minimize buffer mixups during $code
297     _debug( "# finalizing layers ...\n" ); 
298     _relayer(\*STDOUT, $layers{stdout});
299     _relayer(\*STDERR, $layers{stderr}) unless $merge;
300     _debug( "# running code $code ...\n" ); 
301     $code->();
302     $exit_code = $?; # save this for later
303   }
304   # restore prior filehandles and shut down tees
305   _debug( "# restoring ...\n" ); 
306   _open_std( $stash->{old} );
307   _close( $_ ) for values %{$stash->{old}}; # don't leak fds
308   _unproxy( %proxy_std );
309   _kill_tees( $stash ) if $tee_stdout || $tee_stderr;
310   # return captured output
311   _relayer($stash->{capture}{stdout}, $layers{stdout});
312   _relayer($stash->{capture}{stderr}, $layers{stderr}) unless $merge;
313   _debug( "# slurping captured $_ with layers: @{[PerlIO::get_layers($stash->{capture}{$_})]}\n") for qw/stdout stderr/;
314   my $got_out = _slurp($stash->{capture}{stdout});
315   my $got_err = $merge ? q() : _slurp($stash->{capture}{stderr});
316   print CT_ORIG_STDOUT $got_out if $localize{stdout} && $tee_stdout; 
317   print CT_ORIG_STDERR $got_err if !$merge && $localize{stderr} && $tee_stdout; 
318   $? = $exit_code;
319   _debug( "# ending _capture_tee with (@_)...\n" ); 
320   return $got_out if $merge;
321   return wantarray ? ($got_out, $got_err) : $got_out;
322 }
323
324 #--------------------------------------------------------------------------#
325 # create API subroutines from [tee STDOUT flag, tee STDERR, merge flag]               
326 #--------------------------------------------------------------------------#
327
328 my %api = (
329   capture         => [0,0,0],
330   capture_merged  => [0,0,1],
331   tee             => [1,1,0],
332   tee_merged      => [1,0,1], # don't tee STDOUT since merging
333 );
334
335 for my $sub ( keys %api ) {
336   my $args = join q{, }, @{$api{$sub}}; 
337   eval "sub $sub(&) {unshift \@_, $args; goto \\&_capture_tee;}"; ## no critic
338 }
339
340 1;
341
342 __END__
343
344 =begin wikidoc
345
346 = NAME
347
348 Capture::Tiny - Capture STDOUT and STDERR from Perl, XS or external programs
349
350 = VERSION
351
352 This documentation describes version %%VERSION%%.
353
354 = SYNOPSIS
355
356     use Capture::Tiny qw/capture tee capture_merged tee_merged/;
357
358     ($stdout, $stderr) = capture {
359       # your code here
360     };
361
362     ($stdout, $stderr) = tee {
363       # your code here
364     };
365
366     $merged = capture_merged {
367       # your code here
368     };
369
370     $merged = tee_merged {
371       # your code here
372     };
373
374 = DESCRIPTION
375
376 Capture::Tiny provides a simple, portable way to capture anything sent to
377 STDOUT or STDERR, regardless of whether it comes from Perl, from XS code or
378 from an external program.  Optionally, output can be teed so that it is
379 captured while being passed through to the original handles.  Yes, it even
380 works on Windows.  Stop guessing which of a dozen capturing modules to use in
381 any particular situation and just use this one.
382
383 This module was heavily inspired by [IO::CaptureOutput], which provides
384 similar functionality without the ability to tee output and with more
385 complicated code and API.
386
387 = USAGE
388
389 The following functions are available.  None are exported by default.
390
391 == capture
392
393   ($stdout, $stderr) = capture \&code;
394   $stdout = capture \&code;
395
396 The {capture} function takes a code reference and returns what is sent to
397 STDOUT and STDERR.  In scalar context, it returns only STDOUT.  If no output
398 was received, returns an empty string.  Regardless of context, all output is
399 captured -- nothing is passed to the existing handles.
400
401 It is prototyped to take a subroutine reference as an argument. Thus, it
402 can be called in block form:
403
404   ($stdout, $stderr) = capture {
405     # your code here ...
406   };
407
408 == capture_merged
409
410   $merged = capture_merged \&code;
411
412 The {capture_merged} function works just like {capture} except STDOUT and
413 STDERR are merged. (Technically, STDERR is redirected to STDOUT before
414 executing the function.)  If no output was received, returns an empty string.
415 As with {capture} it may be called in block form.
416
417 Caution: STDOUT and STDERR output in the merged result are not guaranteed to be
418 properly ordered due to buffering.
419
420 == tee
421
422   ($stdout, $stderr) = tee \&code;
423   $stdout = tee \&code;
424
425 The {tee} function works just like {capture}, except that output is captured
426 as well as passed on to the original STDOUT and STDERR.  As with {capture} it
427 may be called in block form.
428
429 == tee_merged
430
431   $merged = tee_merged \&code;
432
433 The {tee_merged} function works just like {capture_merged} except that output
434 is captured as well as passed on to STDOUT.  As with {capture} it may be called
435 in block form.
436
437 Caution: STDOUT and STDERR output in the merged result are not guaranteed to be
438 properly ordered due to buffering.
439
440 = LIMITATIONS
441
442 == Portability
443
444 Portability is a goal, not a guarantee.  {tee} requires fork, except on
445 Windows where {system(1, @cmd)} is used instead.  Not tested on any
446 particularly esoteric platforms yet.
447
448 == PerlIO layers
449
450 Capture::Tiny does it's best to preserve PerlIO layers such as ':utf8' or
451 ':crlf' when capturing.   Layers should be applied to STDOUT or STDERR ~before~
452 the call to {capture} or {tee}.
453
454 == Closed STDIN, STDOUT or STDERR
455
456 Capture::Tiny will work even if STDIN, STDOUT or STDERR have been previously
457 closed.  However, since they may be reopened to capture or tee output, any code
458 within the captured block that depends on finding them closed will, of course,
459 not find them to be closed.  If they started closed, Capture::Tiny will reclose
460 them again when the capture block finishes.
461
462 ==  Scalar filehandles and STDIN, STDOUT or STDERR
463
464 If STDOUT or STDERR are reopened to scalar filehandles prior to the call to
465 {capture} or {tee}, then Capture::Tiny will override the output handle for the
466 duration of the {capture} or {tee} call and then send captured output to the
467 output handle after the capture is complete.  (Requires Perl 5.8)
468
469 Capture::Tiny attempts to preserve the semantics of STDIN opened to a scalar
470 reference.
471
472 ==  Tied STDIN, STDOUT or STDERR
473
474 If STDOUT or STDERR are tied prior to the call to {capture} or {tee}, then
475 Capture::Tiny will attempt to override the tie for the duration of the
476 {capture} or {tee} call and then send captured output to the tied handle after
477 the capture is complete.  (Requires Perl 5.8)
478
479 Capture::Tiny does not (yet) support resending utf8 encoded data to a tied
480 STDOUT or STDERR handle.  Characters will appear as bytes.
481
482 Capture::Tiny attempts to preserve the semantics of tied STDIN, but capturing
483 or teeing when STDIN is tied is currently broken on Windows.
484
485 == Modifiying STDIN, STDOUT or STDERR during a capture
486
487 Attempting to modify STDIN, STDOUT or STDERR ~during~ {capture} or {tee} is
488 almost certainly going to cause problems.  Don't do that.
489
490 = BUGS
491
492 Please report any bugs or feature requests using the CPAN Request Tracker.
493 Bugs can be submitted through the web interface at
494 [http://rt.cpan.org/Dist/Display.html?Queue=Capture-Tiny]
495
496 When submitting a bug or request, please include a test-file or a patch to an
497 existing test-file that illustrates the bug or desired feature.
498
499 = SEE ALSO
500
501 This is a selection of CPAN modules that provide some sort of output capture,
502 albeit with various limitations that make them appropriate only in particular
503 circumstances.  I'm probably missing some.  The long list is provided to show
504 why I felt Capture::Tiny was necessary.
505
506 * [IO::Capture]
507 * [IO::Capture::Extended]
508 * [IO::CaptureOutput]
509 * [IPC::Capture]
510 * [IPC::Cmd]
511 * [IPC::Open2]
512 * [IPC::Open3]
513 * [IPC::Open3::Simple]
514 * [IPC::Open3::Utils]
515 * [IPC::Run]
516 * [IPC::Run::SafeHandles]
517 * [IPC::Run::Simple]
518 * [IPC::Run3]
519 * [IPC::System::Simple]
520 * [Tee]
521 * [IO::Tee]
522 * [File::Tee]
523 * [Filter::Handle]
524 * [Tie::STDERR]
525 * [Tie::STDOUT]
526 * [Test::Output]
527
528 = AUTHOR
529
530 David A. Golden (DAGOLDEN)
531
532 = COPYRIGHT AND LICENSE
533
534 Copyright (c) 2009 by David A. Golden. All rights reserved.
535
536 Licensed under Apache License, Version 2.0 (the "License").  You may not use
537 this file except in compliance with the License.  A copy of the License was
538 distributed with this file or you may obtain a copy of the License from
539 http://www.apache.org/licenses/LICENSE-2.0
540
541 Files produced as output though the use of this software, shall not be
542 considered Derivative Works, but shall be considered the original work of the
543 Licensor.
544
545 Unless required by applicable law or agreed to in writing, software
546 distributed under the License is distributed on an "AS IS" BASIS,
547 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
548 See the License for the specific language governing permissions and
549 limitations under the License.
550
551 =end wikidoc
552
553 =cut
554