childprocess 0.5.9 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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