summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2014-08-23 21:10:55 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2014-08-23 21:10:55 -0700
commit8303b4ee475f2e24ee2cb4df7b2ec737d8d366c2 (patch)
tree4319521882c18f1efb789bc77b10c6ebf3761367 /lib
parent023b549a40577db1f4b8cc431c2451202b1d8c74 (diff)
downloadffi-yajl-8303b4ee475f2e24ee2cb4df7b2ec737d8d366c2.tar.gz
fix rbx using dlopen via FFI
this means rbx uses FFI in ways that I cannot work around.
Diffstat (limited to 'lib')
-rw-r--r--lib/ffi_yajl/ext.rb55
1 files changed, 44 insertions, 11 deletions
diff --git a/lib/ffi_yajl/ext.rb b/lib/ffi_yajl/ext.rb
index 504cbe1..1441cba 100644
--- a/lib/ffi_yajl/ext.rb
+++ b/lib/ffi_yajl/ext.rb
@@ -4,28 +4,62 @@ require 'ffi_yajl/encoder'
require 'ffi_yajl/parser'
require 'ffi'
require 'libyajl2'
-begin
- require 'fiddle'
-rescue LoadError
-end
module FFI_Yajl
# FIXME: DRY with ffi_yajl/ffi.rb
+ # FIXME: extract map_library_name from FFI and stop requiring it at the top level
+ # so that the C-library can be installed without FFI
libname = ::FFI.map_library_name("yajl")
libpath = File.expand_path(File.join(Libyajl2.opt_path, libname))
libpath.gsub!(/dylib/, 'bundle')
libpath = ::FFI.map_library_name("yajl") unless File.exist?(libpath)
- if defined?(Fiddle) && Fiddle.respond_to?(:dlopen)
- ::Fiddle.dlopen(libpath)
- else
- # deliberately convoluted delayed require here to avoid deprecation
- # warning from requiring dl
+
+ #
+ # FFS, what exactly was so wrong with DL.dlopen that ruby had to get rid of it???
+ #
+
+ def self.try_fiddle_dlopen(libpath)
+ require 'fiddle'
+ if defined?(Fiddle) && Fiddle.respond_to?(:dlopen)
+ ::Fiddle.dlopen(libpath)
+ true
+ else
+ false
+ end
+ rescue LoadError
+ return false
+ end
+
+ def self.try_dl_dlopen(libpath)
require 'dl'
if defined?(DL) && DL.respond_to?(:dlopen)
::DL.dlopen(libpath)
+ true
else
- raise "cannot find dlopen in either DL or Fiddle, cannot proceed"
+ false
end
+ rescue LoadError
+ return false
+ end
+
+ def self.try_ffi_dlopen(libpath)
+ require 'ffi'
+ require 'rbconfig'
+ extend ::FFI::Library
+ ffi_lib 'dl'
+ attach_function 'dlopen', :dlopen, [:string, :int], :void
+ if Config::CONFIG['host_os'] =~ /linux/i
+ dlopen libpath, 0x102 # linux: RTLD_GLOBAL | RTLD_NOW
+ else
+ dlopen libpath, 0
+ end
+ true
+ rescue LoadError
+ return false
+ end
+
+ unless try_fiddle_dlopen(libpath) || try_dl_dlopen(libpath) || try_ffi_dlopen(libpath)
+ raise "cannot find dlopen vi Fiddle, DL or FFI, what am I supposed to do?"
end
class Parser
@@ -38,4 +72,3 @@ module FFI_Yajl
include FFI_Yajl::Ext::Encoder
end
end
-