childprocess 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.document +6 -6
  3. data/.gitignore +25 -25
  4. data/.rspec +1 -1
  5. data/.travis.yml +20 -18
  6. data/CHANGELOG.md +8 -0
  7. data/Gemfile +11 -4
  8. data/LICENSE +20 -20
  9. data/README.md +178 -178
  10. data/Rakefile +61 -61
  11. data/childprocess.gemspec +30 -29
  12. data/lib/childprocess.rb +184 -177
  13. data/lib/childprocess/abstract_io.rb +36 -36
  14. data/lib/childprocess/abstract_process.rb +187 -187
  15. data/lib/childprocess/errors.rb +26 -26
  16. data/lib/childprocess/jruby.rb +56 -56
  17. data/lib/childprocess/jruby/io.rb +16 -16
  18. data/lib/childprocess/jruby/process.rb +159 -159
  19. data/lib/childprocess/jruby/pump.rb +52 -52
  20. data/lib/childprocess/tools/generator.rb +145 -145
  21. data/lib/childprocess/unix.rb +9 -9
  22. data/lib/childprocess/unix/fork_exec_process.rb +70 -70
  23. data/lib/childprocess/unix/io.rb +21 -21
  24. data/lib/childprocess/unix/lib.rb +186 -186
  25. data/lib/childprocess/unix/platform/i386-linux.rb +12 -12
  26. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -11
  27. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -12
  28. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -11
  29. data/lib/childprocess/unix/posix_spawn_process.rb +134 -134
  30. data/lib/childprocess/unix/process.rb +89 -89
  31. data/lib/childprocess/version.rb +3 -3
  32. data/lib/childprocess/windows.rb +33 -33
  33. data/lib/childprocess/windows/handle.rb +91 -91
  34. data/lib/childprocess/windows/io.rb +25 -25
  35. data/lib/childprocess/windows/lib.rb +415 -415
  36. data/lib/childprocess/windows/process.rb +129 -129
  37. data/lib/childprocess/windows/process_builder.rb +174 -174
  38. data/lib/childprocess/windows/structs.rb +148 -148
  39. data/spec/abstract_io_spec.rb +12 -12
  40. data/spec/childprocess_spec.rb +291 -256
  41. data/spec/io_spec.rb +228 -228
  42. data/spec/jruby_spec.rb +24 -24
  43. data/spec/pid_behavior.rb +12 -12
  44. data/spec/spec_helper.rb +253 -253
  45. data/spec/unix_spec.rb +57 -57
  46. data/spec/windows_spec.rb +23 -23
  47. metadata +47 -45
