childprocess 4.1.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +23 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +0 -2
  5. data/README.md +3 -20
  6. data/lib/childprocess/abstract_process.rb +1 -1
  7. data/lib/childprocess/errors.rb +0 -21
  8. data/lib/childprocess/process_spawn_process.rb +127 -0
  9. data/lib/childprocess/unix/process.rb +3 -64
  10. data/lib/childprocess/unix.rb +2 -4
  11. data/lib/childprocess/version.rb +1 -1
  12. data/lib/childprocess/windows/process.rb +13 -116
  13. data/lib/childprocess/windows.rb +0 -29
  14. data/lib/childprocess.rb +16 -53
  15. data/spec/childprocess_spec.rb +39 -15
  16. data/spec/io_spec.rb +1 -1
  17. data/spec/spec_helper.rb +3 -18
  18. data/spec/unix_spec.rb +3 -7
  19. metadata +8 -27
  20. data/.travis.yml +0 -37
  21. data/appveyor.yml +0 -36
  22. data/lib/childprocess/jruby/io.rb +0 -16
  23. data/lib/childprocess/jruby/process.rb +0 -184
  24. data/lib/childprocess/jruby/pump.rb +0 -53
  25. data/lib/childprocess/jruby.rb +0 -56
  26. data/lib/childprocess/tools/generator.rb +0 -146
  27. data/lib/childprocess/unix/fork_exec_process.rb +0 -78
  28. data/lib/childprocess/unix/lib.rb +0 -186
  29. data/lib/childprocess/unix/platform/arm64-macosx.rb +0 -11
  30. data/lib/childprocess/unix/platform/i386-linux.rb +0 -12
  31. data/lib/childprocess/unix/platform/i386-solaris.rb +0 -11
  32. data/lib/childprocess/unix/platform/x86_64-linux.rb +0 -12
  33. data/lib/childprocess/unix/platform/x86_64-macosx.rb +0 -11
  34. data/lib/childprocess/unix/posix_spawn_process.rb +0 -134
  35. data/lib/childprocess/windows/handle.rb +0 -91
  36. data/lib/childprocess/windows/lib.rb +0 -416
  37. data/lib/childprocess/windows/process_builder.rb +0 -178
  38. data/lib/childprocess/windows/structs.rb +0 -149
  39. data/spec/jruby_spec.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a5e6dc8970dbfa81b42c587480b4cd7a564995c2a6a0be84f2c8192edcf6d0c
4
- data.tar.gz: 766be22f3575a6ef9ba837a37722f0a852f509fc9efb2a77b01ca121b865a28e
3
+ metadata.gz: 3b5d923affd397c31cc2193e6dc9d6e1a6d32e485f3721210e65caf72b9ee138
4
+ data.tar.gz: '06896c2aa64a9c521b45206d1a0638a8aa63e433a013c261909a920fab135c75'
5
5
  SHA512:
