diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2014-08-23 21:10:55 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2014-08-23 21:10:55 -0700 |
commit | 8303b4ee475f2e24ee2cb4df7b2ec737d8d366c2 (patch) | |
tree | 4319521882c18f1efb789bc77b10c6ebf3761367 /lib | |
parent | 023b549a40577db1f4b8cc431c2451202b1d8c74 (diff) | |
download | ffi-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.rb | 55 |
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 - |