@@ -1,24 +1,24 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
- require "pid_behavior"
3
-
4
- if ChildProcess.jruby? && !ChildProcess.windows?
5
- describe ChildProcess::JRuby::IO do
6
- let(:io) { ChildProcess::JRuby::IO.new }
7
-
8
- it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
- expect { io.stdout = nil }.to raise_error(ArgumentError)
10
- end
11
- end
12
-
13
- describe ChildProcess::JRuby::Process do
14
- if ChildProcess.unix?
15
- it_behaves_like "a platform that provides the child's pid"
16
- else
17
- it "raises an error when trying to access the child's pid" do
18
- process = exit_with(0)
19
- process.start
20
- expect { process.pid }.to raise_error(NotImplementedError)
21
- end
22
- end
23
- end
24
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require "pid_behavior"
3
+
4
+ if ChildProcess.jruby? && !ChildProcess.windows?
5
+ describe ChildProcess::JRuby::IO do
6
+ let(:io) { ChildProcess::JRuby::IO.new }
7
+
8
+ it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
+ expect { io.stdout = nil }.to raise_error(ArgumentError)
10
+ end
11
+ end
12
+
13
+ describe ChildProcess::JRuby::Process do
14
+ if ChildProcess.unix?
15
+ it_behaves_like "a platform that provides the child's pid"
16
+ else
17
+ it "raises an error when trying to access the child's pid" do
18
+ process = exit_with(0)
19
+ process.start
20
+ expect { process.pid }.to raise_error(NotImplementedError)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,12 +1,12 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- shared_examples_for "a platform that provides the child's pid" do
4
- it "knows the child's pid" do
5
- Tempfile.open("pid-spec") do |file|
6
- process = write_pid(file.path).start
7
- process.wait
8
-
9
- expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
- end
11
- end
12
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ shared_examples_for "a platform that provides the child's pid" do
4
+ it "knows the child's pid" do
5
+ Tempfile.open("pid-spec") do |file|
6
+ process = write_pid(file.path).start
7
+ process.wait
8
+
9
+ expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
+ end
11
+ end
12
+ end
@@ -1,253 +1,253 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
-
4
- unless defined?(JRUBY_VERSION)
5
- require 'coveralls'
6
- Coveralls.wear!
7
- end
8
-
9
- require 'childprocess'
10
- require 'rspec'
11
- require 'tempfile'
12
- require 'socket'
13
- require 'stringio'
14
- require 'ostruct'
15
-
16
- module ChildProcessSpecHelper
17
- RUBY = defined?(Gem) ? Gem.ruby : 'ruby'
18
-
19
- def ruby_process(*args)
20
- @process = ChildProcess.build(RUBY , *args)
21
- end
22
-
23
- def sleeping_ruby(seconds = nil)
24
- if seconds
25
- ruby_process("-e", "sleep #{seconds}")
26
- else
27
- ruby_process("-e", "sleep")
28
- end
29
- end
30
-
31
- def invalid_process
32
- @process = ChildProcess.build("unlikelytoexist")
33
- end
34
-
35
- def ignored(signal)
36
- code = <<-RUBY
37
- trap(#{signal.inspect}, "IGNORE")
38
- sleep
39
- RUBY
40
-
41
- ruby_process tmp_script(code)
42
- end
43
-
44
- def write_env(path)
45
- code = <<-RUBY
46
- File.open(#{path.inspect}, "w") { |f| f << ENV.inspect }
47
- RUBY
48
-
49
- ruby_process tmp_script(code)
50
- end
51
-
52
- def write_argv(path, *args)
53
- code = <<-RUBY
54
- File.open(#{path.inspect}, "w") { |f| f << ARGV.inspect }
55
- RUBY
56
-
57
- ruby_process(tmp_script(code), *args)
58
- end
59
-
60
- def write_pid(path)
61
- code = <<-RUBY
62
- File.open(#{path.inspect}, "w") { |f| f << Process.pid }
63
- RUBY
64
-
65
- ruby_process tmp_script(code)
66
- end
67
-
68
- def write_pid_in_sleepy_grand_child(path)
69
- code = <<-RUBY
70
- system "ruby", "-e", 'File.open(#{path.inspect}, "w") { |f| f << Process.pid; f.flush }; sleep'
71
- RUBY
72
-
73
- ruby_process tmp_script(code)
74
- end
75
-
76
- def exit_with(exit_code)
77
- ruby_process(tmp_script("exit(#{exit_code})"))
78
- end
79
-
80
- def with_env(hash)
81
- hash.each { |k,v| ENV[k] = v }
82
- begin
83
- yield
84
- ensure
85
- hash.each_key { |k| ENV[k] = nil }
86
- end
87
- end
88
-
89
- def tmp_script(code)
90
- # use an ivar to avoid GC
91
- @tf = Tempfile.new("childprocess-temp")
92
- @tf << code
93
- @tf.close
94
-
95
- puts code if $DEBUG
96
-
97
- @tf.path
98
- end
99
-
100
- def cat
101
- if ChildProcess.os == :windows
102
- ruby(<<-CODE)
103
- STDIN.sync = STDOUT.sync = true
104
- IO.copy_stream(STDIN, STDOUT)
105
- CODE
106
- else
107
- ChildProcess.build("cat")
108
- end
109
- end
110
-
111
- def echo
112
- if ChildProcess.os == :windows
113
- ruby(<<-CODE)
114
- STDIN.sync = true
115
- STDOUT.sync = true
116
-
117
- puts "hello"
118
- CODE
119
- else
120
- ChildProcess.build("echo", "hello")
121
- end
122
- end
123
-
124
- def ruby(code)
125
- ruby_process(tmp_script(code))
126
- end
127
-
128
- def with_executable_at(path, &blk)
129
- if ChildProcess.os == :windows
130
- path << ".cmd"
131
- content = "#{RUBY} -e 'sleep 10' \n @echo foo"
132
- else
133
- content = "#!/bin/sh\nsleep 10\necho foo"
134
- end
135
-
136
- File.open(path, 'w', 0744) { |io| io << content }
137
- proc = ChildProcess.build(path)
138
-
139
- begin
140
- yield proc
141
- ensure
142
- proc.stop if proc.alive?
143
- File.delete path
144
- end
145
- end
146
-
147
- def exit_timeout
148
- 10
149
- end
150
-
151
- def random_free_port
152
- server = TCPServer.new('127.0.0.1', 0)
153
- port = server.addr[1]
154
- server.close
155
-
156
- port
157
- end
158
-
159
- def with_tmpdir(&blk)
160
- name = "#{Time.now.strftime("%Y%m%d")}-#{$$}-#{rand(0x100000000).to_s(36)}"
161
- FileUtils.mkdir_p(name)
162
-
163
- begin
164
- yield File.expand_path(name)
165
- ensure
166
- FileUtils.rm_rf name
167
- end
168
- end
169
-
170
- def wait_until(timeout = 10, &blk)
171
- end_time = Time.now + timeout
172
- last_exception = nil
173
-
174
- until Time.now >= end_time
175
- begin
176
- result = yield
177
- return result if result
178
- rescue RSpec::Expectations::ExpectationNotMetError => ex
179
- last_exception = ex
180
- end
181
-
182
- sleep 0.01
183
- end
184
-
185
- msg = "timed out after #{timeout} seconds"
186
- msg << ":\n#{last_exception.message}" if last_exception
187
-
188
- raise msg
189
- end
190
-
191
- def can_bind?(host, port)
192
- TCPServer.new(host, port).close
193
- true
194
- rescue
195
- false
196
- end
197
-
198
- def rewind_and_read(io)
199
- io.rewind
200
- io.read
201
- end
202
-
203
- def alive?(pid)
204
- if ChildProcess.windows?
205
- ChildProcess::Windows::Lib.alive?(pid)
206
- else
207
- begin
208
- Process.getpgid pid
209
- true
210
- rescue Errno::ESRCH
211
- false
212
- end
213
- end
214
- end
215
-
216
- def capture_std
217
- orig_out = STDOUT.clone
218
- orig_err = STDERR.clone
219
-
220
- out = Tempfile.new 'captured-stdout'
221
- err = Tempfile.new 'captured-stderr'
222
- out.sync = true
223
- err.sync = true
224
-
225
- STDOUT.reopen out
226
- STDERR.reopen err
227
-
228
- yield
229
-
230
- OpenStruct.new stdout: rewind_and_read(out), stderr: rewind_and_read(err)
231
- ensure
232
- STDOUT.reopen orig_out
233
- STDERR.reopen orig_err
234
- end
235
-
236
- end # ChildProcessSpecHelper
237
-
238
- Thread.abort_on_exception = true
239
-
240
- RSpec.configure do |c|
241
- c.include(ChildProcessSpecHelper)
242
- c.after(:each) {
243
- defined?(@process) && @process.alive? && @process.stop
244
- }
245
-
246
- if ChildProcess.jruby? && ChildProcess.new("true").instance_of?(ChildProcess::JRuby::Process)
247
- c.filter_run_excluding :process_builder => false
248
- end
249
-
250
- if ChildProcess.linux? && ChildProcess.posix_spawn?
251
- c.filter_run_excluding :posix_spawn_on_linux => false
252
- end
253
- end
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ unless defined?(JRUBY_VERSION)
5
+ require 'coveralls'
6
+ Coveralls.wear!
7
+ end
8
+
9
+ require 'childprocess'
10
+ require 'rspec'
11
+ require 'tempfile'
12
+ require 'socket'
13
+ require 'stringio'
14
+ require 'ostruct'
15
+
16
+ module ChildProcessSpecHelper
17
+ RUBY = defined?(Gem) ? Gem.ruby : 'ruby'
18
+
19
+ def ruby_process(*args)
20
+ @process = ChildProcess.build(RUBY , *args)
21
+ end
22
+
23
+ def sleeping_ruby(seconds = nil)
24
+ if seconds
25
+ ruby_process("-e", "sleep #{seconds}")
26
+ else
27
+ ruby_process("-e", "sleep")
28
+ end
29
+ end
30
+
31
+ def invalid_process
32
+ @process = ChildProcess.build("unlikelytoexist")
33
+ end
34
+
35
+ def ignored(signal)
36
+ code = <<-RUBY
37
+ trap(#{signal.inspect}, "IGNORE")
38
+ sleep
39
+ RUBY
40
+
41
+ ruby_process tmp_script(code)
42
+ end
43
+
44
+ def write_env(path)
45
+ code = <<-RUBY
46
+ File.open(#{path.inspect}, "w") { |f| f << ENV.inspect }
47
+ RUBY
48
+
49
+ ruby_process tmp_script(code)
50
+ end
51
+
52
+ def write_argv(path, *args)
53
+ code = <<-RUBY
54
+ File.open(#{path.inspect}, "w") { |f| f << ARGV.inspect }
55
+ RUBY
56
+
57
+ ruby_process(tmp_script(code), *args)
58
+ end
59
+
60
+ def write_pid(path)
61
+ code = <<-RUBY
62
+ File.open(#{path.inspect}, "w") { |f| f << Process.pid }
63
+ RUBY
64
+
65
+ ruby_process tmp_script(code)
66
+ end
67
+
68
+ def write_pid_in_sleepy_grand_child(path)
69
+ code = <<-RUBY
70
+ system "ruby", "-e", 'File.open(#{path.inspect}, "w") { |f| f << Process.pid; f.flush }; sleep'
71
+ RUBY
72
+
73
+ ruby_process tmp_script(code)
74
+ end
75
+
76
+ def exit_with(exit_code)
77
+ ruby_process(tmp_script("exit(#{exit_code})"))
78
+ end
79
+
80
+ def with_env(hash)
81
+ hash.each { |k,v| ENV[k] = v }
82
+ begin
83
+ yield
84
+ ensure
85
+ hash.each_key { |k| ENV[k] = nil }
86
+ end
87
+ end
88
+
89
+ def tmp_script(code)
90
+ # use an ivar to avoid GC
91
+ @tf = Tempfile.new("childprocess-temp")
92
+ @tf << code
93
+ @tf.close
94
+
95
+ puts code if $DEBUG
96
+
97
+ @tf.path
98
+ end
99
+
100
+ def cat
101
+ if ChildProcess.os == :windows
102
+ ruby(<<-CODE)
103
+ STDIN.sync = STDOUT.sync = true
104
+ IO.copy_stream(STDIN, STDOUT)
105
+ CODE
106
+ else
107
+ ChildProcess.build("cat")
108
+ end
109
+ end
110
+
111
+ def echo
112
+ if ChildProcess.os == :windows
113
+ ruby(<<-CODE)
114
+ STDIN.sync = true
115
+ STDOUT.sync = true
116
+
117
+ puts "hello"
118
+ CODE
119
+ else
120
+ ChildProcess.build("echo", "hello")
121
+ end
122
+ end
123
+
124
+ def ruby(code)
125
+ ruby_process(tmp_script(code))
126
+ end
127
+
128
+ def with_executable_at(path, &blk)
129
+ if ChildProcess.os == :windows
130
+ path << ".cmd"
131
+ content = "#{RUBY} -e 'sleep 10' \n @echo foo"
132
+ else
133
+ content = "#!/bin/sh\nsleep 10\necho foo"
134
+ end
135
+
136
+ File.open(path, 'w', 0744) { |io| io << content }
137
+ proc = ChildProcess.build(path)
138
+
139
+ begin
140
+ yield proc
141
+ ensure
142
+ proc.stop if proc.alive?
143
+ File.delete path
144
+ end
145
+ end
146
+
147
+ def exit_timeout
148
+ 10
149
+ end
150
+
151
+ def random_free_port
152
+ server = TCPServer.new('127.0.0.1', 0)
153
+ port = server.addr[1]
154
+ server.close
155
+
156
+ port
157
+ end
158
+
159
+ def with_tmpdir(&blk)
160
+ name = "#{Time.now.strftime("%Y%m%d")}-#{$$}-#{rand(0x100000000).to_s(36)}"
161
+ FileUtils.mkdir_p(name)
162
+
163
+ begin
164
+ yield File.expand_path(name)
165
+ ensure
166
+ FileUtils.rm_rf name
167
+ end
168
+ end
169
+
170
+ def wait_until(timeout = 10, &blk)
171
+ end_time = Time.now + timeout
172
+ last_exception = nil
173
+
174
+ until Time.now >= end_time
175
+ begin
176
+ result = yield
177
+ return result if result
178
+ rescue RSpec::Expectations::ExpectationNotMetError => ex
179
+ last_exception = ex
180
+ end
181
+
182
+ sleep 0.01
183
+ end
184
+
185
+ msg = "timed out after #{timeout} seconds"
186
+ msg << ":\n#{last_exception.message}" if last_exception
187
+
188
+ raise msg
189
+ end
190
+
191
+ def can_bind?(host, port)
192
+ TCPServer.new(host, port).close
193
+ true
194
+ rescue
195
+ false
196
+ end
197
+
198
+ def rewind_and_read(io)
199
+ io.rewind
200
+ io.read
201
+ end
202
+
203
+ def alive?(pid)
204
+ if ChildProcess.windows?
205
+ ChildProcess::Windows::Lib.alive?(pid)
206
+ else
207
+ begin
208
+ Process.getpgid pid
209
+ true
210
+ rescue Errno::ESRCH
211
+ false
212
+ end
213
+ end
214
+ end
215
+
216
+ def capture_std
217
+ orig_out = STDOUT.clone
218
+ orig_err = STDERR.clone
219
+
220
+ out = Tempfile.new 'captured-stdout'
221
+ err = Tempfile.new 'captured-stderr'
222
+ out.sync = true
223
+ err.sync = true
224
+
225
+ STDOUT.reopen out
226
+ STDERR.reopen err
227
+
228
+ yield
229
+
230
+ OpenStruct.new stdout: rewind_and_read(out), stderr: rewind_and_read(err)
231
+ ensure
232
+ STDOUT.reopen orig_out
233
+ STDERR.reopen orig_err
234
+ end
235
+
236
+ end # ChildProcessSpecHelper
237
+
238
+ Thread.abort_on_exception = true
239
+
240
+ RSpec.configure do |c|
241
+ c.include(ChildProcessSpecHelper)
242
+ c.after(:each) {
243
+ defined?(@process) && @process.alive? && @process.stop
244
+ }
245
+
246
+ if ChildProcess.jruby? && ChildProcess.new("true").instance_of?(ChildProcess::JRuby::Process)
247
+ c.filter_run_excluding :process_builder => false
248
+ end
249
+
250
+ if ChildProcess.linux? && ChildProcess.posix_spawn?
251
+ c.filter_run_excluding :posix_spawn_on_linux => false
252
+ end
253
+ end