pax_global_header00006660000000000000000000000064117532303560014517gustar00rootroot0000000000000052 comment=53a53c7ecc992196d05e59ad91c69627b909943b ruby-popen4-0.1.4/000077500000000000000000000000001175323035600137055ustar00rootroot00000000000000ruby-popen4-0.1.4/CHANGES000066400000000000000000000004301175323035600146750ustar00rootroot00000000000000== 0.1.4 - 17-Nov-2009 * Platform specific dependency == 0.1.3 - 20-Oct-2009 * Use of win32-open3 gem == 0.1.1 - 12-Jun-2006 * Fixed Bug 4742 - open3.so Open4 fails to return Process::Status on Windows 2000. - Thanks to Park Heesob! == 0.1.0 - 10-Jun-2006 * Initial releaseruby-popen4-0.1.4/LICENSE000066400000000000000000000052101175323035600147100ustar00rootroot00000000000000== POpen4 License POpen4 is copyright John-Mason P. Shackelford (john-mason@shackelford.org) and made available under the terms of Ruby's license, included below for your convenience. == Ruby's License Ruby is copyrighted free software by Yukihiro Matsumoto . You can redistribute it and/or modify it under either the terms of the GPL (see the file GPL), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, 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 by allowing the author to include your modifications in the software. b) use the modified software only within your corporation or organization. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 3. You may distribute the software in object code or binary form, provided that you do at least ONE of the following: a) distribute the binaries and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b) accompany the distribution with the machine-readable source of the software. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the author, so that they are not under these terms. For the list of those files and their copying conditions, see the file LEGAL. 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ruby-popen4-0.1.4/README.rdoc000066400000000000000000000034461175323035600155220ustar00rootroot00000000000000== Description POpen4 provides the Rubyist a single API across platforms for executing a command in a child process with handles on stdout, stderr, stdin streams as well as access to the process ID and exit status. It does very little other than to provide an easy way to use either Ara Howard's Open4 library or the win32-popen3 library by Park Heesob and Daniel Berger depending on your platform and without having to code around the slight differences in their APIs. Consider this my first attempt at a response to {Daniel's request}[http://groups.google.com/group/comp.lang.ruby/msg/44ba016610fa8878] for a consensus on the API back in 2005. It is my hope that this project will be shortly absorbed or replaced with a better solution. POpen4 offers very little in the way of features or flexibility, but it does work across platforms without extra coding. == Notes Rather than adopting either Open4's API or win32-open3's (they differ in several respects, but most obviously in the order in which streams are passed to the block) I am proposing a third API for couple of reasons. First, Open4 passes the PID first and win32-open3 passes stdin neither of which seem to me to be the streams we are most likely to use when we don't need all four. POpen4 passes stdout and stderr first so that when the others are not required we can omit them from the block. Second, I thought it best to break everybody's code rather than to be a drop in replacement on one platform and be a surprise on another. No surprises--it's a new API on either platform. == Installation $ gem install POpen4 --source http://gemcutter.org == Acknowledgements Ara Howard, Park Heesob, Daniel Berger and others have done the real work. Many thanks to them for the many hours they have poured into sharing their work with the Ruby community at large.ruby-popen4-0.1.4/Rakefile000066400000000000000000000034341175323035600153560ustar00rootroot00000000000000require 'rubygems' require 'rubygems/user_interaction' require 'rake/testtask' require 'rake/rdoctask' task :default => [:test] # Test -------------------------------------------------------------------- desc "Run the unit tests" task :test do Rake::TestTask.new("test") do |t| t.libs << "tests" t.pattern = 'tests/*_test.rb' t.verbose = true end end # Documentation ----------------------------------------------------------- desc "Generate RDoc" rd = Rake::RDocTask.new("rdoc") { |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = "POpen4 -- Open4 cross-platform" rdoc.options << '--main' << 'README' rdoc.rdoc_files.include('README', 'LICENSE', 'CHANGES') rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc') } # GEM Packaging ----------------------------------------------------------- begin require 'jeweler' # Windows Jeweler::Tasks.new do |gemspec| gemspec.name = "POpen4" gemspec.summary = "Open4 cross-platform" gemspec.description = "" gemspec.email = "john-mason@shackelford.org" gemspec.homepage = "http://github.com/pka/popen4" gemspec.authors = ["John-Mason P. Shackelford"] gemspec.add_dependency("Platform", ">= 0.4.0") gemspec.platform = 'x86-mswin32' gemspec.add_dependency("win32-open3") end # Unix Jeweler::Tasks.new do |gemspec| gemspec.name = "POpen4" gemspec.summary = "Open4 cross-platform" gemspec.description = "" gemspec.email = "john-mason@shackelford.org" gemspec.homepage = "http://github.com/pka/popen4" gemspec.authors = ["John-Mason P. Shackelford"] gemspec.add_dependency("Platform", ">= 0.4.0") gemspec.add_dependency("open4") end rescue LoadError puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" end ruby-popen4-0.1.4/VERSION000066400000000000000000000000061175323035600147510ustar00rootroot000000000000000.1.4 ruby-popen4-0.1.4/lib/000077500000000000000000000000001175323035600144535ustar00rootroot00000000000000ruby-popen4-0.1.4/lib/popen4.rb000066400000000000000000000062541175323035600162140ustar00rootroot00000000000000require 'rubygems' require 'platform' case Platform::OS # win32/popen4 yields stdin, stdout, stderr and pid, respectively when :win32 require 'win32/open3' # POpen4 provides the Rubyist a single API across platforms for executing a # command in a child process with handles on stdout, stderr, and stdin streams # as well as access to the process ID and exit status. # # Consider the following example (borrowed from Open4): # # require 'rubygems' # require 'popen4' # # status = # POpen4::popen4("cmd") do |stdout, stderr, stdin, pid| # stdin.puts "echo hello world!" # stdin.puts "echo ERROR! 1>&2" # stdin.puts "exit" # stdin.close # # puts "pid : #{ pid }" # puts "stdout : #{ stdout.read.strip }" # puts "stderr : #{ stderr.read.strip }" # end # # puts "status : #{ status.inspect }" # puts "exitstatus : #{ status.exitstatus }" # module POpen4 # Starts a new process and hands IO objects representing the subprocess # stdout, stderr, stdin streams and the pid (respectively) to the block # supplied. If the command could not be started, return nil. # # The mode argument may be set to t[ext] or b[inary] and is used only on # Windows platforms. # # The stdin stream and/or pid may be omitted from the block parameter list # if they are not required. def self.popen4(command, mode = "t") # :yields: stdout, stderr, stdin, pid err_output = nil Open4.popen4(command, mode) do |stdin,stdout,stderr,pid| yield stdout, stderr, stdin, pid # On windows we will always get an exit status of 3 unless # we read to the end of the streams so we do this on all platforms # so that our behavior is always the same. stdout.read unless stdout.eof? # On windows executing a non existent command does not raise an error # (as in unix) so on unix we return nil instead of a status object and # on windows we try to determine if we couldn't start the command and # return nil instead of the Process::Status object. stderr.rewind err_output = stderr.read end return $? end # def end # module else # unix popen4 yields pid, stdin, stdout and stderr, respectively # :enddoc: require 'open4' module POpen4 def self.popen4(command, mode = "t") begin return status = Open4.popen4(command) do |pid,stdin,stdout,stderr| yield stdout, stderr, stdin, pid # On windows we will always get an exit status of 3 unless # we read to the end of the streams so we do this on all platforms # so that our behavior is always the same. stdout.read unless stdout.eof? stderr.read unless stderr.eof? end rescue Errno::ENOENT => e # On windows executing a non existent command does not raise an error # (as in unix) so on unix we return nil instead of a status object and # on windows we try to determine if we couldn't start the command and # return nil instead of the Process::Status object. return nil end end #def end #module end ruby-popen4-0.1.4/metadata.yml000066400000000000000000000030511175323035600162070ustar00rootroot00000000000000--- !ruby/object:Gem::Specification name: POpen4 version: !ruby/object:Gem::Version version: 0.1.4 platform: ruby authors: - John-Mason P. Shackelford autorequire: bindir: bin cert_chain: [] date: 2009-11-17 00:00:00 +01:00 default_executable: dependencies: - !ruby/object:Gem::Dependency name: Platform type: :runtime version_requirement: version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.4.0 version: - !ruby/object:Gem::Dependency name: open4 type: :runtime version_requirement: version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" version: description: "" email: john-mason@shackelford.org executables: [] extensions: [] extra_rdoc_files: - LICENSE - README.rdoc files: - CHANGES - LICENSE - README.rdoc - Rakefile - VERSION - lib/popen4.rb - tests/popen4_test.rb has_rdoc: true homepage: http://github.com/pka/popen4 licenses: [] post_install_message: rdoc_options: - --charset=UTF-8 require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" version: required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" version: requirements: [] rubyforge_project: rubygems_version: 1.3.5 signing_key: specification_version: 3 summary: Open4 cross-platform test_files: [] ruby-popen4-0.1.4/tests/000077500000000000000000000000001175323035600150475ustar00rootroot00000000000000ruby-popen4-0.1.4/tests/popen4_test.rb000066400000000000000000000037551175323035600176520ustar00rootroot00000000000000$: << File.join( File.dirname( __FILE__ ), '../lib/') require 'test/unit' require 'popen4' require 'platform' class POpen4Test < Test::Unit::TestCase case Platform::OS when :win32 CMD_SHELL = "cmd" CMD_STDERR = "ruby -e \"$stderr.puts 'ruby'\"" CMD_EXIT = "ruby -e \"$stdout.puts 'ruby'; exit 1\"" else # unix CMD_SHELL = "sh" CMD_STDERR = "ruby -e '$stderr.puts \"ruby\"'" CMD_EXIT = "ruby -e '$stdout.puts \"ruby\"; exit 1'" end CMD_GOOD = "ruby --version" CMD_BAD = CMD_GOOD.reverse def test_popen4_block_good_cmd assert_nothing_raised do POpen4.popen4(CMD_GOOD){ |pout, perr, pin, pid| } end end def test_popen4_block_bad_cmd status = nil assert_nothing_raised do status = POpen4.popen4(CMD_BAD){ |pout, perr, pin, pid| } end assert_nil status end def test_popen4_block_status status = POpen4.popen4(CMD_GOOD) do |pout, perr, pin, pid| assert_kind_of(IO, pin) assert_kind_of(IO, pout) assert_kind_of(IO, perr) assert_kind_of(Fixnum, pid) end assert_kind_of Process::Status, status end def test_open4_block_read_stdout status = POpen4.popen4(CMD_GOOD) do |pout, perr| assert_match(/ruby \d\.\d\.\d/, pout.gets) end assert_equal 0, status.exitstatus end def test_open4_block_read_stderr status = POpen4.popen4(CMD_STDERR) do |pout, perr| assert_match "ruby", perr.gets end assert_equal 0, status.exitstatus end def test_open4_block_exitstatus status = POpen4.popen4(CMD_EXIT) do |pout, perr| assert_match "ruby", pout.gets end assert_kind_of Process::Status, status assert_equal 1, status.exitstatus end def test_open4_block_write_stdin status = POpen4.popen4(CMD_SHELL) do |pout, perr, pin| pin.puts CMD_GOOD pin.puts "exit" pin.close assert_match(/ruby \d\.\d\.\d/, pout.readlines.join) end assert_equal 0, status.exitstatus end end