6
- metadata.gz: 8e4ac84967566de68d200d983bfebca6fce9575d7e8fb0aa0324b64dc4b6e0d29d29abe173ce99a54f8b37501eb515573b457f6b612a395f3f5d2bc672da6802
7
- data.tar.gz: 16bc7aaffd67ab47f1f8a8ded31681fb88f1767421838c3ddb1f1033fb7dc0f5c5d664b7dce3fb4107edb9818a73ce2769f23a3e1f30bf51ffc3dd088d8a7690
6
+ metadata.gz: a0a5d3cfee92a6e4896eaf557dbf4fc50d54b54d42c43033776165991b1b606f12ccd1e17d0dbe26963b7d002482ee40877b3ea024765b371393e4a0cbd0343f
7
+ data.tar.gz: 6814491e59bbb30b61393670ca84d5da9d61ea5cb5dbc54a45599ef9cb7318bbf82751fddaf5c7ee5ef501718d7cad4a08636fab3a379148899af3acd0303bd4
@@ -0,0 +1,23 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ fail-fast: false
7
+ matrix:
8
+ os: [ ubuntu, macos, windows ]
9
+ ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', jruby, truffleruby ]
10
+ exclude:
11
+ - { os: windows, ruby: truffleruby }
12
+ # fails to load rspec: RuntimeError: CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before false -> after true
13
+ - { os: windows, ruby: jruby }
14
+ runs-on: ${{ matrix.os }}-latest
15
+ env:
16
+ CHILDPROCESS_UNSET: should-be-unset
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - run: bundle exec rake spec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### Version 5.0.0 / 2024-01-06
2
+
3
+ * [#175](https://github.com/enkessler/childprocess/pull/175): Replace all backends by `Process.spawn` for portability, reliability and simplicity.
4
+ * [#185](https://github.com/enkessler/childprocess/pull/185): Add support for Ruby 3.x
5
+
1
6
  ### Version 4.1.0 / 2021-06-08
2
7
 
3
8
  * [#170](https://github.com/enkessler/childprocess/pull/170): Update gem homepage to use `https://`
data/Gemfile CHANGED
@@ -5,5 +5,3 @@ gemspec
5
5
 
6
6
  # Used for local development/testing only
7
7
  gem 'rake'
8
-
9
- gem 'ffi' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true' || Gem.win_platform?
data/README.md CHANGED
@@ -16,8 +16,6 @@ a standalone library.
16
16
 
17
17
  * Ruby 2.4+, JRuby 9+
18
18
 
19
- Windows users **must** ensure the `ffi` gem (`>= 1.0.11`) is installed in order to use ChildProcess.
20
-
21
19
  # Usage
22
20
 
23
21
  The object returned from `ChildProcess.build` will implement `ChildProcess::AbstractProcess`.
@@ -73,9 +71,9 @@ begin
73
71
  process = ChildProcess.build("sh" , "-c",
74
72
  "for i in {1..3}; do echo $i; sleep 1; done")
75
73
  process.io.stdout = w
76
- process.start # This results in a fork, inheriting the write end of the pipe.
74
+ process.start # This results in a subprocess inheriting the write end of the pipe.
77
75
 
78
- # Close parent's copy of the write end of the pipe so when the (forked) child
76
+ # Close parent's copy of the write end of the pipe so when the child
79
77
  # process closes its write end of the pipe the parent receives EOF when
80
78
  # attempting to read from it. If the parent leaves its write end open, it
81
79
  # will not detect EOF.
@@ -138,17 +136,6 @@ search.io.stdin.close
138
136
  search.wait
139
137
  ```
140
138
 
141
- #### Prefer posix_spawn on *nix
142
-
143
- If the parent process is using a lot of memory, `fork+exec` can be very expensive. The `posix_spawn()` API removes this overhead.
144
-
145
- ```ruby
146
- ChildProcess.posix_spawn = true
147
- process = ChildProcess.build(*args)
148
- ```
149
-
150
- To be able to use this, please make sure that you have the `ffi` gem installed.
151
-
152
139
  ### Ensure entire process tree dies
153
140
 
154
141
  By default, the child process does not create a new process group. This means there's no guarantee that the entire process tree will die when the child process is killed. To solve this:
@@ -195,11 +182,7 @@ ChildProcess.logger = logger
195
182
 
196
183
  # Implementation
197
184
 
198
- How the process is launched and killed depends on the platform:
199
-
200
- * Unix : `fork + exec` (or `posix_spawn` if enabled)
201
- * Windows : `CreateProcess()` and friends
202
- * JRuby : `java.lang.{Process,ProcessBuilder}`
185
+ ChildProcess 5+ uses `Process.spawn` from the Ruby core library for maximum portability.
203
186
 
204
187
  # Note on Patches/Pull Requests
205
188
 
@@ -39,7 +39,7 @@ module ChildProcess
39
39
  # @see ChildProcess.build
40
40
  #
41
41
 
42
- def initialize(args)
42
+ def initialize(*args)
43
43
  unless args.all? { |e| e.kind_of?(String) }
44
44
  raise ArgumentError, "all arguments must be String: #{args.inspect}"
45
45
  end
@@ -13,25 +13,4 @@ module ChildProcess
13
13
 
14
14
  class LaunchError < Error
15
15
  end
16
-
17
- class MissingFFIError < Error
18
- def initialize
19
- message = "FFI is a required pre-requisite for Windows or posix_spawn support in the ChildProcess gem. " +
20
- "Ensure the `ffi` gem is installed. " +
21
- "If you believe this is an error, please file a bug at http://github.com/enkessler/childprocess/issues"
22
-
23
- super(message)
24
- end
25
-
26
- end
27
-
28
- class MissingPlatformError < Error
29
- def initialize
30
- message = "posix_spawn is not yet supported on #{ChildProcess.platform_name} (#{RUBY_PLATFORM}), falling back to default implementation. " +
31
- "If you believe this is an error, please file a bug at http://github.com/enkessler/childprocess/issues"
32
-
33
- super(message)
34
- end
35
-
36
- end
37
16
  end
@@ -0,0 +1,127 @@
1
+ require_relative 'abstract_process'
2
+
3
+ module ChildProcess
4
+ class ProcessSpawnProcess < AbstractProcess
5
+ attr_reader :pid
6
+
7
+ def exited?
8
+ return true if @exit_code
9
+
10
+ assert_started
11
+ pid, status = ::Process.waitpid2(@pid, ::Process::WNOHANG | ::Process::WUNTRACED)
12
+ pid = nil if pid == 0 # may happen on jruby
13
+
14
+ log(:pid => pid, :status => status)
15
+
16
+ if pid
17
+ set_exit_code(status)
18
+ end
19
+
20
+ !!pid
21
+ rescue Errno::ECHILD
22
+ # may be thrown for detached processes
23
+ true
24
+ end
25
+
26
+ def wait
27
+ assert_started
28
+
29
+ if exited?
30
+ exit_code
31
+ else
32
+ _, status = ::Process.waitpid2(@pid)
33
+
34
+ set_exit_code(status)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def launch_process
41
+ environment = {}
42
+ @environment.each_pair do |key, value|
43
+ key = key.to_s
44
+ value = value.nil? ? nil : value.to_s
45
+
46
+ if key.include?("\0") || key.include?("=") || value.to_s.include?("\0")
47
+ raise InvalidEnvironmentVariable, "#{key.inspect} => #{value.to_s.inspect}"
48
+ end
49
+ environment[key] = value
50
+ end
51
+
52
+ options = {}
53
+
54
+ options[:out] = io.stdout ? io.stdout.fileno : File::NULL
55
+ options[:err] = io.stderr ? io.stderr.fileno : File::NULL
56
+
57
+ if duplex?
58
+ reader, writer = ::IO.pipe
59
+ options[:in] = reader.fileno
60
+ unless ChildProcess.windows?
61
+ options[writer.fileno] = :close
62
+ end
63
+ end
64
+
65
+ if leader?
66
+ if ChildProcess.windows?
67
+ options[:new_pgroup] = true
68
+ else
69
+ options[:pgroup] = true
70
+ end
71
+ end
72
+
73
+ options[:chdir] = @cwd if @cwd
74
+
75
+ if @args.size == 1
76
+ # When given a single String, Process.spawn would think it should use the shell
77
+ # if there is any special character in it. However, ChildProcess should never
78
+ # use the shell. So we use the [cmdname, argv0] form to force no shell.
79
+ arg = @args[0]
80
+ args = [[arg, arg]]
81
+ else
82
+ args = @args
83
+ end
84
+
85
+ begin
86
+ @pid = ::Process.spawn(environment, *args, options)
87
+ rescue SystemCallError => e
88
+ raise LaunchError, e.message
89
+ end
90
+
91
+ if duplex?
92
+ io._stdin = writer
93
+ reader.close
94
+ end
95
+
96
+ ::Process.detach(@pid) if detach?
97
+ end
98
+
99
+ def set_exit_code(status)
100
+ @exit_code = status.exitstatus || status.termsig
101
+ end
102
+
103
+ def send_term
104
+ send_signal 'TERM'
105
+ end
106
+
107
+ def send_kill
108
+ send_signal 'KILL'
109
+ end
110
+
111
+ def send_signal(sig)
112
+ assert_started
113
+
114
+ log "sending #{sig}"
115
+ if leader?
116
+ if ChildProcess.unix?
117
+ ::Process.kill sig, -@pid # negative pid == process group
118
+ else
119
+ output = `taskkill /F /T /PID #{@pid}`
120
+ log output
121
+ end
122
+ else
123
+ ::Process.kill sig, @pid
124
+ end
125
+ end
126
+ end
127
+ end
@@ -1,8 +1,8 @@
1
+ require_relative '../process_spawn_process'
2
+
1
3
  module ChildProcess
2
4
  module Unix
3
- class Process < AbstractProcess
4
- attr_reader :pid
5
-
5
+ class Process < ProcessSpawnProcess
6
6
  def io
7
7
  @io ||= Unix::IO.new
8
8
  end
@@ -24,67 +24,6 @@ module ChildProcess
24
24
  # and send_kill
25
25
  true
26
26
  end
27
-
28
- def exited?
29
- return true if @exit_code
30
-
31
- assert_started
32
- pid, status = ::Process.waitpid2(@pid, ::Process::WNOHANG | ::Process::WUNTRACED)
33
- pid = nil if pid == 0 # may happen on jruby
34
-
35
- log(:pid => pid, :status => status)
36
-
37
- if pid
38
- set_exit_code(status)
39
- end
40
-
41
- !!pid
42
- rescue Errno::ECHILD
43
- # may be thrown for detached processes
44
- true
45
- end
46
-
47
- def wait
48
- assert_started
49
-
50
- if exited?
51
- exit_code
52
- else
53
- _, status = ::Process.waitpid2(@pid)
54
-
55
- set_exit_code(status)
56
- end
57
- end
58
-
59
- private
60
-
61
- def send_term
62
- send_signal 'TERM'
63
- end
64
-
65
- def send_kill
66
- send_signal 'KILL'
67
- end
68
-
69
- def send_signal(sig)
70
- assert_started
71
-
72
- log "sending #{sig}"
73
- ::Process.kill sig, _pid
74
- end
75
-
76
- def set_exit_code(status)
77
- @exit_code = status.exitstatus || status.termsig
78
- end
79
-
80
- def _pid
81
- if leader?
82
- -@pid # negative pid == process group
83
- else
84
- @pid
85
- end
86
- end
87
-
88
27
  end # Process
89
28
  end # Unix
90
29
  end # ChildProcess
@@ -3,7 +3,5 @@ module ChildProcess
3
3
  end
4
4
  end
5
5
 
6
- require "childprocess/unix/io"
7
- require "childprocess/unix/process"
8
- require "childprocess/unix/fork_exec_process"
9
- # PosixSpawnProcess + ffi is required on demand.
6
+ require_relative "unix/io"
7
+ require_relative "unix/process"
@@ -1,3 +1,3 @@
1
1
  module ChildProcess
2
- VERSION = '4.1.0'
2
+ VERSION = '5.0.0'
3
3
  end
@@ -1,131 +1,28 @@
1
+ require_relative '../process_spawn_process'
2
+
1
3
  module ChildProcess
2
4
  module Windows
3
- class Process < AbstractProcess
4
-
5
- attr_reader :pid
6
-
5
+ class Process < ProcessSpawnProcess
7
6
  def io
8
7
  @io ||= Windows::IO.new
9
8
  end
10
9
 
11
10
  def stop(timeout = 3)
12
11
  assert_started
12
+ send_kill
13
13
 
14
- log "sending KILL"
15
- @handle.send(WIN_SIGKILL)
16
-
17
- poll_for_exit(timeout)
18
- ensure
19
- close_handle
20
- close_job_if_necessary
21
- end
22
-
23
- def wait
24
- if exited?
25
- exit_code
26
- else
27
- @handle.wait
28
- @exit_code = @handle.exit_code
29
-
30
- close_handle
31
- close_job_if_necessary
32
-
33
- @exit_code
34
- end
35
- end
36
-
37
- def exited?
38
- return true if @exit_code
39
- assert_started
40
-
41
- code = @handle.exit_code
42
- exited = code != PROCESS_STILL_ACTIVE
43
-
44
- log(:exited? => exited, :code => code)
45
-
46
- if exited
47
- @exit_code = code
48
- close_handle
49
- close_job_if_necessary
50
- end
51
-
52
- exited
53
- end
54
-
55
- private
56
-
57
- def launch_process
58
- builder = ProcessBuilder.new(@args)
59
- builder.leader = leader?
60
- builder.detach = detach?
61
- builder.duplex = duplex?
62
- builder.environment = @environment unless @environment.empty?
63
- builder.cwd = @cwd
64
-
65
- if @io
66
- builder.stdout = @io.stdout
67
- builder.stderr = @io.stderr
68
- end
69
-
70
- @pid = builder.start
71
- @handle = Handle.open @pid
72
-
73
- if leader?
74
- @job = Job.new(detach?, true)
75
- @job << @handle
76
- end
77
-
78
- if duplex?
79
- raise Error, "no stdin stream" unless builder.stdin
80
- io._stdin = builder.stdin
81
- end
82
-
83
- self
84
- end
85
-
86
- def close_handle
87
- @handle.close
88
- end
89
-
90
- def close_job_if_necessary
91
- @job.close if leader?
92
- end
93
-
94
-
95
- class Job
96
- def initialize(detach, leader)
97
- @pointer = Lib.create_job_object(nil, nil)
98
-
99
- if @pointer.nil? || @pointer.null?
100
- raise Error, "unable to create job object"
101
- end
102
-
103
- basic = JobObjectBasicLimitInformation.new
104
- basic[:LimitFlags] |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE if !detach
105
- basic[:LimitFlags] |= JOB_OBJECT_LIMIT_BREAKAWAY_OK if leader
106
-
107
- extended = JobObjectExtendedLimitInformation.new
108
- extended[:BasicLimitInformation] = basic
109
-
110
- ret = Lib.set_information_job_object(
111
- @pointer,
112
- JOB_OBJECT_EXTENDED_LIMIT_INFORMATION,
113
- extended,
114
- extended.size
115
- )
116
-
117
- Lib.check_error ret
118
- end
119
-
120
- def <<(handle)
121
- Lib.check_error Lib.assign_process_to_job_object(@pointer, handle.pointer)
14
+ begin
15
+ return poll_for_exit(timeout)
16
+ rescue TimeoutError
17
+ # try next
122
18
  end
123
19
 
124
- def close
125
- Lib.close_handle @pointer
126
- end
20
+ wait
21
+ rescue Errno::ECHILD, Errno::ESRCH
22
+ # handle race condition where process dies between timeout
23
+ # and send_kill
24
+ true
127
25
  end
128
-
129
26
  end # Process
130
27
  end # Windows
131
28
  end # ChildProcess
@@ -1,38 +1,9 @@
1
1
  require "rbconfig"
2
2
 
3
- begin
4
- require 'ffi'
5
- rescue LoadError
6
- raise ChildProcess::MissingFFIError
7
- end
8
-
9
3
  module ChildProcess
10
4
  module Windows
11
- module Lib
12
- extend FFI::Library
13
-
14
- def self.msvcrt_name
15
- host_part = RbConfig::CONFIG['host_os'].split("_")[1]
16
- manifest = File.join(RbConfig::CONFIG['bindir'], 'ruby.exe.manifest')
17
-
18
- if host_part && host_part.to_i > 80 && File.exists?(manifest)
19
- "msvcr#{host_part}"
20
- else
21
- "msvcrt"
22
- end
23
- end
24
-
25
- ffi_lib "kernel32", msvcrt_name
26
- ffi_convention :stdcall
27
-
28
-
29
- end # Library
30
5
  end # Windows
31
6
  end # ChildProcess
32
7
 
33
- require "childprocess/windows/lib"
34
- require "childprocess/windows/structs"
35
- require "childprocess/windows/handle"
36
8
  require "childprocess/windows/io"
37
- require "childprocess/windows/process_builder"
38
9
  require "childprocess/windows/process"
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
- if posix_spawn?
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
- if RUBY_PLATFORM == "java"
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
- platform == :jruby
54
+ RUBY_ENGINE == 'jruby'
66
55
  end
67
56
 
68
57
  def windows?
69
58
  os == :windows
70
59
  end
71
60
 
72
- def posix_spawn?
73
- enabled = @posix_spawn || %w[1 true].include?(ENV['CHILDPROCESS_POSIX_SPAWN'])
74
- return false unless enabled
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
- true
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
- require 'jruby' if ChildProcess.jruby?
207
-
208
- require 'childprocess/unix' if ChildProcess.unix?
209
- require 'childprocess/windows' if ChildProcess.windows?
210
- require 'childprocess/jruby' if ChildProcess.jruby?
169
+ if ChildProcess.windows?
170
+ require 'childprocess/windows'
171
+ else
172
+ require 'childprocess/unix'
173
+ end