childprocess 0.9.0 → 3.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 (50) hide show
  1. checksums.yaml +5 -5
  2. data/.document +6 -6
  3. data/.gitignore +28 -28
  4. data/.rspec +1 -1
  5. data/.travis.yml +40 -44
  6. data/CHANGELOG.md +73 -49
  7. data/Gemfile +21 -15
  8. data/LICENSE +20 -20
  9. data/README.md +218 -196
  10. data/Rakefile +61 -61
  11. data/appveyor.yml +42 -60
  12. data/childprocess.gemspec +26 -30
  13. data/lib/childprocess.rb +210 -205
  14. data/lib/childprocess/abstract_io.rb +36 -36
  15. data/lib/childprocess/abstract_process.rb +192 -192
  16. data/lib/childprocess/errors.rb +37 -26
  17. data/lib/childprocess/jruby.rb +56 -56
  18. data/lib/childprocess/jruby/io.rb +16 -16
  19. data/lib/childprocess/jruby/process.rb +184 -159
  20. data/lib/childprocess/jruby/pump.rb +53 -53
  21. data/lib/childprocess/tools/generator.rb +145 -145
  22. data/lib/childprocess/unix.rb +9 -9
  23. data/lib/childprocess/unix/fork_exec_process.rb +78 -70
  24. data/lib/childprocess/unix/io.rb +21 -21
  25. data/lib/childprocess/unix/lib.rb +186 -186
  26. data/lib/childprocess/unix/platform/i386-linux.rb +12 -12
  27. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -11
  28. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -12
  29. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -11
  30. data/lib/childprocess/unix/posix_spawn_process.rb +134 -134
  31. data/lib/childprocess/unix/process.rb +90 -89
  32. data/lib/childprocess/version.rb +3 -3
  33. data/lib/childprocess/windows.rb +38 -33
  34. data/lib/childprocess/windows/handle.rb +91 -91
  35. data/lib/childprocess/windows/io.rb +25 -25
  36. data/lib/childprocess/windows/lib.rb +416 -416
  37. data/lib/childprocess/windows/process.rb +130 -130
  38. data/lib/childprocess/windows/process_builder.rb +178 -175
  39. data/lib/childprocess/windows/structs.rb +148 -148
  40. data/spec/abstract_io_spec.rb +12 -12
  41. data/spec/childprocess_spec.rb +447 -422
  42. data/spec/get_env.ps1 +13 -0
  43. data/spec/io_spec.rb +228 -228
  44. data/spec/jruby_spec.rb +24 -24
  45. data/spec/pid_behavior.rb +12 -12
  46. data/spec/platform_detection_spec.rb +86 -86
  47. data/spec/spec_helper.rb +270 -261
  48. data/spec/unix_spec.rb +57 -57
  49. data/spec/windows_spec.rb +23 -23
  50. metadata +8 -39
