From 3e84e33013ba48f35ef789750f8372b817583745 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 31 Jan 2025 21:38:03 +0900 Subject: [PATCH] Define Fiddle.last_error family statically `RUBY_ENGINE` and `Fiddle::WINDOWS` should not change in a process, no need to be checked inside the methods. Also, `win32_last_error` and `win32_last_socket_error` are equal to `last_error` on JRuby. --- lib/fiddle.rb | 145 ++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 76 deletions(-) diff --git a/lib/fiddle.rb b/lib/fiddle.rb index 4723d70..3976a78 100644 --- a/lib/fiddle.rb +++ b/lib/fiddle.rb @@ -10,98 +10,72 @@ require 'fiddle/version' module Fiddle - if WINDOWS - # Returns the last win32 +Error+ of the current executing +Thread+ or nil - # if none - def self.win32_last_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] - end + case RUBY_ENGINE + when 'jruby' + def self.last_error + FFI.errno.nonzero? end - # Sets the last win32 +Error+ of the current executing +Thread+ to +error+ - def self.win32_last_error= error - if RUBY_ENGINE == 'jruby' - FFI.errno = error || 0 - else - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error - end - end - - # Returns the last win32 socket +Error+ of the current executing - # +Thread+ or nil if none - def self.win32_last_socket_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] - end + def self.last_error= error + FFI.errno = error || 0 end - # Sets the last win32 socket +Error+ of the current executing - # +Thread+ to +error+ - def self.win32_last_socket_error= error - if RUBY_ENGINE == 'jruby' - FFI.errno = error || 0 - else - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error + if WINDOWS + class << self + alias win32_last_error last_error + alias win32_last_error= last_error= + alias win32_last_socket_error last_error + alias win32_last_socket_error= last_error= end end - end - - # Returns the last +Error+ of the current executing +Thread+ or nil if none - def self.last_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else + else + # Returns the last +Error+ of the current executing +Thread+ or nil if none + def self.last_error Thread.current[:__FIDDLE_LAST_ERROR__] end - end - # Sets the last +Error+ of the current executing +Thread+ to +error+ - def self.last_error= error - if RUBY_ENGINE == 'jruby' - FFI.errno = error || 0 - else + # Sets the last +Error+ of the current executing +Thread+ to +error+ + def self.last_error= error Thread.current[:__DL2_LAST_ERROR__] = error Thread.current[:__FIDDLE_LAST_ERROR__] = error end + + if WINDOWS + # Returns the last win32 +Error+ of the current executing +Thread+ or nil + # if none + def self.win32_last_error + Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] + end + + # Sets the last win32 +Error+ of the current executing +Thread+ to +error+ + def self.win32_last_error= error + Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error + end + + # Returns the last win32 socket +Error+ of the current executing + # +Thread+ or nil if none + def self.win32_last_socket_error + Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] + end + + # Sets the last win32 socket +Error+ of the current executing + # +Thread+ to +error+ + def self.win32_last_socket_error= error + Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error + end + end end - # call-seq: dlopen(library) => Fiddle::Handle - # - # Creates a new handler that opens +library+, and returns an instance of - # Fiddle::Handle. - # - # If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which - # is the equivalent to RTLD_DEFAULT. See man 3 dlopen for more. - # - # lib = Fiddle.dlopen(nil) - # - # The default is dependent on OS, and provide a handle for all libraries - # already loaded. For example, in most cases you can use this to access - # +libc+ functions, or ruby functions like +rb_str_new+. - # - # See Fiddle::Handle.new for more. - def dlopen library - begin + case RUBY_PLATFORM + when /linux/ + def dlopen library Fiddle::Handle.new(library) rescue DLError => error - case RUBY_PLATFORM - when /linux/ - case error.message - when /\A(\/.+?): (?:invalid ELF header|file too short)/ - # This may be a linker script: - # https://sourceware.org/binutils/docs/ld.html#Scripts - path = $1 - else - raise - end + case error.message + when /\A(\/.+?): (?:invalid ELF header|file too short)/ + # This may be a linker script: + # https://sourceware.org/binutils/docs/ld.html#Scripts + path = $1 else raise end @@ -123,6 +97,25 @@ def dlopen library # Not found raise end + else + # call-seq: dlopen(library) => Fiddle::Handle + # + # Creates a new handler that opens +library+, and returns an instance of + # Fiddle::Handle. + # + # If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which + # is the equivalent to RTLD_DEFAULT. See man 3 dlopen for more. + # + # lib = Fiddle.dlopen(nil) + # + # The default is dependent on OS, and provide a handle for all libraries + # already loaded. For example, in most cases you can use this to access + # +libc+ functions, or ruby functions like +rb_str_new+. + # + # See Fiddle::Handle.new for more. + def dlopen library + Fiddle::Handle.new(library) + end end module_function :dlopen