IO-CaptureOutput-1.1102000755001750001750 011336240130 14261 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/MANIFEST000444001750001750 65411336240130 15534 0ustar00daviddavid000000000000Build.PL Changes examples/capture.pl inc/Module/Build/DAGOLDEN.pm INSTALL lib/IO/CaptureOutput.pm lib/IO/CaptureOutput.pod LICENSE Makefile.PL MANIFEST MANIFEST.SKIP META.yml Module meta-data (added by MakeMaker) README t/capture.t t/capture_exec.t t/capture_file.t t/errors.t t/noconsole.t t/scripts/wperl-capture.pl t/scripts/wperl-exec.pl t/wperl.t Todo xt/critic.t xt/perlcriticrc xt/pod-coverage.t xt/pod.t xt/spelling.t IO-CaptureOutput-1.1102/META.yml000444001750001750 135011336240130 15666 0ustar00daviddavid000000000000--- abstract: 'capture STDOUT and STDERR from Perl code, subprocesses or XS' author: - 'David A. Golden ' build_requires: File::Spec: 3.27 IO::File: 0 Test::More: 0.62 configure_requires: Module::Build: 0.36 generated_by: 'Module::Build version 0.3603' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: IO-CaptureOutput no_index: directory: - examples - inc provides: IO::CaptureOutput: file: lib/IO/CaptureOutput.pm version: 1.1102 requires: Carp: 0 Exporter: 0 File::Basename: 0 File::Temp: 0.16 Symbol: 0 resources: license: http://dev.perl.org/licenses/ repository: http://dagolden.googlecode.com/svn/ version: 1.1102 IO-CaptureOutput-1.1102/MANIFEST.SKIP000444001750001750 100011336240130 16303 0ustar00daviddavid000000000000# Version control files and dirs. \bRCS\b \bCVS\b ,v$ .svn/ .git/ .gitignore # ExtUtils::MakeMaker generated files and dirs. ^MANIFEST\.(?!SKIP) ^Makefile$ ^blib/ ^blibdirs$ ^PM_to_blib$ ^pm_to_blib$ ^MakeMaker-\d # Inline::C from testing ^_Inline # Module::Build ^Build$ ^_build .bat$ # Coverage ^cover_db # Temp, old, vi and emacs files. ~$ \.old$ ^#.*#$ ^\.# \.swp$ \.bak$ \.tmp$ ^MYMETA IO-CaptureOutput-1.1102/Todo000444001750001750 54711336240130 15234 0ustar00daviddavid000000000000# Todo for IO::CaptureOutput #--------------------------------------------------------------------------# # Bugs #--------------------------------------------------------------------------# #--------------------------------------------------------------------------# # Features #--------------------------------------------------------------------------# IO-CaptureOutput-1.1102/README000444001750001750 1454611336240130 15330 0ustar00daviddavid000000000000NAME IO::CaptureOutput - capture STDOUT and STDERR from Perl code, subprocesses or XS VERSION This documentation describes version 1.1102. SYNOPSIS use IO::CaptureOutput qw(capture qxx qxy); # STDOUT and STDERR separately capture { noisy_sub(@args) } \$stdout, \$stderr; # STDOUT and STDERR together capture { noisy_sub(@args) } \$combined, \$combined; # STDOUT and STDERR from external command ($stdout, $stderr, $success) = qxx( @cmd ); # STDOUT and STDERR together from external command ($combined, $success) = qxy( @cmd ); DESCRIPTION This module provides routines for capturing STDOUT and STDERR from perl subroutines, forked system calls (e.g. "system()", "fork()") and from XS or C modules. FUNCTIONS The following functions will be exported on demand. capture() capture \&subroutine, \$stdout, \$stderr; Captures everything printed to "STDOUT" and "STDERR" for the duration of &subroutine. $stdout and $stderr are optional scalars that will contain "STDOUT" and "STDERR" respectively. "capture()" uses a code prototype so the first argument can be specified directly within brackets if desired. # shorthand with prototype capture { print __PACKAGE__ } \$stdout, \$stderr; Returns the return value(s) of &subroutine. The sub is called in the same context as "capture()" was called e.g.: @rv = capture { wantarray } ; # returns true $rv = capture { wantarray } ; # returns defined, but not true capture { wantarray }; # void, returns undef "capture()" is able to capture output from subprocesses and C code, which traditional "tie()" methods of output capture are unable to do. Note: "capture()" will only capture output that has been written or flushed to the filehandle. If the two scalar references refer to the same scalar, then "STDERR" will be merged to "STDOUT" before capturing and the scalar will hold the combined output of both. capture \&subroutine, \$combined, \$combined; Normally, "capture()" uses anonymous, temporary files for capturing output. If desired, specific file names may be provided instead as additional options. capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; Files provided will be clobbered, overwriting any previous data, but will persist after the call to "capture()" for inspection or other manipulation. By default, when no references are provided to hold STDOUT or STDERR, output is captured and silently discarded. # Capture STDOUT, discard STDERR capture \&subroutine, \$stdout; # Discard STDOUT, capture STDERR capture \&subroutine, undef, \$stderr; However, even when using "undef", output can be captured to specific files. # Capture STDOUT to a specific file, discard STDERR capture \&subroutine, \$stdout, undef, $outfile; # Discard STDOUT, capture STDERR to a specific file capture \&subroutine, undef, \$stderr, undef, $err_file; # Discard both, capture merged output to a specific file capture \&subroutine, undef, undef, $mergedfile; It is a fatal error to merge STDOUT and STDERR and request separate, specific files for capture. # ERROR: capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; capture \&subroutine, undef, undef, $out_file, $err_file; If either STDOUT or STDERR should be passed through to the terminal instead of captured, provide a reference to undef -- "\undef" -- instead of a capture variable. # Capture STDOUT, display STDERR capture \&subroutine, \$stdout, \undef; # Display STDOUT, capture STDERR capture \&subroutine, \undef, \$stderr; capture_exec() ($stdout, $stderr, $success, $exit_code) = capture_exec(@args); Captures and returns the output from "system(@args)". In scalar context, "capture_exec()" will return what was printed to "STDOUT". In list context, it returns what was printed to "STDOUT" and "STDERR" as well as a success flag and the exit value. $stdout = capture_exec('perl', '-e', 'print "hello world"'); ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test"'); "capture_exec" passes its arguments to "system()" and on MSWin32 will protect arguments with shell quotes if necessary. This makes it a handy and slightly more portable alternative to backticks, piped "open()" and "IPC::Open3". The $success flag returned will be true if the command ran successfully and false if it did not (if the command could not be run or if it ran and returned a non-zero exit value). On failure, the raw exit value of the "system()" call is available both in the $exit_code returned and in the $? variable. ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test" and exit 1'); if ( ! $success ) { print "The exit code was " . ($exit_code >> 8) . "\n"; } See perlvar for more information on interpreting a child process exit code. capture_exec_combined() ($combined, $success, $exit_code) = capture_exec_combined( 'perl', '-e', 'print "hello\n"', 'warn "Test\n" ); This is just like "capture_exec()", except that it merges "STDERR" with "STDOUT" before capturing output. Note: there is no guarantee that text printed to "STDOUT" and "STDERR" in the subprocess will be appear in order. The actual order will depend on how IO buffering is handled in the subprocess. qxx() This is an alias for "capture_exec()". qxy() This is an alias for "capture_exec_combined()". SEE ALSO * IPC::Open3 * IO::Capture * IO::Utils * IPC::System::Simple AUTHORS * Simon Flack (original author) * David Golden (co-maintainer since version 1.04) COPYRIGHT AND LICENSE Portions copyright 2004, 2005 Simon Flack. Portions copyright 2007, 2008 David Golden. All rights reserved. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. IO-CaptureOutput-1.1102/Build.PL000444001750001750 172311336240130 15715 0ustar00daviddavid000000000000use strict; use lib 'inc'; use Module::Build::DAGOLDEN; my $build = Module::Build::DAGOLDEN->new( module_name => 'IO::CaptureOutput', dist_author => 'David A. Golden ', license => 'perl', create_readme => 1, create_makefile_pl => 'traditional', requires => { 'Carp' => 0, 'Exporter' => 0, 'File::Basename' => 0, 'File::Temp' => 0.16, # many bug fixes 'Symbol' => 0, }, build_requires => { 'File::Spec' => 3.27, # many bug fixes 'Test::More' => 0.62, # newer API 'IO::File' => 0, }, add_to_cleanup => [ '_Inline' ], meta_merge => { no_index => { directory => [ qw{ examples inc }], }, resources => { repository => 'http://dagolden.googlecode.com/svn/' }, }, ); $build->create_build_script; IO-CaptureOutput-1.1102/Makefile.PL000444001750001750 135011336240130 16367 0ustar00daviddavid000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.3603 use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'IO::CaptureOutput', 'VERSION_FROM' => 'lib/IO/CaptureOutput.pm', 'PREREQ_PM' => { 'Carp' => 0, 'Exporter' => 0, 'File::Basename' => 0, 'File::Spec' => '3.27', 'File::Temp' => '0.16', 'IO::File' => 0, 'Symbol' => 0, 'Test::More' => '0.62' }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {} ) ; IO-CaptureOutput-1.1102/Changes000444001750001750 1146211336240130 15735 0ustar00daviddavid000000000000Revision history for IO::CaptureOutput 1.1102 Mon Feb 15 07:36:53 EST 2010 - Fixed test that confused archname and osname (reported by Tux) 1.1101 Tue Mar 3 23:30:45 EST 2009 - Fixed Makefile.PL; no functional changes 1.11 Mon Feb 9 21:47:37 EST 2009 - Fixed: bug in creation of STDERR capture proxy object 1.1001 Tue Jan 20 18:32:27 EST 2009 - Test fix: marked some wperl.exe tests as TODO on Windows Vista/Win7 1.10 Sun Sep 21 09:34:31 EDT 2008 - Added: functions to capture output from external command now also return a success flag and the exit code - Documented: shorter, punchier synopsis 1.09 Thu Jul 3 09:17:35 EDT 2008 - Added: parameter validation and error messages - Documented: examples of capturing only to a file and parameter errors 1.08_50 Mon May 19 23:19:01 EDT 2008 - Changed: doesn't bother to read captured output back from file if no scalar reference is provided to receive it - Fixed: 'capture { .. } undef, undef, $capture_file' now correctly merges STDOUT and STDERR 1.0801 Sat Feb 9 09:41:11 EST 2008 - testfix: skip some error handling tests if temp files can't be made read-only (e.g. running test as root) - added some prerequisites and meta information to Build.PL - added an 'examples' directory 1.08 Wed Feb 6 22:43:37 EST 2008 - added additional tests and revised documentation 1.07_01 Wed Jan 30 20:57:15 EST 2008 - added support for capturing to named files instead of anonymous temporary ones (adapted from patch from Anton Berezin) - added support to pass through STDOUT or STDERR without capture while capturing the other one (adapted from patch from Anton Berezin) 1.0601 Sun Dec 30 17:31:31 EST 2007 - relaxed capture_exec.t to avoid failing under noisy perl configurations 1.06 Mon, 26 Nov 2007 16:40:40 EST - no changes from 1.05_53 1.05_53 Sat Nov 17 18:45:08 EST 2007 - MSVC++ fixes for Inline::C testing breaks on other compilers; this version uses separate C routines for MSVC++ and other compilers 1.05_52 Sat Nov 17 14:47:52 EST 2007 - changed Inline::C code for printing to stdout to match that for stderr; works around a bug if the intalled MSVC++ version doesn't match the version used to build ActiveState Perl on MSWin32. 1.05_51 Sat Nov 17 13:36:39 EST 2007 - changed Inline::C code for printing to stderr to attempt to work around a segfault bug on some MSWin32 systems (Alternative described by BrowserUK at http://www.perlmonks.org/?node_id=649021 ) - minor Perl::Critic cleanup to pass xt tests 1.05 Fri Nov 16 08:44:06 EST 2007 *** No changes since 1.04_03; key changes since 1.03 follows *** - added support for capture() merging STDERR and STDOUT to the same scalar, i.e. "capture( \&foo, \$out, \$out )" (RT#24695) - added capture_exec_combined() and alias qxy() to merge STDERR and STDOUT for subprocess execution (RT#29289) - bugfix: stop crashing if output filehandles are previously closed or if running without a console on MSWin32 (i.e. wperl.exe) (RT#23676) - bugfix: capture.t would fail on Win32 if Inline::C was installed; fixed the sample C code used in testing to flush stderr (RT#21712) - bugfix: was failing on perl 5.8.0 due to extraneous space in call to open(); removing the space fixed the bug (RT#22044) 1.04_03 Sun Nov 4 11:35:57 EST 2007 - suppress warnings included in captured output when console output handles were previously closed; only affects some versions/builds of perl on some platforms (found by Slaven Rezic 5.6.2 on FreeBSD 6.2) 1.04_02 Wed Oct 31 00:52:49 EDT 2007 - added support for capture() merging STDERR and STDOUT to the same scalar, i.e. "capture( \&foo, \$out, \$out )" (RT#24695) - added capture_exec_combined() and alias qxy() to merge STDERR and STDOUT for subprocess execution (RT#29289) - bugfix: stop crashing if output filehandles are previously closed or if running without a console on MSWin32 (i.e. wperl.exe) (RT#23676) - cleaned up documentation for consistency 1.04_01 Mon Oct 29 22:56:45 EDT 2007 - DAGOLDEN added as maintainer; updated build system and packaging for ongoing maintenance - bugfix: capture.t would fail on Win32 if Inline::C was installed; fixed the sample C code used in testing to flush stderr (RT#21712) - bugfix: was failing on perl 5.8.0 due to extraneous space in call to open(); removing the space fixed the bug (RT#22044) 1.03 2005-03-25 - Add t/pod_coverage.t 1.02 2004-11-22 - add extra quoting on Win32 platform - Win32 won't unlink a file that is open in write mode, so close it first - minor POD tweaks 1.0 2004-11-21 - Initial revision IO-CaptureOutput-1.1102/INSTALL000444001750001750 47211336240130 15432 0ustar00daviddavid000000000000INSTALLATION If Module::Build is installed (preferred): perl Build.PL perl Build perl Build test perl Build install Otherwise, using a Makefile: perl Makefile.PL make make test make install If you are on a Windows machine you should use 'nmake' or 'dmake' rather than 'make'. IO-CaptureOutput-1.1102/LICENSE000444001750001750 3723311336240130 15453 0ustar00daviddavid000000000000License terms of Perl itself This program is free software; you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" which comes with this Kit. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the Artistic License for more details. --------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS --------------------------------------------------------------------------- The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End IO-CaptureOutput-1.1102/t000755001750001750 011336240130 14524 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/t/wperl.t000444001750001750 270711336240130 16205 0ustar00daviddavid000000000000use strict; use IO::File; use File::Temp 0.16 (); use File::Spec; use Test::More; if ( $^O ne 'MSWin32' ) { plan skip_all => "not MSWin32"; } ( my $wperl = $^X ) =~ s/perl\.exe$/wperl.exe/i; if ( ! -x $wperl ) { plan skip_all => "no wperl.exe found"; } sub _is_vista { require Win32; my (undef, $major, $minor, $build, $id) = Win32::GetOSVersion(); return $id == 2 && $major > 5; # 2 for NT, 6 is 2k/XP/Server 2003 } #--------------------------------------------------------------------------# # test scripts #--------------------------------------------------------------------------# my @scripts = qw( wperl-capture.pl wperl-exec.pl ); plan tests => 2 * @scripts; #--------------------------------------------------------------------------# # loop over scripts and pass a filename for output #--------------------------------------------------------------------------# for my $pl ( @scripts ) { TODO: { local $TODO = "wperl.exe can't capture child process output on Vista or Win7" if _is_vista() && $pl eq 'wperl-exec.pl'; my $pl_path = File::Spec->catfile('t', 'scripts', $pl); my $outputname = File::Temp->new(); $outputname->close; # avoid Win32 locking it read-only system($wperl, $pl_path, $outputname); is( $?, 0, "'$pl' no error"); my $result = IO::File->new( $outputname ); is_deeply( [ <$result> ], ["STDOUT\n", "STDERR\n"], "'$pl' capture correct" ); } } IO-CaptureOutput-1.1102/t/capture_exec.t000555001750001750 713211336240130 17523 0ustar00daviddavid000000000000#!/usr/bin/perl -w use strict; use Test::More; plan tests => 31; use IO::CaptureOutput qw/capture_exec capture_exec_combined qxx qxy/; my ($out, $err, $suc, $ec); my @perl_e = ($^X, '-e'); # perl -e sub _reset { $_ = '' for ($out, $err); undef $suc; undef $ec; 1}; # low-level debugging #print capture_exec($^X, '-e', 'print join "|", @ARGV'), "\n"; #print join '|', IO::CaptureOutput::_shell_quote($^X, '-e', 'print join "|", @ARGV'), "\n"; # simple test ($out, $err, $suc, $ec) = capture_exec(@perl_e, q[print 'Hello World!'; print STDERR "PID=$$"]); is($out, 'Hello World!', 'capture_exec() caught stdout from external command'); like($err, '/PID=\d+/', 'capture_exec() caught stderr from external command'); ok($suc, 'capture_exec() returned success'); is($ec >> 8, 0, 'capture_exec() exit value'); # with alias _reset; ($out, $err, $suc, $ec) = qxx(@perl_e, q[print 'Hello World!'; print STDERR "PID=$$"]); is($out, 'Hello World!', 'capture_exec() caught stdout from external command'); like($err, '/PID=\d+/', 'capture_exec() caught stderr from external command'); ok($suc, 'capture_exec() returned success'); is($ec >> 8, 0, 'capture_exec() exit value'); # check exit code of system() _reset; ($out, $err, $suc, $ec) = capture_exec(@perl_e, 'print "ok"'); ok($out eq 'ok' && $? == 0, '$? set to 0 after successful execution'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); _reset; ($out, $err, $suc, $ec) = capture_exec(@perl_e, 'exit 5'); is($? >> 8, 5, '$? contains child error after failed execution'); ok(!$suc, 'returned success flag correct on exit N'); is($ec >> 8, 5, 'returned exit value correct on exit N'); # check that output is returned if called in scalar context _reset; $out = capture_exec(@perl_e, 'print "stdout"; print STDERR "stderr"'); is($out, 'stdout', 'capture_exec() returns stdout in scalar context'); # merge STDOUT and STDERR _reset; ($out, $suc, $ec) = capture_exec_combined(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); # with alias _reset; ($out, $suc, $ec) = qxy(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); # check exit code of system() _reset; ($out, $suc, $ec) = qxy(@perl_e, 'print "ok"'); ok($out eq 'ok' && $? == 0, '$? set to 0 after successful execution'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); _reset; ($out, $suc, $ec) = qxy(@perl_e, 'exit 5'); is($? >> 8, 5, '$? contains child error after failed execution'); ok(!$suc, 'returned success flag correct on exit N'); is($ec >> 8, 5, 'returned exit value correct on exit N'); # merge STDOUT and STDERR _reset; $out = capture_exec_combined(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); IO-CaptureOutput-1.1102/t/errors.t000444001750001750 225211336240130 16363 0ustar00daviddavid000000000000use strict; use Test::More; use IO::CaptureOutput qw/capture/; use File::Temp qw/tempfile/; use Config; # save output to specified files my ($out, $err); (undef, my $saved_out) = tempfile; unlink $saved_out; (undef, my $saved_err) = tempfile; unlink $saved_err; sub _reset { $_ = '' for ($out, $err); 1}; sub _print_stuff { print __PACKAGE__; print STDERR __FILE__} my @valid_args = ( q[ ], q[ \$out ], q[ undef, \$err ], q[ \$out, \$err ], q[ \$out, \$out ], q[ undef, undef ], q[ \$out, undef, $saved_out ], q[ \$out, undef, $saved_out, $saved_err ], q[ undef, \$err, undef, $saved_err ], q[ undef, \$err, $saved_out, $saved_err ], q[ \$out, \$err, $saved_out, $saved_err ], q[ \$out, \$out, $saved_out, $saved_out ], q[ undef, undef, $saved_out, $saved_out ], ); my @invalid_args = ( q[ \$out, \$out, $saved_out, $saved_err ], q[ undef, undef, $saved_out, $saved_err ], ); plan tests => @valid_args + @invalid_args; for my $arg ( @valid_args ) { _reset; eval "capture { _print_stuff() } $arg"; is( $@, q{}, "no error: '$arg'" ); } for my $arg ( @invalid_args ) { _reset; eval "capture { _print_stuff() } $arg"; ok( $@, "error: '$arg'" ); } IO-CaptureOutput-1.1102/t/noconsole.t000444001750001750 332211336240130 17045 0ustar00daviddavid000000000000use strict; use Symbol qw/gensym/; my ($save_out, $save_err); BEGIN { $save_out = gensym(); $save_err = gensym(); open $save_out, ">&main::STDOUT"; open $save_err, ">&main::STDERR"; } use Test::More tests => 7; #--------------------------------------------------------------------------# # close and restore console #--------------------------------------------------------------------------# sub _close_console { close STDOUT or die "Can't close STDOUT"; close STDERR or die "Can't close STDERR"; return; } sub _restore_console { open STDOUT, ">&" . fileno($save_out) or die "Can't restore STDOUT"; open STDERR, ">&" . fileno($save_err) or die "Can't restore STDERR"; return; } #--------------------------------------------------------------------------# # _test_print #--------------------------------------------------------------------------# sub _test_print { print STDOUT "Test to STDOUT\n"; print STDERR "Test to STDERR\n"; return; } #--------------------------------------------------------------------------# my ($stdout, $stderr, $err); BEGIN{ use_ok("IO::CaptureOutput", "capture") } eval { capture \&_test_print, \$stdout, \$stderr; }; $err = $@; is( $err, q{}, "no errors capturing with console open" ); is( $stdout, "Test to STDOUT\n", "STDOUT test with console open" ); is( $stderr, "Test to STDERR\n", "STDERR test with console open" ); $stdout = $stderr = q{}; _close_console; eval { capture \&_test_print, \$stdout, \$stderr; }; $err = $@; _restore_console; is( $err, q{}, "no errors capturing with console closed" ); is( $stdout, "Test to STDOUT\n", "STDOUT test with console closed" ); is( $stderr, "Test to STDERR\n", "STDERR test with console closed" ); IO-CaptureOutput-1.1102/t/capture.t000555001750001750 1123211336240130 16533 0ustar00daviddavid000000000000#!/usr/bin/perl -w #$Id: capture.t,v 1.3 2004/11/22 19:51:09 simonflack Exp $ use strict; use Test::More tests => 21; use IO::CaptureOutput qw/capture/; use Config; my $is_cl = $Config{cc} =~ /cl/i; my ($out, $err, $out2, $err2); sub _reset { $_ = '' for ($out, $err, $out2, $err2); 1}; # Basic test _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err; is($out, __PACKAGE__, 'captured stdout from perl function'); is($err, __FILE__, 'captured stderr from perl function'); # merge STDOUT and STDERR _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$out; like($out, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'captured stdout into one scalar'); like($out, q{/} . quotemeta(__FILE__) . q{$/}, 'captured stderr into same scalar'); # nesting and passing ref to undef to get passthrough _reset && capture sub { capture sub { print __PACKAGE__; print STDERR __FILE__}, \undef, \$err2; }, \$out, \$err; like($out, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'stdout passed through to outer capture'); like($err2, q{/} . quotemeta(__FILE__) . q{$/}, 'captured stderr in inner'); is($err, q{}, 'outer stderr empty'); # repeat with error _reset && capture sub { capture sub { print __PACKAGE__; print STDERR __FILE__}, \$out2, \undef; }, \$out, \$err; like($out2, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'captured stdout in inner'); like($err, q{/} . quotemeta(__FILE__) . q{$/}, 'stderr passed through to outer capture'); is($out, q{}, 'outer stdout empty'); # Check we still get return values _reset; my @arg = capture sub {print 'Testing'; return (1,2,3)}, \$out, \$err; ok($out eq 'Testing' && eq_array(\@arg, [1,2,3]), 'capture() proxies the return values'); # Check that the captured sub is called in the right context my $context = capture sub {wantarray}; ok(defined $context && ! $context, 'capture() calls subroutine in scalar context when appropriate'); ($context) = capture sub {wantarray}; ok($context, 'capture() calls subroutine in list context when appropriate'); capture sub {$context = wantarray}; ok(! defined($context), 'capture() calls subroutine in void context when appropriate'); # Test external program, see t/capture_exec.t for more _reset; capture sub {system($^X, '-V:osname')}, \$out; like($out, "/$^O/", 'capture() caught stdout from external command'); # check we still get stdout/stderr if the code dies eval { capture sub {print "."; print STDERR "5..4..3..2..1.."; die "self-terminating"}, \$out,\$err; }; like($@, "/^self-terminating at " . quotemeta(__FILE__) . "/", '$@ still available after capture'); ok($out eq '.' && $err eq '5..4..3..2..1..', 'capture() still populates output and error variables if the code dies'); # test fork() sub forked_output { fork or do { print "forked"; print STDERR "Child pid $$"; exit; }; select undef, undef, undef, 0.2; } capture \&forked_output, \$out, \$err; ok($out eq 'forked' && $err =~ /^Child pid /, 'capture() traps fork() output'); # Test printing via C code SKIP: { eval "require Inline::C"; skip "Inline::C not available", 3 if $@; eval { my $c_code = do {local $/; }; # Inline->bind( 'C' => $c_code, FORCE_BUILD => 1, BUILD_NOISY => 1 ); Inline->bind( 'C' => $c_code, FORCE_BUILD => 1); }; skip "Inline->bind failed : $@", 3 if $@; ok(test_inline_c(), 'Inline->bind succeeded'); _reset && capture sub { $is_cl ? cl_print_stdout("Hello World") : print_stdout("Hello World"); }, \$out, \$err; is($out, 'Hello World', 'captured stdout from C function'); _reset && capture sub { $is_cl ? cl_print_stderr("Testing stderr") : print_stderr("Testing stderr"); }, \$out, \$err; is($err, 'Testing stderr', 'captured stderr from C function'); } __DATA__ // A basic sub to test that the bind() succeeded #include int test_inline_c () { return 42; } // print to stdout -- regular void print_stdout (char* text) { printf("%s", text); fflush(stdout); } // print to stdout -- for MSVC void cl_print_stdout (const char *template, ... ) { va_list ap; va_start( ap, template ); vfprintf( stdout, template, ap ); va_end( ap ); fflush(stdout); } // print to stdout -- regular void print_stderr (char* text) { fprintf(stderr, "%s", text); fflush(stderr); } // print to stderr -- for MSVC // avoiding fprintf because of segfaults on MSWin32 with some versions of // ActiveState and some combinations of MSVC compiler void cl_print_stderr (const char *template, ... ) { va_list ap; va_start( ap, template ); vfprintf( stderr, template, ap ); va_end( ap ); fflush(stderr); } IO-CaptureOutput-1.1102/t/capture_file.t000444001750001750 1110411336240130 17525 0ustar00daviddavid000000000000use strict; use Test::More; use IO::CaptureOutput qw/capture/; use File::Temp qw/tempfile/; use Config; plan tests => 30; my ($out, $err); sub _reset { $_ = '' for ($out, $err); 1}; sub _readf { return undef unless -r "$_[0]"; local $/; open FF, "< $_[0]"; my $c = ; close FF; return $c } sub _touch { open FF, "> $_[0]"; close FF } # save output to specified files (undef, my $saved_out) = tempfile; unlink $saved_out; (undef, my $saved_err) = tempfile; unlink $saved_err; _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, $saved_out, $saved_err; is($out, __PACKAGE__, 'save both: captured stdout from perl function 2'); is($err, __FILE__, 'save both: captured stderr from perl function 2'); ok(-s $saved_out, "save both: saved stdout file contains something"); ok(-s $saved_err, "save both: saved stderr file contains something"); is(_readf($saved_out), __PACKAGE__, 'saved both: saved stdout file content ok'); is(_readf($saved_err), __FILE__, 'saved both: saved stderr file content ok'); # confirm that files are clobbered _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, $saved_out, $saved_err; ok(-s $saved_out, "clobber: saved stdout file contains something"); ok(-s $saved_err, "clobber: saved stderr file contains something"); is(_readf($saved_out), __PACKAGE__, 'clobber: stdout file correct'); is(_readf($saved_err), __FILE__, 'clobber: stderr correct:'); # save only stderr unlink $saved_out, $saved_err; _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, undef, $saved_err; ok(!-e $saved_out, "only stderr: stdout file does not exist"); ok(-s $saved_err, "only stderr: file contains something"); is(_readf($saved_err), __FILE__, 'only stdout: stderr file'); # check that the merged stdout and stderr are saved where they should unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$out, $saved_out; like($out, q{/^} . quotemeta(__FILE__) . q{/}, 'merge: captured stdout into one scalar 2'); like($out, q{/} . quotemeta(__PACKAGE__) . q{/}, 'merge: captured stderr into same scalar 2'); ok(-s $saved_out, "merge: saved stdout file contains something"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'merge: saved merged file stdout content ok'); like(_readf($saved_out), q{/} . quotemeta(__PACKAGE__) . q{/}, 'merge: saved merged file stderr content ok'); # capture only stdout to a file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, undef, $saved_out; ok(-s $saved_out, "fileonly stdout: saved stdout file contains something"); ok(!-e $saved_err, "fileonly stdout: saved stderr file does not exist"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'fileonly stdout: saved merged file stdout content ok'); # capture only stderr to a file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, undef, \$err, undef, $saved_err; ok(!-e $saved_out, "fileonly stderr: saved stdout file does not exist"); ok(-s $saved_err, "fileonly stderr: saved stderr file contains something"); like(_readf($saved_err), q{/} . quotemeta(__PACKAGE__) . q{/}, 'fileonly stderr: undef, undef file stderr content ok'); # don't capture merged to scalar, only to file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, undef, undef, $saved_out; ok(-s $saved_out, "fileonly merge: saved stdout file contains something"); ok(!-e $saved_err, "fileonly merge: saved stderr file does not exist"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'fileonly merge: file stdout content ok'); like(_readf($saved_out), q{/} . quotemeta(__PACKAGE__) . q{/}, 'fileonly merge: file stderr content ok'); # confirm error handling on read-only files _touch($_) for ($saved_out, $saved_err); chmod 0444, $saved_out, $saved_err; SKIP: { skip "Can't make temp files read-only to test error handling", 2 if ( -w $saved_out || -w $saved_err ); eval { capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$err, $saved_out }; like( $@, q{/Can't write temp file for main::STDOUT/}, "error handling: can't write to stdout file" ); eval { capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$err, undef, $saved_err }; like( $@, q{/Can't write temp file for main::STDERR/}, "error handling: can't write to stderr file" ); } # restore permissions chmod 0666, $saved_out, $saved_err; unlink $saved_out, $saved_err; IO-CaptureOutput-1.1102/t/scripts000755001750001750 011336240130 16213 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/t/scripts/wperl-exec.pl000444001750001750 41411336240130 20737 0ustar00daviddavid000000000000use strict; use IO::File; use IO::CaptureOutput qw/qxx/; my $output_file = shift @ARGV; my ($stdout, $stderr) = qxx($^X, '-e', 'print "STDOUT\n"; print STDERR "STDERR\n"'); my $fh = IO::File->new($output_file, ">"); print {$fh} $stdout, $stderr; $fh->close; IO-CaptureOutput-1.1102/t/scripts/wperl-capture.pl000444001750001750 47411336240130 21464 0ustar00daviddavid000000000000use strict; use IO::File; use IO::CaptureOutput qw/capture/; my $output_file = shift @ARGV; my ($stdout, $stderr) = (q{}, q{}); capture sub { print STDOUT "STDOUT\n"; print STDERR "STDERR\n"; } => \$stdout, \$stderr; my $fh = IO::File->new($output_file, ">"); print {$fh} $stdout, $stderr; $fh->close; IO-CaptureOutput-1.1102/examples000755001750001750 011336240130 16077 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/examples/capture.pl000555001750001750 42111336240130 20214 0ustar00daviddavid000000000000use strict; use warnings; use IO::CaptureOutput qw/capture/; my ($stdout, $stderr); capture sub { print "This prints to STDOUT\n"; print STDERR "This prints to STDERR\n"; } => \$stdout, \$stderr; print "STDOUT was:\n$stdout\n"; print "STDERR was:\n$stderr\n"; IO-CaptureOutput-1.1102/inc000755001750001750 011336240130 15032 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/inc/Module000755001750001750 011336240130 16257 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/inc/Module/Build000755001750001750 011336240130 17316 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/inc/Module/Build/DAGOLDEN.pm000444001750001750 274011336240130 21171 0ustar00daviddavid000000000000package Module::Build::DAGOLDEN; use strict; use Module::Build; use vars qw/@ISA/; @ISA = qw/Module::Build/; use File::Spec; sub ACTION_wikidoc { my $self = shift; eval "use Pod::WikiDoc"; if ( $@ eq '' ) { my $parser = Pod::WikiDoc->new({ comment_blocks => 1, keywords => { VERSION => $self->dist_version }, }); for my $src ( keys %{ $self->find_pm_files() } ) { (my $tgt = $src) =~ s{\.pm$}{.pod}; $parser->filter( { input => $src, output => $tgt, }); print "Creating $tgt\n"; $tgt =~ s{\\}{/}g; $self->_add_to_manifest( 'MANIFEST', $tgt ); } } else { warn "Pod::WikiDoc not available. Skipping wikidoc.\n"; } } sub ACTION_test { my $self = shift; my $missing_pod; for my $src ( keys %{ $self->find_pm_files() } ) { (my $tgt = $src) =~ s{\.pm$}{.pod}; $missing_pod = 1 if ! -e $tgt; } if ( $missing_pod ) { $self->depends_on('wikidoc'); $self->depends_on('build'); } $self->SUPER::ACTION_test; } sub ACTION_testpod { my $self = shift; $self->depends_on('wikidoc'); $self->SUPER::ACTION_testpod; } sub ACTION_distmeta { my $self = shift; $self->depends_on('wikidoc'); $self->SUPER::ACTION_distmeta; } sub ACTION_distdir { my $self = shift; $self->depends_on('wikidoc'); $self->SUPER::ACTION_distdir; } 1; IO-CaptureOutput-1.1102/xt000755001750001750 011336240130 14714 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/xt/pod.t000444001750001750 23411336240130 15777 0ustar00daviddavid000000000000use Test::More; my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok(); IO-CaptureOutput-1.1102/xt/pod-coverage.t000444001750001750 51711336240130 17574 0ustar00daviddavid000000000000use Test::More; my $min_tpc = 1.08; eval "use Test::Pod::Coverage $min_tpc"; plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" if $@; my $min_pc = 0.17; eval "use Pod::Coverage $min_pc"; plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" if $@; all_pod_coverage_ok(); IO-CaptureOutput-1.1102/xt/spelling.t000444001750001750 55711336240130 17042 0ustar00daviddavid000000000000use Test::More; my $min_tps = 0.11; eval "use Test::Spelling $min_tps"; plan skip_all => "Test::Spelling $min_tps required for testing POD" if $@; system( "ispell -v" ) and plan skip_all => "No ispell"; set_spell_cmd( "ispell -l" ); add_stopwords( qw( MSWin CPAN DAGOLDEN README STDERR STDOUT XS co )); all_pod_files_spelling_ok(); IO-CaptureOutput-1.1102/xt/critic.t000444001750001750 33411336240130 16473 0ustar00daviddavid000000000000use strict; use warnings; use File::Spec; use Test::More; require Test::Perl::Critic; my $rcfile = File::Spec->catfile( 'xt', 'perlcriticrc' ); Test::Perl::Critic->import( -profile => $rcfile ); all_critic_ok( 'lib' ); IO-CaptureOutput-1.1102/xt/perlcriticrc000444001750001750 77311336240130 17450 0ustar00daviddavid000000000000severity = 5 [Variables::ProhibitPunctuationVars] allow = $@ $! # Turn these off [-BuiltinFunctions::ProhibitStringyEval] [-ControlStructures::ProhibitPostfixControls] [-ControlStructures::ProhibitUnlessBlocks] [-Documentation::RequirePodSections] [-InputOutput::ProhibitInteractiveTest] [-Miscellanea::RequireRcsKeywords] [-References::ProhibitDoubleSigils] [-RegularExpressions::RequireExtendedFormatting] [-InputOutput::ProhibitTwoArgOpen] # Turn this on [Lax::ProhibitStringyEval::ExceptForRequire] IO-CaptureOutput-1.1102/lib000755001750001750 011336240130 15027 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/lib/IO000755001750001750 011336240130 15336 5ustar00daviddavid000000000000IO-CaptureOutput-1.1102/lib/IO/CaptureOutput.pm000444001750001750 3146311336240130 20704 0ustar00daviddavid000000000000# $Id: CaptureOutput.pm,v 1.3 2005/03/25 12:44:14 simonflack Exp $ package IO::CaptureOutput; use strict; use vars qw/$VERSION @ISA @EXPORT_OK %EXPORT_TAGS $CarpLevel/; use Exporter; use Carp qw/croak/; @ISA = 'Exporter'; @EXPORT_OK = qw/capture capture_exec qxx capture_exec_combined qxy/; %EXPORT_TAGS = (all => \@EXPORT_OK); $VERSION = '1.1102'; $VERSION = eval $VERSION; ## no critic $CarpLevel = 0; # help capture report errors at the right level sub _capture (&@) { ## no critic my ($code, $output, $error, $output_file, $error_file) = @_; # check for valid combinations of input { local $Carp::CarpLevel = 1; my $error = _validate($output, $error, $output_file, $error_file); croak $error if $error; } # if either $output or $error are defined, then we need a variable for # results; otherwise we only capture to files and don't waste memory if ( defined $output || defined $error ) { for ($output, $error) { $_ = \do { my $s; $s = ''} unless ref $_; $$_ = '' if $_ != \undef && !defined($$_); } } # merge if same refs for $output and $error or if both are undef -- # i.e. capture \&foo, undef, undef, $merged_file # this means capturing into separate files *requires* at least one # capture variable my $should_merge = (defined $error && defined $output && $output == $error) || ( !defined $output && !defined $error ) || 0; my ($capture_out, $capture_err); # undef means capture anonymously; anything other than \undef means # capture to that ref; \undef means skip capture if ( !defined $output || $output != \undef ) { $capture_out = IO::CaptureOutput::_proxy->new( 'STDOUT', $output, undef, $output_file ); } if ( !defined $error || $error != \undef ) { $capture_err = IO::CaptureOutput::_proxy->new( 'STDERR', $error, ($should_merge ? 'STDOUT' : undef), $error_file ); } # now that output capture is setup, call the subroutine # results get read when IO::CaptureOutput::_proxy objects go out of scope &$code(); } # Extra indirection for symmetry with capture_exec, etc. Gets error reporting # to the right level sub capture (&@) { ## no critic return &_capture; } sub capture_exec { my @args = @_; my ($output, $error); my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$error; my $success = ($exit == 0 ) ? 1 : 0 ; $? = $exit; return wantarray ? ($output, $error, $success, $exit) : $output; } *qxx = \&capture_exec; sub capture_exec_combined { my @args = @_; my $output; my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$output; my $success = ($exit == 0 ) ? 1 : 0 ; $? = $exit; return wantarray ? ($output, $success, $exit) : $output; } *qxy = \&capture_exec_combined; # extra quoting required on Win32 systems *_shell_quote = ($^O =~ /MSWin32/) ? \&_shell_quote_win32 : sub {@_}; sub _shell_quote_win32 { my @args; for (@_) { if (/[ \"]/) { # TODO: check if ^ requires escaping (my $escaped = $_) =~ s/([\"])/\\$1/g; push @args, '"' . $escaped . '"'; next; } push @args, $_ } return @args; } # detect errors and return an error message or empty string; sub _validate { my ($output, $error, $output_file, $error_file) = @_; # default to "ok" my $msg = q{}; # \$out, \$out, $outfile, $errfile if ( defined $output && defined $error && defined $output_file && defined $error_file && $output == $error && $output != \undef && $output_file ne $error_file ) { $msg = "Merged STDOUT and STDERR, but specified different output and error files"; } # undef, undef, $outfile, $errfile elsif ( !defined $output && !defined $error && defined $output_file && defined $error_file && $output_file ne $error_file ) { $msg = "Merged STDOUT and STDERR, but specified different output and error files"; } return $msg; } # Captures everything printed to a filehandle for the lifetime of the object # and then transfers it to a scalar reference package IO::CaptureOutput::_proxy; use File::Temp 'tempfile'; use File::Basename qw/basename/; use Symbol qw/gensym qualify qualify_to_ref/; use Carp; sub _is_wperl { $^O eq 'MSWin32' && basename($^X) eq 'wperl.exe' } sub new { my $class = shift; my ($orig_fh, $capture_var, $merge_fh, $capture_file) = @_; $orig_fh = qualify($orig_fh); # e.g. main::STDOUT my $fhref = qualify_to_ref($orig_fh); # e.g. \*STDOUT # Duplicate the filehandle my $saved_fh; { no strict 'refs'; ## no critic - needed for 5.005 if ( defined fileno($orig_fh) && ! _is_wperl() ) { $saved_fh = gensym; open $saved_fh, ">&$orig_fh" or croak "Can't redirect <$orig_fh> - $!"; } } # Create replacement filehandle if not merging my ($newio_fh, $newio_file); if ( ! $merge_fh ) { $newio_fh = gensym; if ($capture_file) { $newio_file = $capture_file; } else { (undef, $newio_file) = tempfile; } open $newio_fh, "+>$newio_file" or croak "Can't write temp file for $orig_fh - $!"; } else { $newio_fh = qualify($merge_fh); } # Redirect (or merge) { no strict 'refs'; ## no critic -- needed for 5.005 open $fhref, ">&".fileno($newio_fh) or croak "Can't redirect $orig_fh - $!"; } bless [$$, $orig_fh, $saved_fh, $capture_var, $newio_fh, $newio_file, $capture_file], $class; } sub DESTROY { my $self = shift; my ($pid, $orig_fh, $saved_fh, $capture_var, $newio_fh, $newio_file, $capture_file) = @$self; return unless $pid eq $$; # only cleanup in the process that is capturing # restore the original filehandle my $fh_ref = Symbol::qualify_to_ref($orig_fh); select((select ($fh_ref), $|=1)[0]); if (defined $saved_fh) { open $fh_ref, ">&". fileno($saved_fh) or croak "Can't restore $orig_fh - $!"; } else { close $fh_ref; } # transfer captured data to the scalar reference if we didn't merge # $newio_file is undef if this file handle is merged to another if (ref $capture_var && $newio_file) { # some versions of perl complain about reading from fd 1 or 2 # which could happen if STDOUT and STDERR were closed when $newio # was opened, so we just squelch warnings here and continue local $^W; seek $newio_fh, 0, 0; $$capture_var = do {local $/; <$newio_fh>}; } close $newio_fh if $newio_file; # Cleanup return unless defined $newio_file && -e $newio_file; return if $capture_file; # the "temp" file was explicitly named unlink $newio_file or carp "Couldn't remove temp file '$newio_file' - $!"; } 1; __END__ =pod =begin wikidoc = NAME IO::CaptureOutput - capture STDOUT and STDERR from Perl code, subprocesses or XS = VERSION This documentation describes version %%VERSION%%. = SYNOPSIS use IO::CaptureOutput qw(capture qxx qxy); # STDOUT and STDERR separately capture { noisy_sub(@args) } \$stdout, \$stderr; # STDOUT and STDERR together capture { noisy_sub(@args) } \$combined, \$combined; # STDOUT and STDERR from external command ($stdout, $stderr, $success) = qxx( @cmd ); # STDOUT and STDERR together from external command ($combined, $success) = qxy( @cmd ); = DESCRIPTION This module provides routines for capturing STDOUT and STDERR from perl subroutines, forked system calls (e.g. {system()}, {fork()}) and from XS or C modules. = FUNCTIONS The following functions will be exported on demand. == capture() capture \&subroutine, \$stdout, \$stderr; Captures everything printed to {STDOUT} and {STDERR} for the duration of {&subroutine}. {$stdout} and {$stderr} are optional scalars that will contain {STDOUT} and {STDERR} respectively. {capture()} uses a code prototype so the first argument can be specified directly within brackets if desired. # shorthand with prototype capture { print __PACKAGE__ } \$stdout, \$stderr; Returns the return value(s) of {&subroutine}. The sub is called in the same context as {capture()} was called e.g.: @rv = capture { wantarray } ; # returns true $rv = capture { wantarray } ; # returns defined, but not true capture { wantarray }; # void, returns undef {capture()} is able to capture output from subprocesses and C code, which traditional {tie()} methods of output capture are unable to do. *Note:* {capture()} will only capture output that has been written or flushed to the filehandle. If the two scalar references refer to the same scalar, then {STDERR} will be merged to {STDOUT} before capturing and the scalar will hold the combined output of both. capture \&subroutine, \$combined, \$combined; Normally, {capture()} uses anonymous, temporary files for capturing output. If desired, specific file names may be provided instead as additional options. capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; Files provided will be clobbered, overwriting any previous data, but will persist after the call to {capture()} for inspection or other manipulation. By default, when no references are provided to hold STDOUT or STDERR, output is captured and silently discarded. # Capture STDOUT, discard STDERR capture \&subroutine, \$stdout; # Discard STDOUT, capture STDERR capture \&subroutine, undef, \$stderr; However, even when using {undef}, output can be captured to specific files. # Capture STDOUT to a specific file, discard STDERR capture \&subroutine, \$stdout, undef, $outfile; # Discard STDOUT, capture STDERR to a specific file capture \&subroutine, undef, \$stderr, undef, $err_file; # Discard both, capture merged output to a specific file capture \&subroutine, undef, undef, $mergedfile; It is a fatal error to merge STDOUT and STDERR and request separate, specific files for capture. # ERROR: capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; capture \&subroutine, undef, undef, $out_file, $err_file; If either STDOUT or STDERR should be passed through to the terminal instead of captured, provide a reference to undef -- {\undef} -- instead of a capture variable. # Capture STDOUT, display STDERR capture \&subroutine, \$stdout, \undef; # Display STDOUT, capture STDERR capture \&subroutine, \undef, \$stderr; == capture_exec() ($stdout, $stderr, $success, $exit_code) = capture_exec(@args); Captures and returns the output from {system(@args)}. In scalar context, {capture_exec()} will return what was printed to {STDOUT}. In list context, it returns what was printed to {STDOUT} and {STDERR} as well as a success flag and the exit value. $stdout = capture_exec('perl', '-e', 'print "hello world"'); ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test"'); {capture_exec} passes its arguments to {system()} and on MSWin32 will protect arguments with shell quotes if necessary. This makes it a handy and slightly more portable alternative to backticks, piped {open()} and {IPC::Open3}. The {$success} flag returned will be true if the command ran successfully and false if it did not (if the command could not be run or if it ran and returned a non-zero exit value). On failure, the raw exit value of the {system()} call is available both in the {$exit_code} returned and in the {$?} variable. ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test" and exit 1'); if ( ! $success ) { print "The exit code was " . ($exit_code >> 8) . "\n"; } See [perlvar] for more information on interpreting a child process exit code. == capture_exec_combined() ($combined, $success, $exit_code) = capture_exec_combined( 'perl', '-e', 'print "hello\n"', 'warn "Test\n" ); This is just like {capture_exec()}, except that it merges {STDERR} with {STDOUT} before capturing output. *Note:* there is no guarantee that text printed to {STDOUT} and {STDERR} in the subprocess will be appear in order. The actual order will depend on how IO buffering is handled in the subprocess. == qxx() This is an alias for {capture_exec()}. == qxy() This is an alias for {capture_exec_combined()}. = SEE ALSO * [IPC::Open3] * [IO::Capture] * [IO::Utils] * [IPC::System::Simple] = AUTHORS * Simon Flack (original author) * David Golden (co-maintainer since version 1.04) = COPYRIGHT AND LICENSE Portions copyright 2004, 2005 Simon Flack. Portions copyright 2007, 2008 David Golden. All rights reserved. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =end wikidoc =cut IO-CaptureOutput-1.1102/lib/IO/CaptureOutput.pod000444001750001750 1467211336240130 21055 0ustar00daviddavid000000000000# Generated by Pod::WikiDoc version 0.18 =pod =head1 NAME IO::CaptureOutput - capture STDOUT and STDERR from Perl code, subprocesses or XS =head1 VERSION This documentation describes version 1.1102. =head1 SYNOPSIS use IO::CaptureOutput qw(capture qxx qxy); # STDOUT and STDERR separately capture { noisy_sub(@args) } \$stdout, \$stderr; # STDOUT and STDERR together capture { noisy_sub(@args) } \$combined, \$combined; # STDOUT and STDERR from external command ($stdout, $stderr, $success) = qxx( @cmd ); # STDOUT and STDERR together from external command ($combined, $success) = qxy( @cmd ); =head1 DESCRIPTION This module provides routines for capturing STDOUT and STDERR from perl subroutines, forked system calls (e.g. C<<< system() >>>, C<<< fork() >>>) and from XS or C modules. =head1 FUNCTIONS The following functions will be exported on demand. =head2 capture() capture \&subroutine, \$stdout, \$stderr; Captures everything printed to C<<< STDOUT >>> and C<<< STDERR >>> for the duration of C<<< &subroutine >>>. C<<< $stdout >>> and C<<< $stderr >>> are optional scalars that will contain C<<< STDOUT >>> and C<<< STDERR >>> respectively. C<<< capture() >>> uses a code prototype so the first argument can be specified directly within brackets if desired. # shorthand with prototype capture { print __PACKAGE__ } \$stdout, \$stderr; Returns the return value(s) of C<<< &subroutine >>>. The sub is called in the same context as C<<< capture() >>> was called e.g.: @rv = capture { wantarray } ; # returns true $rv = capture { wantarray } ; # returns defined, but not true capture { wantarray }; # void, returns undef C<<< capture() >>> is able to capture output from subprocesses and C code, which traditional C<<< tie() >>> methods of output capture are unable to do. B C<<< capture() >>> will only capture output that has been written or flushed to the filehandle. If the two scalar references refer to the same scalar, then C<<< STDERR >>> will be merged to C<<< STDOUT >>> before capturing and the scalar will hold the combined output of both. capture \&subroutine, \$combined, \$combined; Normally, C<<< capture() >>> uses anonymous, temporary files for capturing output. If desired, specific file names may be provided instead as additional options. capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; Files provided will be clobbered, overwriting any previous data, but will persist after the call to C<<< capture() >>> for inspection or other manipulation. By default, when no references are provided to hold STDOUT or STDERR, output is captured and silently discarded. # Capture STDOUT, discard STDERR capture \&subroutine, \$stdout; # Discard STDOUT, capture STDERR capture \&subroutine, undef, \$stderr; However, even when using C<<< undef >>>, output can be captured to specific files. # Capture STDOUT to a specific file, discard STDERR capture \&subroutine, \$stdout, undef, $outfile; # Discard STDOUT, capture STDERR to a specific file capture \&subroutine, undef, \$stderr, undef, $err_file; # Discard both, capture merged output to a specific file capture \&subroutine, undef, undef, $mergedfile; It is a fatal error to merge STDOUT and STDERR and request separate, specific files for capture. # ERROR: capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; capture \&subroutine, undef, undef, $out_file, $err_file; If either STDOUT or STDERR should be passed through to the terminal instead of captured, provide a reference to undef -- C<<< \undef >>> -- instead of a capture variable. # Capture STDOUT, display STDERR capture \&subroutine, \$stdout, \undef; # Display STDOUT, capture STDERR capture \&subroutine, \undef, \$stderr; =head2 capture_exec() ($stdout, $stderr, $success, $exit_code) = capture_exec(@args); Captures and returns the output from C<<< system(@args) >>>. In scalar context, C<<< capture_exec() >>> will return what was printed to C<<< STDOUT >>>. In list context, it returns what was printed to C<<< STDOUT >>> and C<<< STDERR >>> as well as a success flag and the exit value. $stdout = capture_exec('perl', '-e', 'print "hello world"'); ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test"'); C<<< capture_exec >>> passes its arguments to C<<< system() >>> and on MSWin32 will protect arguments with shell quotes if necessary. This makes it a handy and slightly more portable alternative to backticks, piped C<<< open() >>> and C<<< IPC::Open3 >>>. The C<<< $success >>> flag returned will be true if the command ran successfully and false if it did not (if the command could not be run or if it ran and returned a non-zero exit value). On failure, the raw exit value of the C<<< system() >>> call is available both in the C<<< $exit_code >>> returned and in the C<<< $? >>> variable. ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test" and exit 1'); if ( ! $success ) { print "The exit code was " . ($exit_code >> 8) . "\n"; } See L for more information on interpreting a child process exit code. =head2 capture_exec_combined() ($combined, $success, $exit_code) = capture_exec_combined( 'perl', '-e', 'print "hello\n"', 'warn "Test\n" ); This is just like C<<< capture_exec() >>>, except that it merges C<<< STDERR >>> with C<<< STDOUT >>> before capturing output. B there is no guarantee that text printed to C<<< STDOUT >>> and C<<< STDERR >>> in the subprocess will be appear in order. The actual order will depend on how IO buffering is handled in the subprocess. =head2 qxx() This is an alias for C<<< capture_exec() >>>. =head2 qxy() This is an alias for C<<< capture_exec_combined() >>>. =head1 SEE ALSO =over =item * L =item * L =item * L =item * L =back =head1 AUTHORS =over =item * Simon Flack Esimonflk _AT_ cpan.orgE (original author) =item * David Golden Edagolden _AT_ cpan.orgE (co-maintainer since version 1.04) =back =head1 COPYRIGHT AND LICENSE Portions copyright 2004, 2005 Simon Flack. Portions copyright 2007, 2008 David Golden. All rights reserved. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.