childprocess 4.0.0 → 5.0.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +23 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +0 -14
- data/README.md +3 -20
- data/childprocess.gemspec +1 -1
- data/lib/childprocess/abstract_process.rb +1 -1
- data/lib/childprocess/errors.rb +0 -21
- data/lib/childprocess/process_spawn_process.rb +127 -0
- data/lib/childprocess/unix/process.rb +3 -64
- data/lib/childprocess/unix.rb +2 -4
- data/lib/childprocess/version.rb +1 -1
- data/lib/childprocess/windows/process.rb +13 -116
- data/lib/childprocess/windows.rb +0 -29
- data/lib/childprocess.rb +16 -53
- data/spec/childprocess_spec.rb +40 -16
- data/spec/io_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -18
- data/spec/unix_spec.rb +3 -7
- metadata +6 -24
- data/.travis.yml +0 -37
- data/appveyor.yml +0 -36
- data/lib/childprocess/jruby/io.rb +0 -16
- data/lib/childprocess/jruby/process.rb +0 -184
- data/lib/childprocess/jruby/pump.rb +0 -53
- data/lib/childprocess/jruby.rb +0 -56
- data/lib/childprocess/tools/generator.rb +0 -146
- data/lib/childprocess/unix/fork_exec_process.rb +0 -78
- data/lib/childprocess/unix/lib.rb +0 -186
- data/lib/childprocess/unix/platform/i386-linux.rb +0 -12
- data/lib/childprocess/unix/platform/i386-solaris.rb +0 -11
- data/lib/childprocess/unix/platform/x86_64-linux.rb +0 -12
- data/lib/childprocess/unix/platform/x86_64-macosx.rb +0 -11
- data/lib/childprocess/unix/posix_spawn_process.rb +0 -134
- data/lib/childprocess/windows/handle.rb +0 -91
- data/lib/childprocess/windows/lib.rb +0 -416
- data/lib/childprocess/windows/process_builder.rb +0 -178
- data/lib/childprocess/windows/structs.rb +0 -149
- data/spec/jruby_spec.rb +0 -24
data/lib/childprocess.rb
CHANGED
@@ -2,6 +2,7 @@ require 'childprocess/version'
|
|
2
2
|
require 'childprocess/errors'
|
3
3
|
require 'childprocess/abstract_process'
|
4
4
|
require 'childprocess/abstract_io'
|
5
|
+
require 'childprocess/process_spawn_process'
|
5
6
|
require "fcntl"
|
6
7
|
require 'logger'
|
7
8
|
|
@@ -15,15 +16,9 @@ module ChildProcess
|
|
15
16
|
def new(*args)
|
16
17
|
case os
|
17
18
|
when :macosx, :linux, :solaris, :bsd, :cygwin, :aix
|
18
|
-
|
19
|
-
Unix::PosixSpawnProcess.new(args)
|
20
|
-
elsif jruby?
|
21
|
-
JRuby::Process.new(args)
|
22
|
-
else
|
23
|
-
Unix::ForkExecProcess.new(args)
|
24
|
-
end
|
19
|
+
Unix::Process.new(*args)
|
25
20
|
when :windows
|
26
|
-
Windows::Process.new(args)
|
21
|
+
Windows::Process.new(*args)
|
27
22
|
else
|
28
23
|
raise Error, "unsupported platform #{platform_name.inspect}"
|
29
24
|
end
|
@@ -40,13 +35,7 @@ module ChildProcess
|
|
40
35
|
end
|
41
36
|
|
42
37
|
def platform
|
43
|
-
|
44
|
-
:jruby
|
45
|
-
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == "ironruby"
|
46
|
-
:ironruby
|
47
|
-
else
|
48
|
-
os
|
49
|
-
end
|
38
|
+
os
|
50
39
|
end
|
51
40
|
|
52
41
|
def platform_name
|
@@ -62,35 +51,18 @@ module ChildProcess
|
|
62
51
|
end
|
63
52
|
|
64
53
|
def jruby?
|
65
|
-
|
54
|
+
RUBY_ENGINE == 'jruby'
|
66
55
|
end
|
67
56
|
|
68
57
|
def windows?
|
69
58
|
os == :windows
|
70
59
|
end
|
71
60
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
begin
|
77
|
-
require 'ffi'
|
78
|
-
rescue LoadError
|
79
|
-
raise ChildProcess::MissingFFIError
|
80
|
-
end
|
81
|
-
|
82
|
-
begin
|
83
|
-
require "childprocess/unix/platform/#{ChildProcess.platform_name}"
|
84
|
-
rescue LoadError
|
85
|
-
raise ChildProcess::MissingPlatformError
|
86
|
-
end
|
87
|
-
|
88
|
-
require "childprocess/unix/lib"
|
89
|
-
require 'childprocess/unix/posix_spawn_process'
|
61
|
+
def posix_spawn_chosen_explicitly?
|
62
|
+
@posix_spawn || %w[1 true].include?(ENV['CHILDPROCESS_POSIX_SPAWN'])
|
63
|
+
end
|
90
64
|
|
91
|
-
|
92
|
-
rescue ChildProcess::MissingPlatformError => ex
|
93
|
-
warn_once ex.message
|
65
|
+
def posix_spawn?
|
94
66
|
false
|
95
67
|
end
|
96
68
|
|
@@ -103,6 +75,8 @@ module ChildProcess
|
|
103
75
|
end
|
104
76
|
|
105
77
|
def os
|
78
|
+
return :windows if ENV['FAKE_WINDOWS'] == 'true'
|
79
|
+
|
106
80
|
@os ||= (
|
107
81
|
require "rbconfig"
|
108
82
|
host_os = RbConfig::CONFIG['host_os'].downcase
|
@@ -158,17 +132,6 @@ module ChildProcess
|
|
158
132
|
def close_on_exec(file)
|
159
133
|
if file.respond_to?(:close_on_exec=)
|
160
134
|
file.close_on_exec = true
|
161
|
-
elsif file.respond_to?(:fcntl) && defined?(Fcntl::FD_CLOEXEC)
|
162
|
-
file.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
|
163
|
-
|
164
|
-
if jruby? && posix_spawn?
|
165
|
-
# on JRuby, the fcntl call above apparently isn't enough when
|
166
|
-
# we're launching the process through posix_spawn.
|
167
|
-
fileno = JRuby.posix_fileno_for(file)
|
168
|
-
Unix::Lib.fcntl fileno, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
|
169
|
-
end
|
170
|
-
elsif windows?
|
171
|
-
Windows::Lib.dont_inherit file
|
172
135
|
else
|
173
136
|
raise Error, "not sure how to set close-on-exec for #{file.inspect} on #{platform_name.inspect}"
|
174
137
|
end
|
@@ -203,8 +166,8 @@ module ChildProcess
|
|
203
166
|
end # class << self
|
204
167
|
end # ChildProcess
|
205
168
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
require 'childprocess/
|
210
|
-
|
169
|
+
if ChildProcess.windows?
|
170
|
+
require 'childprocess/windows'
|
171
|
+
else
|
172
|
+
require 'childprocess/unix'
|
173
|
+
end
|
data/spec/childprocess_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require File.expand_path('../spec_helper', __FILE__)
|
4
|
-
require 'rubygems/mock_gem_ui'
|
5
4
|
|
6
5
|
|
7
6
|
describe ChildProcess do
|
@@ -11,12 +10,17 @@ describe ChildProcess do
|
|
11
10
|
let(:gemspec) { eval(File.read "#{here}/../childprocess.gemspec") }
|
12
11
|
|
13
12
|
it 'validates cleanly' do
|
14
|
-
|
15
|
-
|
13
|
+
if Gem::VERSION >= "3.5.0"
|
14
|
+
expect { gemspec.validate }.not_to output(/warn/i).to_stderr
|
15
|
+
else
|
16
|
+
require 'rubygems/mock_gem_ui'
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
mock_ui = Gem::MockGemUi.new
|
19
|
+
Gem::DefaultUserInteraction.use_ui(mock_ui) { gemspec.validate }
|
19
20
|
|
21
|
+
expect(mock_ui.error).to_not match(/warn/i)
|
22
|
+
end
|
23
|
+
end
|
20
24
|
|
21
25
|
it "returns self when started" do
|
22
26
|
process = sleeping_ruby
|
@@ -25,14 +29,7 @@ describe ChildProcess do
|
|
25
29
|
expect(process).to be_alive
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
# without waiting for the child to exit with code 127.
|
30
|
-
#
|
31
|
-
# See e.g. http://repo.or.cz/w/glibc.git/blob/669704fd:/sysdeps/posix/spawni.c#l34
|
32
|
-
#
|
33
|
-
# We could work around this by doing the PATH search ourselves, but not sure
|
34
|
-
# it's worth it.
|
35
|
-
it "raises ChildProcess::LaunchError if the process can't be started", :posix_spawn_on_linux => false do
|
32
|
+
it "raises ChildProcess::LaunchError if the process can't be started" do
|
36
33
|
expect { invalid_process.start }.to raise_error(ChildProcess::LaunchError)
|
37
34
|
end
|
38
35
|
|
@@ -95,7 +92,7 @@ describe ChildProcess do
|
|
95
92
|
end
|
96
93
|
end
|
97
94
|
|
98
|
-
it "can override env vars only for the
|
95
|
+
it "can override env vars only for the child process" do
|
99
96
|
Tempfile.open("env-spec") do |file|
|
100
97
|
file.close
|
101
98
|
process = write_env(file.path)
|
@@ -127,6 +124,31 @@ describe ChildProcess do
|
|
127
124
|
end
|
128
125
|
end
|
129
126
|
|
127
|
+
it "can set env vars using Symbol keys and values" do
|
128
|
+
Tempfile.open("env-spec") do |file|
|
129
|
+
process = ruby('puts ENV["SYMBOL_KEY"]')
|
130
|
+
process.environment[:SYMBOL_KEY] = :VALUE
|
131
|
+
process.io.stdout = file
|
132
|
+
process.start
|
133
|
+
process.wait
|
134
|
+
expect(rewind_and_read(file)).to eq "VALUE\n"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "raises ChildProcess::InvalidEnvironmentVariable for invalid env vars" do
|
139
|
+
process = ruby(':OK')
|
140
|
+
process.environment["a\0b"] = '1'
|
141
|
+
expect { process.start }.to raise_error(ChildProcess::InvalidEnvironmentVariable)
|
142
|
+
|
143
|
+
process = ruby(':OK')
|
144
|
+
process.environment["A=1"] = '2'
|
145
|
+
expect { process.start }.to raise_error(ChildProcess::InvalidEnvironmentVariable)
|
146
|
+
|
147
|
+
process = ruby(':OK')
|
148
|
+
process.environment['A'] = "a\0b"
|
149
|
+
expect { process.start }.to raise_error(ChildProcess::InvalidEnvironmentVariable)
|
150
|
+
end
|
151
|
+
|
130
152
|
it "inherits the parent's env vars also when some are overridden" do
|
131
153
|
Tempfile.open("env-spec") do |file|
|
132
154
|
file.close
|
@@ -195,7 +217,7 @@ describe ChildProcess do
|
|
195
217
|
|
196
218
|
Tempfile.open('grandparent_out') do |gp_file|
|
197
219
|
# Create a parent and detached child process that will spit out their PID. Make sure that the child process lasts longer than the parent.
|
198
|
-
p_process = ruby("require 'childprocess' ; c_process = ChildProcess.build('ruby', '-e', 'puts \\\"Child PID: \#{Process.pid}\\\" ; sleep 5') ; c_process.io.inherit! ; c_process.detach = true ; c_process.start ; puts \"Child PID: \#{c_process.pid}\" ; puts \"Parent PID: \#{Process.pid}\"")
|
220
|
+
p_process = ruby("$: << 'lib'; require 'childprocess' ; c_process = ChildProcess.build('ruby', '-e', 'puts \\\"Child PID: \#{Process.pid}\\\" ; sleep 5') ; c_process.io.inherit! ; c_process.detach = true ; c_process.start ; puts \"Child PID: \#{c_process.pid}\" ; puts \"Parent PID: \#{Process.pid}\"")
|
199
221
|
p_process.io.stdout = p_process.io.stderr = gp_file
|
200
222
|
|
201
223
|
# Let the parent process die
|
@@ -277,7 +299,7 @@ describe ChildProcess do
|
|
277
299
|
}
|
278
300
|
end
|
279
301
|
|
280
|
-
it 'kills the full process tree'
|
302
|
+
it 'kills the full process tree' do
|
281
303
|
Tempfile.open('kill-process-tree') do |file|
|
282
304
|
process = write_pid_in_sleepy_grand_child(file.path)
|
283
305
|
process.leader = true
|
@@ -288,6 +310,8 @@ describe ChildProcess do
|
|
288
310
|
end
|
289
311
|
|
290
312
|
process.stop
|
313
|
+
expect(process).to be_exited
|
314
|
+
|
291
315
|
wait_until(3) { expect(alive?(pid)).to eql(false) }
|
292
316
|
end
|
293
317
|
end
|
data/spec/io_spec.rb
CHANGED
@@ -138,7 +138,7 @@ describe ChildProcess do
|
|
138
138
|
|
139
139
|
stdin.close
|
140
140
|
process.poll_for_exit(exit_timeout)
|
141
|
-
|
141
|
+
ensure
|
142
142
|
out_receiver.close
|
143
143
|
out.close
|
144
144
|
end
|
@@ -151,7 +151,7 @@ describe ChildProcess do
|
|
151
151
|
# http://travis-ci.org/#!/enkessler/childprocess/jobs/487331
|
152
152
|
#
|
153
153
|
|
154
|
-
it "works with pipes"
|
154
|
+
it "works with pipes" do
|
155
155
|
process = ruby(<<-CODE)
|
156
156
|
STDOUT.print "stdout"
|
157
157
|
STDERR.print "stderr"
|
data/spec/spec_helper.rb
CHANGED
@@ -210,16 +210,9 @@ module ChildProcessSpecHelper
|
|
210
210
|
end
|
211
211
|
|
212
212
|
def alive?(pid)
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
begin
|
217
|
-
Process.getpgid pid
|
218
|
-
true
|
219
|
-
rescue Errno::ESRCH
|
220
|
-
false
|
221
|
-
end
|
222
|
-
end
|
213
|
+
!!Process.kill(0, pid)
|
214
|
+
rescue Errno::ESRCH
|
215
|
+
false
|
223
216
|
end
|
224
217
|
|
225
218
|
def capture_std
|
@@ -259,12 +252,4 @@ RSpec.configure do |c|
|
|
259
252
|
c.after(:each) {
|
260
253
|
defined?(@process) && @process.alive? && @process.stop
|
261
254
|
}
|
262
|
-
|
263
|
-
if ChildProcess.jruby? && ChildProcess.new("true").instance_of?(ChildProcess::JRuby::Process)
|
264
|
-
c.filter_run_excluding :process_builder => false
|
265
|
-
end
|
266
|
-
|
267
|
-
if ChildProcess.linux? && ChildProcess.posix_spawn?
|
268
|
-
c.filter_run_excluding :posix_spawn_on_linux => false
|
269
|
-
end
|
270
255
|
end
|
data/spec/unix_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../spec_helper', __FILE__)
|
2
2
|
require "pid_behavior"
|
3
3
|
|
4
|
-
if ChildProcess.unix?
|
4
|
+
if ChildProcess.unix?
|
5
5
|
|
6
6
|
describe ChildProcess::Unix::Process do
|
7
7
|
it_behaves_like "a platform that provides the child's pid"
|
@@ -9,7 +9,7 @@ if ChildProcess.unix? && !ChildProcess.jruby? && !ChildProcess.posix_spawn?
|
|
9
9
|
it "handles ECHILD race condition where process dies between timeout and KILL" do
|
10
10
|
process = sleeping_ruby
|
11
11
|
|
12
|
-
allow(
|
12
|
+
allow(Process).to receive(:spawn).and_return('fakepid')
|
13
13
|
allow(process).to receive(:send_term)
|
14
14
|
allow(process).to receive(:poll_for_exit).and_raise(ChildProcess::TimeoutError)
|
15
15
|
allow(process).to receive(:send_kill).and_raise(Errno::ECHILD.new)
|
@@ -18,14 +18,12 @@ if ChildProcess.unix? && !ChildProcess.jruby? && !ChildProcess.posix_spawn?
|
|
18
18
|
expect { process.stop }.not_to raise_error
|
19
19
|
|
20
20
|
allow(process).to receive(:alive?).and_return(false)
|
21
|
-
|
22
|
-
process.send(:send_signal, 'TERM')
|
23
21
|
end
|
24
22
|
|
25
23
|
it "handles ESRCH race condition where process dies between timeout and KILL" do
|
26
24
|
process = sleeping_ruby
|
27
25
|
|
28
|
-
allow(
|
26
|
+
allow(Process).to receive(:spawn).and_return('fakepid')
|
29
27
|
allow(process).to receive(:send_term)
|
30
28
|
allow(process).to receive(:poll_for_exit).and_raise(ChildProcess::TimeoutError)
|
31
29
|
allow(process).to receive(:send_kill).and_raise(Errno::ESRCH.new)
|
@@ -34,8 +32,6 @@ if ChildProcess.unix? && !ChildProcess.jruby? && !ChildProcess.posix_spawn?
|
|
34
32
|
expect { process.stop }.not_to raise_error
|
35
33
|
|
36
34
|
allow(process).to receive(:alive?).and_return(false)
|
37
|
-
|
38
|
-
process.send(:send_signal, 'TERM')
|
39
35
|
end
|
40
36
|
end
|
41
37
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: childprocess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jari Bakken
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-01-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -64,54 +64,37 @@ extensions: []
|
|
64
64
|
extra_rdoc_files: []
|
65
65
|
files:
|
66
66
|
- ".document"
|
67
|
+
- ".github/workflows/ci.yml"
|
67
68
|
- ".gitignore"
|
68
69
|
- ".rspec"
|
69
|
-
- ".travis.yml"
|
70
70
|
- CHANGELOG.md
|
71
71
|
- Gemfile
|
72
72
|
- LICENSE
|
73
73
|
- README.md
|
74
74
|
- Rakefile
|
75
|
-
- appveyor.yml
|
76
75
|
- childprocess.gemspec
|
77
76
|
- lib/childprocess.rb
|
78
77
|
- lib/childprocess/abstract_io.rb
|
79
78
|
- lib/childprocess/abstract_process.rb
|
80
79
|
- lib/childprocess/errors.rb
|
81
|
-
- lib/childprocess/
|
82
|
-
- lib/childprocess/jruby/io.rb
|
83
|
-
- lib/childprocess/jruby/process.rb
|
84
|
-
- lib/childprocess/jruby/pump.rb
|
85
|
-
- lib/childprocess/tools/generator.rb
|
80
|
+
- lib/childprocess/process_spawn_process.rb
|
86
81
|
- lib/childprocess/unix.rb
|
87
|
-
- lib/childprocess/unix/fork_exec_process.rb
|
88
82
|
- lib/childprocess/unix/io.rb
|
89
|
-
- lib/childprocess/unix/lib.rb
|
90
|
-
- lib/childprocess/unix/platform/i386-linux.rb
|
91
|
-
- lib/childprocess/unix/platform/i386-solaris.rb
|
92
|
-
- lib/childprocess/unix/platform/x86_64-linux.rb
|
93
|
-
- lib/childprocess/unix/platform/x86_64-macosx.rb
|
94
|
-
- lib/childprocess/unix/posix_spawn_process.rb
|
95
83
|
- lib/childprocess/unix/process.rb
|
96
84
|
- lib/childprocess/version.rb
|
97
85
|
- lib/childprocess/windows.rb
|
98
|
-
- lib/childprocess/windows/handle.rb
|
99
86
|
- lib/childprocess/windows/io.rb
|
100
|
-
- lib/childprocess/windows/lib.rb
|
101
87
|
- lib/childprocess/windows/process.rb
|
102
|
-
- lib/childprocess/windows/process_builder.rb
|
103
|
-
- lib/childprocess/windows/structs.rb
|
104
88
|
- spec/abstract_io_spec.rb
|
105
89
|
- spec/childprocess_spec.rb
|
106
90
|
- spec/get_env.ps1
|
107
91
|
- spec/io_spec.rb
|
108
|
-
- spec/jruby_spec.rb
|
109
92
|
- spec/pid_behavior.rb
|
110
93
|
- spec/platform_detection_spec.rb
|
111
94
|
- spec/spec_helper.rb
|
112
95
|
- spec/unix_spec.rb
|
113
96
|
- spec/windows_spec.rb
|
114
|
-
homepage:
|
97
|
+
homepage: https://github.com/enkessler/childprocess
|
115
98
|
licenses:
|
116
99
|
- MIT
|
117
100
|
metadata: {}
|
@@ -130,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
113
|
- !ruby/object:Gem::Version
|
131
114
|
version: '0'
|
132
115
|
requirements: []
|
133
|
-
rubygems_version: 3.
|
116
|
+
rubygems_version: 3.0.3.1
|
134
117
|
signing_key:
|
135
118
|
specification_version: 4
|
136
119
|
summary: A simple and reliable solution for controlling external programs running
|
@@ -140,7 +123,6 @@ test_files:
|
|
140
123
|
- spec/childprocess_spec.rb
|
141
124
|
- spec/get_env.ps1
|
142
125
|
- spec/io_spec.rb
|
143
|
-
- spec/jruby_spec.rb
|
144
126
|
- spec/pid_behavior.rb
|
145
127
|
- spec/platform_detection_spec.rb
|
146
128
|
- spec/spec_helper.rb
|
data/.travis.yml
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
os:
|
2
|
-
- linux
|
3
|
-
- osx
|
4
|
-
|
5
|
-
rvm:
|
6
|
-
- rbx-3
|
7
|
-
- 2.4
|
8
|
-
- 2.5
|
9
|
-
- 2.6
|
10
|
-
- ruby-head
|
11
|
-
|
12
|
-
sudo: false
|
13
|
-
|
14
|
-
cache: bundler
|
15
|
-
|
16
|
-
before_install:
|
17
|
-
- "echo 'gem: --no-document' > ~/.gemrc"
|
18
|
-
- gem install bundler
|
19
|
-
|
20
|
-
before_script:
|
21
|
-
- 'export JAVA_OPTS="${JAVA_OPTS_FOR_SPECS}"'
|
22
|
-
|
23
|
-
env:
|
24
|
-
global:
|
25
|
-
matrix:
|
26
|
-
- CHILDPROCESS_POSIX_SPAWN=true CHILDPROCESS_UNSET=should-be-unset
|
27
|
-
- CHILDPROCESS_POSIX_SPAWN=false CHILDPROCESS_UNSET=should-be-unset
|
28
|
-
|
29
|
-
matrix:
|
30
|
-
allow_failures:
|
31
|
-
- rvm: rbx-3
|
32
|
-
- rvm: ruby-head
|
33
|
-
- env: "CHILDPROCESS_POSIX_SPAWN=true"
|
34
|
-
include:
|
35
|
-
- rvm: jruby-9.2.5.0
|
36
|
-
jdk: openjdk11
|
37
|
-
env: "JAVA_OPTS_FOR_SPECS='--add-opens java.base/java.io=org.jruby.dist --add-opens java.base/sun.nio.ch=org.jruby.dist'"
|
data/appveyor.yml
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
version: '1.0.{build}'
|
2
|
-
|
3
|
-
environment:
|
4
|
-
matrix:
|
5
|
-
- CHILDPROCESS_POSIX_SPAWN: true
|
6
|
-
CHILDPROCESS_UNSET: should-be-unset
|
7
|
-
RUBY_VERSION: 24-x64
|
8
|
-
- CHILDPROCESS_POSIX_SPAWN: false
|
9
|
-
CHILDPROCESS_UNSET: should-be-unset
|
10
|
-
RUBY_VERSION: 24-x64
|
11
|
-
- CHILDPROCESS_POSIX_SPAWN: true
|
12
|
-
CHILDPROCESS_UNSET: should-be-unset
|
13
|
-
RUBY_VERSION: 25-x64
|
14
|
-
- CHILDPROCESS_POSIX_SPAWN: false
|
15
|
-
CHILDPROCESS_UNSET: should-be-unset
|
16
|
-
RUBY_VERSION: 25-x64
|
17
|
-
- CHILDPROCESS_POSIX_SPAWN: true
|
18
|
-
CHILDPROCESS_UNSET: should-be-unset
|
19
|
-
RUBY_VERSION: 26-x64
|
20
|
-
- CHILDPROCESS_POSIX_SPAWN: false
|
21
|
-
CHILDPROCESS_UNSET: should-be-unset
|
22
|
-
RUBY_VERSION: 26-x64
|
23
|
-
|
24
|
-
install:
|
25
|
-
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
26
|
-
- bundle install
|
27
|
-
|
28
|
-
build: off
|
29
|
-
|
30
|
-
before_test:
|
31
|
-
- ruby -v
|
32
|
-
- gem -v
|
33
|
-
- bundle -v
|
34
|
-
|
35
|
-
test_script:
|
36
|
-
- bundle exec rake
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module ChildProcess
|
2
|
-
module JRuby
|
3
|
-
class IO < AbstractIO
|
4
|
-
private
|
5
|
-
|
6
|
-
def check_type(output)
|
7
|
-
unless output.respond_to?(:to_outputstream) && output.respond_to?(:write)
|
8
|
-
raise ArgumentError, "expected #{output.inspect} to respond to :to_outputstream"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
end # IO
|
13
|
-
end # Unix
|
14
|
-
end # ChildProcess
|
15
|
-
|
16
|
-
|
@@ -1,184 +0,0 @@
|
|
1
|
-
require "java"
|
2
|
-
|
3
|
-
module ChildProcess
|
4
|
-
module JRuby
|
5
|
-
class Process < AbstractProcess
|
6
|
-
def initialize(args)
|
7
|
-
super(args)
|
8
|
-
|
9
|
-
@pumps = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def io
|
13
|
-
@io ||= JRuby::IO.new
|
14
|
-
end
|
15
|
-
|
16
|
-
def exited?
|
17
|
-
return true if @exit_code
|
18
|
-
|
19
|
-
assert_started
|
20
|
-
@exit_code = @process.exitValue
|
21
|
-
stop_pumps
|
22
|
-
|
23
|
-
true
|
24
|
-
rescue java.lang.IllegalThreadStateException => ex
|
25
|
-
log(ex.class => ex.message)
|
26
|
-
false
|
27
|
-
ensure
|
28
|
-
log(:exit_code => @exit_code)
|
29
|
-
end
|
30
|
-
|
31
|
-
def stop(timeout = nil)
|
32
|
-
assert_started
|
33
|
-
|
34
|
-
@process.destroy
|
35
|
-
wait # no way to actually use the timeout here..
|
36
|
-
end
|
37
|
-
|
38
|
-
def wait
|
39
|
-
if exited?
|
40
|
-
exit_code
|
41
|
-
else
|
42
|
-
@process.waitFor
|
43
|
-
|
44
|
-
stop_pumps
|
45
|
-
@exit_code = @process.exitValue
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Implementation of ChildProcess::JRuby::Process#pid depends heavily on
|
50
|
-
# what Java SDK is being used; here, we look it up once at load, then
|
51
|
-
# define the method once to avoid runtime overhead.
|
52
|
-
normalised_java_version_major = java.lang.System.get_property("java.version")
|
53
|
-
.slice(/^(1\.)?([0-9]+)/, 2)
|
54
|
-
.to_i
|
55
|
-
if normalised_java_version_major >= 9
|
56
|
-
|
57
|
-
# On modern Javas, we can simply delegate through to `Process#pid`,
|
58
|
-
# which was introduced in Java 9.
|
59
|
-
#
|
60
|
-
# @return [Integer] the pid of the process after it has started
|
61
|
-
# @raise [NotImplementedError] when trying to access pid on platform for
|
62
|
-
# which it is unsupported in Java
|
63
|
-
def pid
|
64
|
-
@process.pid
|
65
|
-
rescue java.lang.UnsupportedOperationException => e
|
66
|
-
raise NotImplementedError, "pid is not supported on this platform: #{e.message}"
|
67
|
-
end
|
68
|
-
|
69
|
-
else
|
70
|
-
|
71
|
-
# On Legacy Javas, fall back to reflection.
|
72
|
-
#
|
73
|
-
# Only supported in JRuby on a Unix operating system, thanks to limitations
|
74
|
-
# in Java's classes
|
75
|
-
#
|
76
|
-
# @return [Integer] the pid of the process after it has started
|
77
|
-
# @raise [NotImplementedError] when trying to access pid on non-Unix platform
|
78
|
-
#
|
79
|
-
def pid
|
80
|
-
if @process.getClass.getName != "java.lang.UNIXProcess"
|
81
|
-
raise NotImplementedError, "pid is only supported by JRuby child processes on Unix"
|
82
|
-
end
|
83
|
-
|
84
|
-
# About the best way we can do this is with a nasty reflection-based impl
|
85
|
-
# Thanks to Martijn Courteaux
|
86
|
-
# http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193
|
87
|
-
field = @process.getClass.getDeclaredField("pid")
|
88
|
-
field.accessible = true
|
89
|
-
field.get(@process)
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def launch_process(&blk)
|
97
|
-
pb = java.lang.ProcessBuilder.new(@args)
|
98
|
-
|
99
|
-
pb.directory java.io.File.new(@cwd || Dir.pwd)
|
100
|
-
set_env pb.environment
|
101
|
-
|
102
|
-
begin
|
103
|
-
@process = pb.start
|
104
|
-
rescue java.io.IOException => ex
|
105
|
-
raise LaunchError, ex.message
|
106
|
-
end
|
107
|
-
|
108
|
-
setup_io
|
109
|
-
end
|
110
|
-
|
111
|
-
def setup_io
|
112
|
-
if @io
|
113
|
-
redirect(@process.getErrorStream, @io.stderr)
|
114
|
-
redirect(@process.getInputStream, @io.stdout)
|
115
|
-
else
|
116
|
-
@process.getErrorStream.close
|
117
|
-
@process.getInputStream.close
|
118
|
-
end
|
119
|
-
|
120
|
-
if duplex?
|
121
|
-
io._stdin = create_stdin
|
122
|
-
else
|
123
|
-
@process.getOutputStream.close
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def redirect(input, output)
|
128
|
-
if output.nil?
|
129
|
-
input.close
|
130
|
-
return
|
131
|
-
end
|
132
|
-
|
133
|
-
@pumps << Pump.new(input, output.to_outputstream).run
|
134
|
-
end
|
135
|
-
|
136
|
-
def stop_pumps
|
137
|
-
@pumps.each { |pump| pump.stop }
|
138
|
-
end
|
139
|
-
|
140
|
-
def set_env(env)
|
141
|
-
merged = ENV.to_hash
|
142
|
-
|
143
|
-
@environment.each { |k, v| merged[k.to_s] = v }
|
144
|
-
|
145
|
-
merged.each do |k, v|
|
146
|
-
if v
|
147
|
-
env.put(k, v.to_s)
|
148
|
-
elsif env.has_key? k
|
149
|
-
env.remove(k)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
removed_keys = env.key_set.to_a - merged.keys
|
154
|
-
removed_keys.each { |k| env.remove(k) }
|
155
|
-
end
|
156
|
-
|
157
|
-
def create_stdin
|
158
|
-
output_stream = @process.getOutputStream
|
159
|
-
|
160
|
-
stdin = output_stream.to_io
|
161
|
-
stdin.sync = true
|
162
|
-
stdin.instance_variable_set(:@childprocess_java_stream, output_stream)
|
163
|
-
|
164
|
-
class << stdin
|
165
|
-
# The stream provided is a BufferedeOutputStream, so we
|
166
|
-
# have to flush it to make the bytes flow to the process
|
167
|
-
def __childprocess_flush__
|
168
|
-
@childprocess_java_stream.flush
|
169
|
-
end
|
170
|
-
|
171
|
-
[:flush, :print, :printf, :putc, :puts, :write, :write_nonblock].each do |m|
|
172
|
-
define_method(m) do |*args|
|
173
|
-
super(*args)
|
174
|
-
self.__childprocess_flush__
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
stdin
|
180
|
-
end
|
181
|
-
|
182
|
-
end # Process
|
183
|
-
end # JRuby
|
184
|
-
end # ChildProcess
|