Skip to content

Commit b5b5097

Browse files
nobuhsbt
authored andcommitted
[ruby/fiddle] Define Fiddle.last_error family and Fiddle.dlopen
statically (ruby/fiddle#172) `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. ruby/fiddle@50ac00ed53
1 parent 56c814a commit b5b5097

File tree

1 file changed

+69
-76
lines changed

1 file changed

+69
-76
lines changed

ext/fiddle/lib/fiddle.rb

Lines changed: 69 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,98 +10,72 @@
1010
require 'fiddle/version'
1111

1212
module Fiddle
13-
if WINDOWS
14-
# Returns the last win32 +Error+ of the current executing +Thread+ or nil
15-
# if none
16-
def self.win32_last_error
17-
if RUBY_ENGINE == 'jruby'
18-
errno = FFI.errno
19-
errno == 0 ? nil : errno
20-
else
21-
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
22-
end
13+
case RUBY_ENGINE
14+
when 'jruby'
15+
def self.last_error
16+
FFI.errno.nonzero?
2317
end
2418

25-
# Sets the last win32 +Error+ of the current executing +Thread+ to +error+
26-
def self.win32_last_error= error
27-
if RUBY_ENGINE == 'jruby'
28-
FFI.errno = error || 0
29-
else
30-
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
31-
end
32-
end
33-
34-
# Returns the last win32 socket +Error+ of the current executing
35-
# +Thread+ or nil if none
36-
def self.win32_last_socket_error
37-
if RUBY_ENGINE == 'jruby'
38-
errno = FFI.errno
39-
errno == 0 ? nil : errno
40-
else
41-
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
42-
end
19+
def self.last_error= error
20+
FFI.errno = error || 0
4321
end
4422

45-
# Sets the last win32 socket +Error+ of the current executing
46-
# +Thread+ to +error+
47-
def self.win32_last_socket_error= error
48-
if RUBY_ENGINE == 'jruby'
49-
FFI.errno = error || 0
50-
else
51-
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
23+
if WINDOWS
24+
class << self
25+
alias win32_last_error last_error
26+
alias win32_last_error= last_error=
27+
alias win32_last_socket_error last_error
28+
alias win32_last_socket_error= last_error=
5229
end
5330
end
54-
end
55-
56-
# Returns the last +Error+ of the current executing +Thread+ or nil if none
57-
def self.last_error
58-
if RUBY_ENGINE == 'jruby'
59-
errno = FFI.errno
60-
errno == 0 ? nil : errno
61-
else
31+
else
32+
# Returns the last +Error+ of the current executing +Thread+ or nil if none
33+
def self.last_error
6234
Thread.current[:__FIDDLE_LAST_ERROR__]
6335
end
64-
end
6536

66-
# Sets the last +Error+ of the current executing +Thread+ to +error+
67-
def self.last_error= error
68-
if RUBY_ENGINE == 'jruby'
69-
FFI.errno = error || 0
70-
else
37+
# Sets the last +Error+ of the current executing +Thread+ to +error+
38+
def self.last_error= error
7139
Thread.current[:__DL2_LAST_ERROR__] = error
7240
Thread.current[:__FIDDLE_LAST_ERROR__] = error
7341
end
42+
43+
if WINDOWS
44+
# Returns the last win32 +Error+ of the current executing +Thread+ or nil
45+
# if none
46+
def self.win32_last_error
47+
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
48+
end
49+
50+
# Sets the last win32 +Error+ of the current executing +Thread+ to +error+
51+
def self.win32_last_error= error
52+
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
53+
end
54+
55+
# Returns the last win32 socket +Error+ of the current executing
56+
# +Thread+ or nil if none
57+
def self.win32_last_socket_error
58+
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
59+
end
60+
61+
# Sets the last win32 socket +Error+ of the current executing
62+
# +Thread+ to +error+
63+
def self.win32_last_socket_error= error
64+
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
65+
end
66+
end
7467
end
7568

76-
# call-seq: dlopen(library) => Fiddle::Handle
77-
#
78-
# Creates a new handler that opens +library+, and returns an instance of
79-
# Fiddle::Handle.
80-
#
81-
# If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which
82-
# is the equivalent to RTLD_DEFAULT. See <code>man 3 dlopen</code> for more.
83-
#
84-
# lib = Fiddle.dlopen(nil)
85-
#
86-
# The default is dependent on OS, and provide a handle for all libraries
87-
# already loaded. For example, in most cases you can use this to access
88-
# +libc+ functions, or ruby functions like +rb_str_new+.
89-
#
90-
# See Fiddle::Handle.new for more.
91-
def dlopen library
92-
begin
69+
case RUBY_PLATFORM
70+
when /linux/
71+
def dlopen library
9372
Fiddle::Handle.new(library)
9473
rescue DLError => error
95-
case RUBY_PLATFORM
96-
when /linux/
97-
case error.message
98-
when /\A(\/.+?): (?:invalid ELF header|file too short)/
99-
# This may be a linker script:
100-
# https://sourceware.org/binutils/docs/ld.html#Scripts
101-
path = $1
102-
else
103-
raise
104-
end
74+
case error.message
75+
when /\A(\/.+?): (?:invalid ELF header|file too short)/
76+
# This may be a linker script:
77+
# https://sourceware.org/binutils/docs/ld.html#Scripts
78+
path = $1
10579
else
10680
raise
10781
end
@@ -123,6 +97,25 @@ def dlopen library
12397
# Not found
12498
raise
12599
end
100+
else
101+
# call-seq: dlopen(library) => Fiddle::Handle
102+
#
103+
# Creates a new handler that opens +library+, and returns an instance of
104+
# Fiddle::Handle.
105+
#
106+
# If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which
107+
# is the equivalent to RTLD_DEFAULT. See <code>man 3 dlopen</code> for more.
108+
#
109+
# lib = Fiddle.dlopen(nil)
110+
#
111+
# The default is dependent on OS, and provide a handle for all libraries
112+
# already loaded. For example, in most cases you can use this to access
113+
# +libc+ functions, or ruby functions like +rb_str_new+.
114+
#
115+
# See Fiddle::Handle.new for more.
116+
def dlopen library
117+
Fiddle::Handle.new(library)
118+
end
126119
end
127120
module_function :dlopen
128121

0 commit comments

Comments
 (0)