-
-
Save headius/2e3928e8a96c1a86cd887e37da78b844 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/bigdecimal/lib/bigdecimal/math.rb b/ext/bigdecimal/lib/bigdecimal/math.rb | |
index 0b9d0648bb..5a7cd5e984 100644 | |
--- a/ext/bigdecimal/lib/bigdecimal/math.rb | |
+++ b/ext/bigdecimal/lib/bigdecimal/math.rb | |
@@ -227,6 +227,19 @@ def PI(prec) | |
# | |
def E(prec) | |
raise ArgumentError, "Zero or negative precision for E" if prec <= 0 | |
- BigMath.exp(1, prec) | |
+ n = prec + BigDecimal.double_fig | |
+ one = BigDecimal("1") | |
+ y = one | |
+ d = y | |
+ z = one | |
+ i = 0 | |
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) | |
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig | |
+ i += 1 | |
+ z *= i | |
+ d = one.div(z,m) | |
+ y += d | |
+ end | |
+ y | |
end | |
end | |
diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb | |
index 4512989310..2d49cd3fd7 100644 | |
--- a/ext/fiddle/lib/fiddle.rb | |
+++ b/ext/fiddle/lib/fiddle.rb | |
@@ -1,6 +1,6 @@ | |
# frozen_string_literal: true | |
- | |
-require 'fiddle.so' | |
+require 'fiddle.so' unless RUBY_ENGINE == 'jruby' | |
+require 'fiddle/jruby' if RUBY_ENGINE == 'jruby' | |
require 'fiddle/closure' | |
require 'fiddle/function' | |
require 'fiddle/version' | |
@@ -10,36 +10,66 @@ module Fiddle | |
# 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__] | |
+ if RUBY_ENGINE == 'jruby' | |
+ errno = FFI.errno | |
+ errno == 0 ? nil : errno | |
+ else | |
+ Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] | |
+ end | |
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 | |
+ if RUBY_ENGINE == 'jruby' | |
+ errno = FFI.errno | |
+ errno == 0 ? nil : errno | |
+ 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 | |
- Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] | |
+ if RUBY_ENGINE == 'jruby' | |
+ errno = FFI.errno | |
+ errno == 0 ? nil : errno | |
+ else | |
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] | |
+ end | |
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 | |
+ if RUBY_ENGINE == 'jruby' | |
+ errno = FFI.errno | |
+ errno == 0 ? nil : errno | |
+ else | |
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error | |
+ end | |
end | |
end | |
# Returns the last +Error+ of the current executing +Thread+ or nil if none | |
def self.last_error | |
- Thread.current[:__FIDDLE_LAST_ERROR__] | |
+ if RUBY_ENGINE == 'jruby' | |
+ errno = FFI.errno | |
+ errno == 0 ? nil : errno | |
+ errno | |
+ else | |
+ Thread.current[:__FIDDLE_LAST_ERROR__] | |
+ end | |
end | |
# 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 | |
+ if RUBY_ENGINE == 'jruby' | |
+ FFI.errno = error || 0 | |
+ else | |
+ Thread.current[:__DL2_LAST_ERROR__] = error | |
+ Thread.current[:__FIDDLE_LAST_ERROR__] = error | |
+ end | |
end | |
# call-seq: dlopen(library) => Fiddle::Handle | |
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb | |
index 3799d589d5..e4725dc49d 100644 | |
--- a/ext/pathname/lib/pathname.rb | |
+++ b/ext/pathname/lib/pathname.rb | |
@@ -10,7 +10,8 @@ | |
# For documentation, see class Pathname. | |
# | |
-require 'pathname.so' | |
+# Load built-in pathname library | |
+JRuby::Util.load_ext("org.jruby.ext.pathname.PathnameLibrary") | |
class Pathname | |
diff --git a/ext/ripper/lib/ripper/core.rb b/ext/ripper/lib/ripper/core.rb | |
index fa075da5b9..968766b12d 100644 | |
--- a/ext/ripper/lib/ripper/core.rb | |
+++ b/ext/ripper/lib/ripper/core.rb | |
@@ -9,7 +9,12 @@ | |
# For details of Ruby License, see ruby/COPYING. | |
# | |
-require 'ripper.so' | |
+if RUBY_ENGINE == 'jruby' | |
+ # Load built-in ripper library | |
+ JRuby::Util.load_ext("org.jruby.ext.ripper.RipperLibrary") | |
+else | |
+ require 'ripper.so' | |
+end | |
class Ripper | |
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb | |
index d756a32a5a..88f03d393e 100644 | |
--- a/ext/socket/lib/socket.rb | |
+++ b/ext/socket/lib/socket.rb | |
@@ -1,6 +1,8 @@ | |
# frozen_string_literal: true | |
-require 'socket.so' | |
+# Load built-in socket library | |
+JRuby::Util.load_ext("org.jruby.ext.socket.SocketLibrary") | |
+ | |
require 'io/wait' | |
class Addrinfo | |
@@ -194,7 +196,7 @@ def bind | |
# creates a listening socket bound to self. | |
def listen(backlog=Socket::SOMAXCONN) | |
- sock = Socket.new(self.pfamily, self.socktype, self.protocol) | |
+ sock = ServerSocket.new(self.pfamily, self.socktype, self.protocol) | |
begin | |
sock.ipv6only! if self.ipv6? | |
sock.setsockopt(:SOCKET, :REUSEADDR, 1) | |
@@ -300,9 +302,9 @@ def connect_address | |
# # use 3-element array. | |
# ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")] | |
# sock.sendmsg("\0", 0, nil, ancdata) | |
- def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) | |
- __sendmsg(mesg, flags, dest_sockaddr, controls) | |
- end | |
+ #def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) | |
+ # __sendmsg(mesg, flags, dest_sockaddr, controls) | |
+ #end | |
# call-seq: | |
# basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls, opts={}) => numbytes_sent | |
@@ -316,10 +318,10 @@ def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) | |
# By specifying a keyword argument _exception_ to +false+, you can indicate | |
# that sendmsg_nonblock should not raise an IO::WaitWritable exception, but | |
# return the symbol +:wait_writable+ instead. | |
- def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, | |
- exception: true) | |
- __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception) | |
- end | |
+ #def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, | |
+ # exception: true) | |
+ # __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception) | |
+ #end | |
# call-seq: | |
# basicsocket.recv_nonblock(maxlen [, flags [, buf [, options ]]]) => mesg | |
@@ -368,9 +370,9 @@ def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, | |
# | |
# === See | |
# * Socket#recvfrom | |
- def recv_nonblock(len, flag = 0, str = nil, exception: true) | |
- __recv_nonblock(len, flag, str, exception) | |
- end | |
+ #def recv_nonblock(len, flag = 0, str = nil, exception: true) | |
+ # __recv_nonblock(len, flag, str, exception) | |
+ #end | |
# call-seq: | |
# basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls] | |
@@ -423,9 +425,9 @@ def recv_nonblock(len, flag = 0, str = nil, exception: true) | |
# return ancdata.unix_rights[0] | |
# end | |
# } | |
- def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) | |
- __recvmsg(dlen, flags, clen, scm_rights) | |
- end | |
+ #def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) | |
+ # __recvmsg(dlen, flags, clen, scm_rights) | |
+ #end | |
# call-seq: | |
# basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls] | |
@@ -439,23 +441,23 @@ def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) | |
# By specifying a keyword argument _exception_ to +false+, you can indicate | |
# that recvmsg_nonblock should not raise an IO::WaitReadable exception, but | |
# return the symbol +:wait_readable+ instead. | |
- def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil, | |
- scm_rights: false, exception: true) | |
- __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception) | |
- end | |
+ #def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil, | |
+ # scm_rights: false, exception: true) | |
+ # __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception) | |
+ #end | |
# Linux-specific optimizations to avoid fcntl for IO#read_nonblock | |
# and IO#write_nonblock using MSG_DONTWAIT | |
# Do other platforms support MSG_DONTWAIT reliably? | |
- if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT) | |
- def read_nonblock(len, str = nil, exception: true) # :nodoc: | |
- __read_nonblock(len, str, exception) | |
- end | |
- | |
- def write_nonblock(buf, exception: true) # :nodoc: | |
- __write_nonblock(buf, exception) | |
- end | |
- end | |
+ #if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT) | |
+ # def read_nonblock(len, str = nil, exception: true) # :nodoc: | |
+ # __read_nonblock(len, str, exception) | |
+ # end | |
+ # | |
+ # def write_nonblock(buf, exception: true) # :nodoc: | |
+ # __write_nonblock(buf, exception) | |
+ # end | |
+ #end | |
end | |
class Socket < BasicSocket | |
@@ -466,6 +468,9 @@ def ipv6only! | |
end | |
end | |
+ # JRuby does not do this dance to get around keyword arguments. | |
+ unless RUBY_ENGINE == 'jruby' | |
+ | |
# call-seq: | |
# socket.recvfrom_nonblock(maxlen[, flags[, outbuf[, opts]]]) => [mesg, sender_addrinfo] | |
# | |
@@ -532,9 +537,9 @@ def ipv6only! | |
# | |
# === See | |
# * Socket#recvfrom | |
- def recvfrom_nonblock(len, flag = 0, str = nil, exception: true) | |
- __recvfrom_nonblock(len, flag, str, exception) | |
- end | |
+ #def recvfrom_nonblock(len, flag = 0, str = nil, exception: true) | |
+ # __recvfrom_nonblock(len, flag, str, exception) | |
+ #end | |
# call-seq: | |
# socket.accept_nonblock([options]) => [client_socket, client_addrinfo] | |
@@ -589,9 +594,11 @@ def recvfrom_nonblock(len, flag = 0, str = nil, exception: true) | |
# | |
# === See | |
# * Socket#accept | |
- def accept_nonblock(exception: true) | |
- __accept_nonblock(exception) | |
- end | |
+ #def accept_nonblock(exception: true) | |
+ # __accept_nonblock(exception) | |
+ #end | |
+ | |
+ end # unless RUBY_ENGINE == 'jruby' | |
# :call-seq: | |
# Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) {|socket| ... } | |
@@ -673,7 +680,7 @@ def self.ip_sockets_port0(ai_list, reuseaddr) | |
port = nil | |
ai_list.each {|ai| | |
begin | |
- s = Socket.new(ai.pfamily, ai.socktype, ai.protocol) | |
+ s = ServerSocket.new(ai.pfamily, ai.socktype, ai.protocol) | |
rescue SystemCallError | |
next | |
end | |
@@ -1210,9 +1217,9 @@ def self.unix_server_loop(path, &b) # :yield: socket, client_addrinfo | |
# | |
# === See | |
# # Socket#connect | |
- def connect_nonblock(addr, exception: true) | |
- __connect_nonblock(addr, exception) | |
- end | |
+ #def connect_nonblock(addr, exception: true) | |
+ # __connect_nonblock(addr, exception) | |
+ #end | |
end | |
class UDPSocket < IPSocket | |
@@ -1268,9 +1275,9 @@ class UDPSocket < IPSocket | |
# | |
# === See | |
# * Socket#recvfrom | |
- def recvfrom_nonblock(len, flag = 0, outbuf = nil, exception: true) | |
- __recvfrom_nonblock(len, flag, outbuf, exception) | |
- end | |
+ #def recvfrom_nonblock(len, flag = 0, outbuf = nil, exception: true) | |
+ # __recvfrom_nonblock(len, flag, outbuf, exception) | |
+ #end | |
end | |
class TCPServer < TCPSocket | |
@@ -1310,9 +1317,9 @@ class TCPServer < TCPSocket | |
# === See | |
# * TCPServer#accept | |
# * Socket#accept | |
- def accept_nonblock(exception: true) | |
- __accept_nonblock(exception) | |
- end | |
+ #def accept_nonblock(exception: true) | |
+ # __accept_nonblock(exception) | |
+ #end | |
end | |
class UNIXServer < UNIXSocket | |
@@ -1351,7 +1358,7 @@ class UNIXServer < UNIXSocket | |
# === See | |
# * UNIXServer#accept | |
# * Socket#accept | |
- def accept_nonblock(exception: true) | |
- __accept_nonblock(exception) | |
- end | |
+ #def accept_nonblock(exception: true) | |
+ # __accept_nonblock(exception) | |
+ #end | |
end if defined?(UNIXSocket) | |
diff --git a/ext/win32/lib/win32/resolv.rb b/ext/win32/lib/win32/resolv.rb | |
index d06658f0aa..b96a4bdfaf 100644 | |
--- a/ext/win32/lib/win32/resolv.rb | |
+++ b/ext/win32/lib/win32/resolv.rb | |
@@ -37,9 +37,81 @@ def self.get_resolv_info | |
end | |
end | |
-begin | |
- require 'win32/resolv.so' | |
-rescue LoadError | |
+ | |
+# JRuby specific use FFI instead of loading native .so | |
+module Win32 | |
+ module Internal | |
+ NO_ERROR, ERROR_BUFFER_OVERFLOW = 0, 111 | |
+ | |
+ require 'ffi' | |
+ | |
+ class IP_ADDRESS_STRING < FFI::Struct | |
+ layout :string, [:uint8, 16] | |
+ end | |
+ | |
+ class IP_ADDR_STRING < FFI::Struct | |
+ layout :next, IP_ADDR_STRING.ptr, | |
+ :ip_address, IP_ADDRESS_STRING, | |
+ :ip_mask_string, IP_ADDRESS_STRING, | |
+ :context, :int | |
+ end | |
+ | |
+ class FIXED_INFO < FFI::Struct | |
+ layout :host_name, [:uint8, 128 + 4], | |
+ :domain_name, [:uint8, 128 + 4], | |
+ :current_dns_server, IP_ADDR_STRING.ptr, | |
+ :dns_server_list, IP_ADDR_STRING, | |
+ :node_type, :uint, | |
+ :scope_id, [:uint8, 256 + 4], | |
+ :enable_routine, :uint, | |
+ :enable_proxy, :uint, | |
+ :enable_dns, :uint | |
+ end | |
+ | |
+ class IntPtr < FFI::Struct | |
+ layout :value, :int | |
+ end | |
+ | |
+ module Iphlpapi | |
+ extend FFI::Library | |
+ ffi_lib 'Iphlpapi' | |
+ ffi_convention :stdcall | |
+ | |
+ attach_function :get_network_params, :GetNetworkParams, [:pointer, IntPtr], :int | |
+ end | |
+ end | |
+end | |
+ | |
+module Win32 | |
+ module Resolv | |
+ def self.get_dns_server_list | |
+ size = Win32::Internal::IntPtr.new | |
+ ret = Win32::Internal::Iphlpapi.get_network_params nil, size | |
+ | |
+ # We get buffer overflow because first arg to get_network_params is nil. | |
+ if ret != Win32::Internal::NO_ERROR && ret != Win32::Internal::ERROR_BUFFER_OVERFLOW | |
+ raise Win32::Resolv::Error | |
+ end | |
+ | |
+ fixed_info = FFI::MemoryPointer.new size[:value] | |
+ ret = Win32::Internal::Iphlpapi.get_network_params fixed_info, size | |
+ | |
+ raise Win32::Resolv::Error if ret != Win32::Internal::NO_ERROR | |
+ | |
+ fixed_info = Win32::Internal::FIXED_INFO.new fixed_info | |
+ | |
+ addr = fixed_info[:dns_server_list] | |
+ addresses = [] | |
+ | |
+ while !addr.null? do # test condition on machines with no DNS entries at all. | |
+ addresses << addr[:ip_address][:string].to_s | |
+ break if addr[:next].null? | |
+ addr = addr[:next] | |
+ end | |
+ | |
+ addresses | |
+ end | |
+ end | |
end | |
module Win32 | |
diff --git a/lib/net/http.rb b/lib/net/http.rb | |
index 552f818e5d..25cc6e370b 100644 | |
--- a/lib/net/http.rb | |
+++ b/lib/net/http.rb | |
@@ -651,6 +651,10 @@ class << HTTP | |
# is required to use the proxy, and p_no_proxy hosts which do not | |
# use the proxy. | |
# | |
+ # In JRuby, this will default to the JSE proxy settings provided in the | |
+ # 'http.proxyHost' and 'http.proxyPort' Java system properties, if they | |
+ # are set, falling back on environment variables otherwise. | |
+ # | |
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil) | |
http = super address, port | |
@@ -1032,10 +1036,12 @@ def connect | |
end | |
end | |
@ssl_context.set_params(ssl_parameters) | |
- @ssl_context.session_cache_mode = | |
- OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | | |
- OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE | |
- @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess } | |
+ # NOTE: session_cache_mode = has no effect on (current) JRuby-OpenSSL | |
+ # @ssl_context.session_cache_mode = | |
+ # OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | | |
+ # OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE | |
+ # SSLSocket#session= does nothing with JRuby-OpenSSL | |
+ # @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess } | |
D "starting SSL for #{conn_addr}:#{conn_port}..." | |
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context) | |
s.sync_close = true | |
@@ -1046,7 +1052,7 @@ def connect | |
s.session = @ssl_session | |
end | |
ssl_socket_connect(s, @open_timeout) | |
- if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && @ssl_context.verify_hostname | |
+ if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) # && @ssl_context.verify_hostname | |
s.post_connection_check(@address) | |
end | |
D "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}" | |
@@ -1103,6 +1109,11 @@ def do_finish | |
# | |
# This class is obsolete. You may pass these same parameters directly to | |
# Net::HTTP.new. See Net::HTTP.new for details of the arguments. | |
+ # | |
+ # In JRuby, this will default to the JSE proxy settings provided in the | |
+ # 'http.proxyHost' and 'http.proxyPort' Java system properties, if they | |
+ # are set, falling back on environment variables otherwise. | |
+ # | |
def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) | |
return self unless p_addr | |
diff --git a/lib/tmpdir.rb b/lib/tmpdir.rb | |
index 3b67164039..cc0b60790b 100644 | |
--- a/lib/tmpdir.rb | |
+++ b/lib/tmpdir.rb | |
@@ -7,7 +7,7 @@ | |
require 'fileutils' | |
begin | |
- require 'etc.so' | |
+ require 'etc' | |
rescue LoadError # rescue LoadError for miniruby | |
end | |
@@ -87,9 +87,9 @@ def self.tmpdir | |
# | |
def self.mktmpdir(prefix_suffix=nil, *rest, **options) | |
base = nil | |
- path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|path, _, _, d| | |
+ path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|_path, _, _, d| | |
base = d | |
- mkdir(path, 0700) | |
+ mkdir(_path, 0700) | |
} | |
if block_given? | |
begin | |
@@ -140,7 +140,10 @@ def create(basename, tmpdir=nil, max_try: nil, **opts) | |
t = Time.now.strftime("%Y%m%d") | |
path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\ | |
"#{n ? %[-#{n}] : ''}#{suffix||''}" | |
- path = File.join(tmpdir, path) | |
+ # We use the second form here because chdir + ./ files won't open right (http://bugs.jruby.org/3698) | |
+ # path = File.join(tmpdir, path) | |
+ path = File.expand_path(path, tmpdir) | |
+ | |
yield(path, n, opts, origdir) | |
rescue Errno::EEXIST | |
n ||= 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment