Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only require FFI on Windows #132

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ if RUBY_VERSION =~ /^1\./
gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version

if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
# The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
gem 'ffi', '< 1.9.15'
else
# Load 'ffi' for testing posix_spawn
gem 'ffi' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true'
end
else
# Load 'ffi' for testing posix_spawn, or on windows.
gem 'ffi' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true' || RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
end
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ ChildProcess.posix_spawn = true
process = ChildProcess.build(*args)
```

To be able to use this, please make sure that you have the `ffi` gem installed.

### Ensure entire process tree dies

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:
Expand Down
4 changes: 2 additions & 2 deletions childprocess.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ Gem::Specification.new do |s|
s.test_files = `git ls-files -- spec/*`.split("\n")
s.require_paths = ["lib"]

s.add_runtime_dependency "ffi", "~> 1.0", ">= 1.0.11"

s.add_development_dependency "rspec", "~> 3.0"
s.add_development_dependency "yard", "~> 0.0"
s.add_development_dependency 'rake', '< 12.0'
s.add_development_dependency 'coveralls', '< 1.0'

s.extensions = 'ext/mkrf_conf.rb'
end


24 changes: 24 additions & 0 deletions ext/mkrf_conf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Based on the example from https://en.wikibooks.org/wiki/Ruby_Programming/RubyGems#How_to_install_different_versions_of_gems_depending_on_which_version_of_ruby_the_installee_is_using
require 'rubygems'
require 'rubygems/command.rb'
require 'rubygems/dependency_installer.rb'

begin
Gem::Command.build_args = ARGV
rescue NoMethodError # rubocop:disable Lint/HandleExceptions
end

inst = Gem::DependencyInstaller.new

begin
if RbConfig::CONFIG['host_os'] =~ %r{mswin|msys|mingw32}i
inst.install 'ffi', "~> 1.0", ">= 1.0.11"
end
rescue # rubocop:disable Lint/RescueWithoutErrorClass
exit(1)
end

# create dummy rakefile to indicate success
File.open(File.join(File.dirname(__FILE__), 'Rakefile'), 'w') do |f|
f.write("task :default\n")
end
7 changes: 6 additions & 1 deletion lib/childprocess.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ def posix_spawn?
enabled = @posix_spawn || %w[1 true].include?(ENV['CHILDPROCESS_POSIX_SPAWN'])
return false unless enabled

require 'ffi'
begin
require 'ffi'
rescue LoadError
raise ChildProcess::MissingFFIError
end

begin
require "childprocess/unix/platform/#{ChildProcess.platform_name}"
rescue LoadError
Expand Down
11 changes: 11 additions & 0 deletions lib/childprocess/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ class InvalidEnvironmentVariable < Error
class LaunchError < Error
end

class MissingFFIError < Error
def initialize
message = "FFI is a required pre-requisite for posix_spawn, falling back to default implementation. " +
"Please add it to your deployment to unlock this functionality. " +
"If you believe this is an error, please file a bug at http://github.com/enkessler/childprocess/issues"

super(message)
end

end

class MissingPlatformError < Error
def initialize
message = "posix_spawn is not yet supported on #{ChildProcess.platform_name} (#{RUBY_PLATFORM}), falling back to default implementation. " +
Expand Down