POpen4 0.1.4-x86-mswin32

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