1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
Description: Support 64b time_t on armel/armhf
Author: Lucas Nussbaum <lucas@debian.org>
Bug-Debian: https://bugs.debian.org/1095247
Bug: https://github.com/petergoldstein/dalli/issues/1034
Forwarded: https://github.com/petergoldstein/dalli/issues/1034
Index: ruby-dalli/lib/dalli/socket.rb
===================================================================
--- ruby-dalli.orig/lib/dalli/socket.rb
+++ ruby-dalli/lib/dalli/socket.rb
@@ -126,8 +126,26 @@ module Dalli
seconds, fractional = options[:socket_timeout].divmod(1)
microseconds = fractional * 1_000_000
- timeval = [seconds, microseconds].pack('l_2')
+ # struct timeval is (time_t, suseconds_t), which translates to either (int32_t, long) or
+ # (int64_t, long) depending on the architecture. For example, on Debian, all 64b
+ # architectures have int64_t for time_t, but for 32b architectures, it depends:
+ # armel and armhf use int64_t, while i386 stayed with int32_t.
+ # Unfortunately Array::pack does not know about time_t. So we generate both candidates,
+ # use getsockopt to get a timeval, and compare sizes.
+ # Supported timeval formats:
+ timeval_formats = [
+ 'q l_', # 64-bit time_t, 64-bit long (e.g., amd64, arm64)
+ 'l l_', # 32-bit time_t, 32-bit long (e.g., i386)
+ 'q l_ x4' # 64-bit time_t, 32-bit long + padding (e.g., armel on Debian)
+ ]
+ timeval_args = [seconds, microseconds]
+ expected_length = sock.getsockopt(::Socket::SOL_SOCKET, ::Socket::SO_RCVTIMEO).data.length
+ timeval_format = timeval_formats.find do |fmt|
+ timeval_args.pack(fmt).length == expected_length
+ end
+ raise Dalli::DalliError,"Unable to determine appropriate timeval format" unless timeval_format
+ timeval = timeval_args.pack(timeval_format)
sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_RCVTIMEO, timeval)
sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_SNDTIMEO, timeval)
end
|