data/Rakefile CHANGED
@@ -1,61 +1,61 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'tmpdir'
4
-
5
- require 'bundler'
6
- Bundler::GemHelper.install_tasks
7
-
8
- include Rake::DSL if defined?(::Rake::DSL)
9
-
10
- require 'rspec/core/rake_task'
11
- RSpec::Core::RakeTask.new(:spec) do |spec|
12
- spec.ruby_opts = "-I lib:spec -w"
13
- spec.pattern = 'spec/**/*_spec.rb'
14
- end
15
-
16
- desc 'Run specs for rcov'
17
- RSpec::Core::RakeTask.new(:rcov) do |spec|
18
- spec.ruby_opts = "-I lib:spec"
19
- spec.pattern = 'spec/**/*_spec.rb'
20
- spec.rcov = true
21
- spec.rcov_opts = %w[--exclude spec,ruby-debug,/Library/Ruby,.gem --include lib/childprocess]
22
- end
23
-
24
- task :default => :spec
25
-
26
- begin
27
- require 'yard'
28
- YARD::Rake::YardocTask.new
29
- rescue LoadError
30
- task :yardoc do
31
- abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
32
- end
33
- end
34
-
35
- task :clean do
36
- rm_rf "pkg"
37
- rm_rf "childprocess.jar"
38
- end
39
-
40
- desc 'Create jar to bundle in selenium-webdriver'
41
- task :jar => [:clean, :build] do
42
- tmpdir = Dir.mktmpdir("childprocess-jar")
43
- gem_to_package = Dir['pkg/*.gem'].first
44
- gem_name = File.basename(gem_to_package, ".gem")
45
- p :gem_to_package => gem_to_package, :gem_name => gem_name
46
-
47
- sh "gem install -i #{tmpdir} #{gem_to_package} --ignore-dependencies --no-rdoc --no-ri"
48
- sh "jar cf childprocess.jar -C #{tmpdir}/gems/#{gem_name}/lib ."
49
- sh "jar tf childprocess.jar"
50
- end
51
-
52
- task :env do
53
- $:.unshift File.expand_path("../lib", __FILE__)
54
- require 'childprocess'
55
- end
56
-
57
- desc 'Calculate size of posix_spawn structs for the current platform'
58
- task :generate => :env do
59
- require 'childprocess/tools/generator'
60
- ChildProcess::Tools::Generator.generate
61
- end
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'tmpdir'
4
+
5
+ require 'bundler'
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ include Rake::DSL if defined?(::Rake::DSL)
9
+
10
+ require 'rspec/core/rake_task'
11
+ RSpec::Core::RakeTask.new(:spec) do |spec|
12
+ spec.ruby_opts = "-I lib:spec -w"
13
+ spec.pattern = 'spec/**/*_spec.rb'
14
+ end
15
+
16
+ desc 'Run specs for rcov'
17
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
18
+ spec.ruby_opts = "-I lib:spec"
19
+ spec.pattern = 'spec/**/*_spec.rb'
20
+ spec.rcov = true
21
+ spec.rcov_opts = %w[--exclude spec,ruby-debug,/Library/Ruby,.gem --include lib/childprocess]
22
+ end
23
+
24
+ task :default => :spec
25
+
26
+ begin
27
+ require 'yard'
28
+ YARD::Rake::YardocTask.new
29
+ rescue LoadError
30
+ task :yardoc do
31
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
32
+ end
33
+ end
34
+
35
+ task :clean do
36
+ rm_rf "pkg"
37
+ rm_rf "childprocess.jar"
38
+ end
39
+
40
+ desc 'Create jar to bundle in selenium-webdriver'
41
+ task :jar => [:clean, :build] do
42
+ tmpdir = Dir.mktmpdir("childprocess-jar")
43
+ gem_to_package = Dir['pkg/*.gem'].first
44
+ gem_name = File.basename(gem_to_package, ".gem")
45
+ p :gem_to_package => gem_to_package, :gem_name => gem_name
46
+
47
+ sh "gem install -i #{tmpdir} #{gem_to_package} --ignore-dependencies --no-rdoc --no-ri"
48
+ sh "jar cf childprocess.jar -C #{tmpdir}/gems/#{gem_name}/lib ."
49
+ sh "jar tf childprocess.jar"
50
+ end
51
+
52
+ task :env do
53
+ $:.unshift File.expand_path("../lib", __FILE__)
54
+ require 'childprocess'
55
+ end
56
+
57
+ desc 'Calculate size of posix_spawn structs for the current platform'
58
+ task :generate => :env do
59
+ require 'childprocess/tools/generator'
60
+ ChildProcess::Tools::Generator.generate
61
+ end
@@ -1,60 +1,42 @@
1
- version: '1.0.{build}'
2
-
3
- environment:
4
- matrix:
5
- - CHILDPROCESS_POSIX_SPAWN: true
6
- CHILDPROCESS_UNSET: should-be-unset
7
- RUBY_VERSION: 193-x64
8
- - CHILDPROCESS_POSIX_SPAWN: false
9
- CHILDPROCESS_UNSET: should-be-unset
10
- RUBY_VERSION: 193-x64
11
- - CHILDPROCESS_POSIX_SPAWN: true
12
- CHILDPROCESS_UNSET: should-be-unset
13
- RUBY_VERSION: 200-x64
14
- - CHILDPROCESS_POSIX_SPAWN: false
15
- CHILDPROCESS_UNSET: should-be-unset
16
- RUBY_VERSION: 200-x64
17
- - CHILDPROCESS_POSIX_SPAWN: true
18
- CHILDPROCESS_UNSET: should-be-unset
19
- RUBY_VERSION: 21-x64
20
- - CHILDPROCESS_POSIX_SPAWN: false
21
- CHILDPROCESS_UNSET: should-be-unset
22
- RUBY_VERSION: 21-x64
23
- - CHILDPROCESS_POSIX_SPAWN: true
24
- CHILDPROCESS_UNSET: should-be-unset
25
- RUBY_VERSION: 22-x64
26
- - CHILDPROCESS_POSIX_SPAWN: false
27
- CHILDPROCESS_UNSET: should-be-unset
28
- RUBY_VERSION: 22-x64
29
- - CHILDPROCESS_POSIX_SPAWN: true
30
- CHILDPROCESS_UNSET: should-be-unset
31
- RUBY_VERSION: 23-x64
32
- - CHILDPROCESS_POSIX_SPAWN: false
33
- CHILDPROCESS_UNSET: should-be-unset
34
- RUBY_VERSION: 23-x64
35
- - CHILDPROCESS_POSIX_SPAWN: true
36
- CHILDPROCESS_UNSET: should-be-unset
37
- RUBY_VERSION: 24-x64
38
- - CHILDPROCESS_POSIX_SPAWN: false
39
- CHILDPROCESS_UNSET: should-be-unset
40
- RUBY_VERSION: 24-x64
41
- - CHILDPROCESS_POSIX_SPAWN: true
42
- CHILDPROCESS_UNSET: should-be-unset
43
- RUBY_VERSION: 25-x64
44
- - CHILDPROCESS_POSIX_SPAWN: false
45
- CHILDPROCESS_UNSET: should-be-unset
46
- RUBY_VERSION: 25-x64
47
-
48
- install:
49
- - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
50
- - bundle install
51
-
52
- build: off
53
-
54
- before_test:
55
- - ruby -v
56
- - gem -v
57
- - bundle -v
58
-
59
- test_script:
60
- - bundle exec rake
1
+ version: '1.0.{build}'
2
+
3
+ environment:
4
+ matrix:
5
+ - CHILDPROCESS_POSIX_SPAWN: true
6
+ CHILDPROCESS_UNSET: should-be-unset
7
+ RUBY_VERSION: 23-x64
8
+ - CHILDPROCESS_POSIX_SPAWN: false
9
+ CHILDPROCESS_UNSET: should-be-unset
10
+ RUBY_VERSION: 23-x64
11
+ - CHILDPROCESS_POSIX_SPAWN: true
12
+ CHILDPROCESS_UNSET: should-be-unset
13
+ RUBY_VERSION: 24-x64
14
+ - CHILDPROCESS_POSIX_SPAWN: false
15
+ CHILDPROCESS_UNSET: should-be-unset
16
+ RUBY_VERSION: 24-x64
17
+ - CHILDPROCESS_POSIX_SPAWN: true
18
+ CHILDPROCESS_UNSET: should-be-unset
19
+ RUBY_VERSION: 25-x64
20
+ - CHILDPROCESS_POSIX_SPAWN: false
21
+ CHILDPROCESS_UNSET: should-be-unset
22
+ RUBY_VERSION: 25-x64
23
+ - CHILDPROCESS_POSIX_SPAWN: true
24
+ CHILDPROCESS_UNSET: should-be-unset
25
+ RUBY_VERSION: 26-x64
26
+ - CHILDPROCESS_POSIX_SPAWN: false
27
+ CHILDPROCESS_UNSET: should-be-unset
28
+ RUBY_VERSION: 26-x64
29
+
30
+ install:
31
+ - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
32
+ - bundle install
33
+
34
+ build: off
35
+
36
+ before_test:
37
+ - ruby -v
38
+ - gem -v
39
+ - bundle -v
40
+
41
+ test_script:
42
+ - bundle exec rake
@@ -1,30 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "childprocess/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "childprocess"
7
- s.version = ChildProcess::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Jari Bakken", "Eric Kessler"]
10
- s.email = ["morrow748@gmail.com"]
11
- s.homepage = "http://github.com/enkessler/childprocess"
12
- s.summary = %q{A simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.}
13
- s.description = %q{This gem aims at being a simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.}
14
-
15
- s.rubyforge_project = "childprocess"
16
- s.license = 'MIT'
17
-
18
- s.files = `git ls-files`.split("\n")
19
- s.test_files = `git ls-files -- spec/*`.split("\n")
20
- s.require_paths = ["lib"]
21
-
22
- s.add_runtime_dependency "ffi", "~> 1.0", ">= 1.0.11"
23
-
24
- s.add_development_dependency "rspec", "~> 3.0"
25
- s.add_development_dependency "yard", "~> 0.0"
26
- s.add_development_dependency 'rake', '< 12.0'
27
- s.add_development_dependency 'coveralls', '< 1.0'
28
- end
29
-
30
-
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "childprocess/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "childprocess"
7
+ s.version = ChildProcess::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jari Bakken", "Eric Kessler", "Shane da Silva"]
10
+ s.email = ["morrow748@gmail.com", "shane@dasilva.io"]
11
+ s.homepage = "http://github.com/enkessler/childprocess"
12
+ s.summary = %q{A simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.}
13
+ s.description = %q{This gem aims at being a simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.}
14
+
15
+ s.license = 'MIT'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- spec/*`.split("\n")
19
+ s.require_paths = ["lib"]
20
+
21
+ s.required_ruby_version = '>= 2.3.0'
22
+
23
+ s.add_development_dependency "rspec", "~> 3.0"
24
+ s.add_development_dependency "yard", "~> 0.0"
25
+ s.add_development_dependency 'coveralls', '< 1.0'
26
+ end
@@ -1,205 +1,210 @@
1
- require 'childprocess/version'
2
- require 'childprocess/errors'
3
- require 'childprocess/abstract_process'
4
- require 'childprocess/abstract_io'
5
- require "fcntl"
6
- require 'logger'
7
-
8
- module ChildProcess
9
-
10
- @posix_spawn = false
11
-
12
- class << self
13
- attr_writer :logger
14
-
15
- def new(*args)
16
- case os
17
- 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
25
- when :windows
26
- Windows::Process.new(args)
27
- else
28
- raise Error, "unsupported platform #{platform_name.inspect}"
29
- end
30
- end
31
- alias_method :build, :new
32
-
33
- def logger
34
- return @logger if defined?(@logger) and @logger
35
-
36
- @logger = Logger.new($stderr)
37
- @logger.level = $DEBUG ? Logger::DEBUG : Logger::INFO
38
-
39
- @logger
40
- end
41
-
42
- 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
50
- end
51
-
52
- def platform_name
53
- @platform_name ||= "#{arch}-#{os}"
54
- end
55
-
56
- def unix?
57
- !windows?
58
- end
59
-
60
- def linux?
61
- os == :linux
62
- end
63
-
64
- def jruby?
65
- platform == :jruby
66
- end
67
-
68
- def windows?
69
- os == :windows
70
- end
71
-
72
- def posix_spawn?
73
- enabled = @posix_spawn || %w[1 true].include?(ENV['CHILDPROCESS_POSIX_SPAWN'])
74
- return false unless enabled
75
-
76
- require 'ffi'
77
- begin
78
- require "childprocess/unix/platform/#{ChildProcess.platform_name}"
79
- rescue LoadError
80
- raise ChildProcess::MissingPlatformError
81
- end
82
-
83
- require "childprocess/unix/lib"
84
- require 'childprocess/unix/posix_spawn_process'
85
-
86
- true
87
- rescue ChildProcess::MissingPlatformError => ex
88
- warn_once ex.message
89
- false
90
- end
91
-
92
- #
93
- # Set this to true to enable experimental use of posix_spawn.
94
- #
95
-
96
- def posix_spawn=(bool)
97
- @posix_spawn = bool
98
- end
99
-
100
- def os
101
- @os ||= (
102
- require "rbconfig"
103
- host_os = RbConfig::CONFIG['host_os'].downcase
104
-
105
- case host_os
106
- when /linux/
107
- :linux
108
- when /darwin|mac os/
109
- :macosx
110
- when /mswin|msys|mingw32/
111
- :windows
112
- when /cygwin/
113
- :cygwin
114
- when /solaris|sunos/
115
- :solaris
116
- when /bsd|dragonfly/
117
- :bsd
118
- when /aix/
119
- :aix
120
- else
121
- raise Error, "unknown os: #{host_os.inspect}"
122
- end
123
- )
124
- end
125
-
126
- def arch
127
- @arch ||= (
128
- host_cpu = RbConfig::CONFIG['host_cpu'].downcase
129
- case host_cpu
130
- when /i[3456]86/
131
- if workaround_older_macosx_misreported_cpu?
132
- # Workaround case: older 64-bit Darwin Rubies misreported as i686
133
- "x86_64"
134
- else
135
- "i386"
136
- end
137
- when /amd64|x86_64/
138
- "x86_64"
139
- when /ppc|powerpc/
140
- "powerpc"
141
- else
142
- host_cpu
143
- end
144
- )
145
- end
146
-
147
- #
148
- # By default, a child process will inherit open file descriptors from the
149
- # parent process. This helper provides a cross-platform way of making sure
150
- # that doesn't happen for the given file/io.
151
- #
152
-
153
- def close_on_exec(file)
154
- if file.respond_to?(:close_on_exec=)
155
- file.close_on_exec = true
156
- elsif file.respond_to?(:fcntl) && defined?(Fcntl::FD_CLOEXEC)
157
- file.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
158
-
159
- if jruby? && posix_spawn?
160
- # on JRuby, the fcntl call above apparently isn't enough when
161
- # we're launching the process through posix_spawn.
162
- fileno = JRuby.posix_fileno_for(file)
163
- Unix::Lib.fcntl fileno, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
164
- end
165
- elsif windows?
166
- Windows::Lib.dont_inherit file
167
- else
168
- raise Error, "not sure how to set close-on-exec for #{file.inspect} on #{platform_name.inspect}"
169
- end
170
- end
171
-
172
- private
173
-
174
- def warn_once(msg)
175
- @warnings ||= {}
176
-
177
- unless @warnings[msg]
178
- @warnings[msg] = true
179
- logger.warn msg
180
- end
181
- end
182
-
183
- # Workaround: detect the situation that an older Darwin Ruby is actually
184
- # 64-bit, but is misreporting cpu as i686, which would imply 32-bit.
185
- #
186
- # @return [Boolean] `true` if:
187
- # (a) on Mac OS X
188
- # (b) actually running in 64-bit mode
189
- def workaround_older_macosx_misreported_cpu?
190
- os == :macosx && is_64_bit?
191
- end
192
-
193
- # @return [Boolean] `true` if this Ruby represents `1` in 64 bits (8 bytes).
194
- def is_64_bit?
195
- 1.size == 8
196
- end
197
-
198
- end # class << self
199
- end # ChildProcess
200
-
201
- require 'jruby' if ChildProcess.jruby?
202
-
203
- require 'childprocess/unix' if ChildProcess.unix?
204
- require 'childprocess/windows' if ChildProcess.windows?
205
- require 'childprocess/jruby' if ChildProcess.jruby?
1
+ require 'childprocess/version'
2
+ require 'childprocess/errors'
3
+ require 'childprocess/abstract_process'
4
+ require 'childprocess/abstract_io'
5
+ require "fcntl"
6
+ require 'logger'
7
+
8
+ module ChildProcess
9
+
10
+ @posix_spawn = false
11
+
12
+ class << self
13
+ attr_writer :logger
14
+
15
+ def new(*args)
16
+ case os
17
+ 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
25
+ when :windows
26
+ Windows::Process.new(args)
27
+ else
28
+ raise Error, "unsupported platform #{platform_name.inspect}"
29
+ end
30
+ end
31
+ alias_method :build, :new
32
+
33
+ def logger
34
+ return @logger if defined?(@logger) and @logger
35
+
36
+ @logger = Logger.new($stderr)
37
+ @logger.level = $DEBUG ? Logger::DEBUG : Logger::INFO
38
+
39
+ @logger
40
+ end
41
+
42
+ 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
50
+ end
51
+
52
+ def platform_name
53
+ @platform_name ||= "#{arch}-#{os}"
54
+ end
55
+
56
+ def unix?
57
+ !windows?
58
+ end
59
+
60
+ def linux?
61
+ os == :linux
62
+ end
63
+
64
+ def jruby?
65
+ platform == :jruby
66
+ end
67
+
68
+ def windows?
69
+ os == :windows
70
+ end
71
+
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'
90
+
91
+ true
92
+ rescue ChildProcess::MissingPlatformError => ex
93
+ warn_once ex.message
94
+ false
95
+ end
96
+
97
+ #
98
+ # Set this to true to enable experimental use of posix_spawn.
99
+ #
100
+
101
+ def posix_spawn=(bool)
102
+ @posix_spawn = bool
103
+ end
104
+
105
+ def os
106
+ @os ||= (
107
+ require "rbconfig"
108
+ host_os = RbConfig::CONFIG['host_os'].downcase
109
+
110
+ case host_os
111
+ when /linux/
112
+ :linux
113
+ when /darwin|mac os/
114
+ :macosx
115
+ when /mswin|msys|mingw32/
116
+ :windows
117
+ when /cygwin/
118
+ :cygwin
119
+ when /solaris|sunos/
120
+ :solaris
121
+ when /bsd|dragonfly/
122
+ :bsd
123
+ when /aix/
124
+ :aix
125
+ else
126
+ raise Error, "unknown os: #{host_os.inspect}"
127
+ end
128
+ )
129
+ end
130
+
131
+ def arch
132
+ @arch ||= (
133
+ host_cpu = RbConfig::CONFIG['host_cpu'].downcase
134
+ case host_cpu
135
+ when /i[3456]86/
136
+ if workaround_older_macosx_misreported_cpu?
137
+ # Workaround case: older 64-bit Darwin Rubies misreported as i686
138
+ "x86_64"
139
+ else
140
+ "i386"
141
+ end
142
+ when /amd64|x86_64/
143
+ "x86_64"
144
+ when /ppc|powerpc/
145
+ "powerpc"
146
+ else
147
+ host_cpu
148
+ end
149
+ )
150
+ end
151
+
152
+ #
153
+ # By default, a child process will inherit open file descriptors from the
154
+ # parent process. This helper provides a cross-platform way of making sure
155
+ # that doesn't happen for the given file/io.
156
+ #
157
+
158
+ def close_on_exec(file)
159
+ if file.respond_to?(:close_on_exec=)
160
+ 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
+ else
173
+ raise Error, "not sure how to set close-on-exec for #{file.inspect} on #{platform_name.inspect}"
174
+ end
175
+ end
176
+
177
+ private
178
+
179
+ def warn_once(msg)
180
+ @warnings ||= {}
181
+
182
+ unless @warnings[msg]
183
+ @warnings[msg] = true
184
+ logger.warn msg
185
+ end
186
+ end
187
+
188
+ # Workaround: detect the situation that an older Darwin Ruby is actually
189
+ # 64-bit, but is misreporting cpu as i686, which would imply 32-bit.
190
+ #
191
+ # @return [Boolean] `true` if:
192
+ # (a) on Mac OS X
193
+ # (b) actually running in 64-bit mode
194
+ def workaround_older_macosx_misreported_cpu?
195
+ os == :macosx && is_64_bit?
196
+ end
197
+
198
+ # @return [Boolean] `true` if this Ruby represents `1` in 64 bits (8 bytes).
199
+ def is_64_bit?
200
+ 1.size == 8
201
+ end
202
+
203
+ end # class << self
204
+ end # ChildProcess
205
+
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?