File: linux64-detection-pr82.patch

package info (click to toggle)
ruby-sys-filesystem 1.4.4-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 308 kB
  • sloc: ruby: 1,952; makefile: 3
file content (265 lines) | stat: -rw-r--r-- 11,623 bytes parent folder | download
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
Description: Fix linux64 detection fails on s390x and alpha
Origin: upstream, https://github.com/djberg96/sys-filesystem/commit/5a3416808e767d0a094c8dd0dc8641f7ff4b7829
Bug: https://github.com/djberg96/sys-filesystem/issues/81
Bug-Debian: https://bugs.debian.org/1114552
Reviewed-by: Aurelien Jarno <aurel32@debian.org>
Last-Update: 2025-09-14

diff --git a/lib/sys/unix/sys/filesystem/functions.rb b/lib/sys/unix/sys/filesystem/functions.rb
index 685b388..e8738b3 100644
--- a/lib/sys/unix/sys/filesystem/functions.rb
+++ b/lib/sys/unix/sys/filesystem/functions.rb
@@ -16,7 +16,7 @@ def self.linux64?
             ENV_JAVA['sun.arch.data.model'].to_i == 64
         else
           RbConfig::CONFIG['host_os'] =~ /linux/i &&
-            (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
+            (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/ || [nil].pack('P').size == 8)
         end
       end
 
diff --git a/lib/sys/unix/sys/filesystem/structs.rb b/lib/sys/unix/sys/filesystem/structs.rb
index a055190..46019e6 100644
--- a/lib/sys/unix/sys/filesystem/structs.rb
+++ b/lib/sys/unix/sys/filesystem/structs.rb
@@ -28,7 +28,7 @@ def self.linux64?
             ENV_JAVA['sun.arch.data.model'].to_i == 64
           else
             RbConfig::CONFIG['host_os'] =~ /linux/i &&
-              (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
+              (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/ || [nil].pack('P').size == 8)
           end
         end
 
@@ -155,7 +155,7 @@ def self.linux64?
             ENV_JAVA['sun.arch.data.model'].to_i == 64
           else
             RbConfig::CONFIG['host_os'] =~ /linux/i &&
-              (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
+              (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/ || [nil].pack('P').size == 8)
           end
         end
 
diff --git a/spec/sys_filesystem_unix_spec.rb b/spec/sys_filesystem_unix_spec.rb
index d9a5ec7..9419b1a 100644
--- a/spec/sys_filesystem_unix_spec.rb
+++ b/spec/sys_filesystem_unix_spec.rb
@@ -524,4 +524,218 @@
       expect{ described_class.stat('/whatever') }.to raise_error(Sys::Filesystem::Error, msg)
     end
   end
+
+  describe 'linux64? method' do
+    let(:functions_class) { Sys::Filesystem::Functions }
+
+    # Helper method to test linux64? with mocked config
+    def test_linux64_with_config(host_os, pointer_size, ruby_platform = nil, java_arch = nil)
+      # Mock RbConfig::CONFIG
+      allow(RbConfig::CONFIG).to receive(:[]).and_call_original
+      allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return(host_os)
+
+      # When running under JRuby, we need to handle it differently
+      if RUBY_PLATFORM == 'java'
+        # Under JRuby, always mock ENV_JAVA since that's the path the code will take
+        if java_arch
+          # This is a JRuby-specific test
+          allow(ENV_JAVA).to receive(:[]).with('sun.arch.data.model').and_return(java_arch.to_s)
+        else
+          # This is meant to test regular Ruby logic, but under JRuby we need to mock ENV_JAVA
+          # to make it take the "regular Ruby" path by returning nil/empty
+          expected_arch = pointer_size == 8 ? '64' : '32'
+          allow(ENV_JAVA).to receive(:[]).with('sun.arch.data.model').and_return(expected_arch)
+        end
+      else
+        # Running under regular Ruby
+        # Determine arch and DEFS based on host_os for the new multi-check approach
+        if pointer_size == 8
+          # For 64-bit systems, make arch contain "64"
+          arch_value = host_os.include?('64') ? host_os : host_os + '64'
+          defs_value = '-DSOMETHING=1'
+        else
+          # For 32-bit systems, ensure neither arch nor DEFS contain "64"
+          arch_value = host_os.gsub(/64/, '32')
+          defs_value = '-DSOMETHING=1'
+        end
+
+        allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_return(arch_value)
+        allow(RbConfig::CONFIG).to receive(:[]).with('DEFS').and_return(defs_value)
+
+        if ruby_platform == 'java'
+          # Mock RUBY_PLATFORM for JRuby tests
+          stub_const('RUBY_PLATFORM', 'java')
+
+          # Mock ENV_JAVA for JRuby
+          env_java_mock = double('ENV_JAVA')
+          allow(env_java_mock).to receive(:[]).with('sun.arch.data.model').and_return(java_arch.to_s)
+          stub_const('ENV_JAVA', env_java_mock)
+        else
+          # Mock the pack method for regular Ruby (last resort check)
+          packed_data = 'x' * pointer_size
+          allow_any_instance_of(Array).to receive(:pack).with('P').and_return(packed_data)
+        end
+      end
+
+      functions_class.send(:linux64?)
+    end
+
+    context 'with different Linux distributions on 64-bit architectures' do
+      let(:linux_distros) do
+        {
+          'x86_64-linux-gnu' => 'Ubuntu/Debian x86_64',
+          'x86_64-pc-linux-gnu' => 'Generic x86_64 Linux',
+          'aarch64-linux-gnu' => 'ARM64 (Raspberry Pi 4, AWS Graviton)',
+          's390x-linux-gnu' => 'IBM Z mainframe',
+          'powerpc64le-linux-gnu' => 'POWER8/9 little-endian',
+          'powerpc64-linux-gnu' => 'POWER8/9 big-endian',
+          'mips64el-linux-gnuabi64' => 'MIPS64 little-endian',
+          'alpha-linux-gnu' => 'DEC Alpha',
+          'sparc64-linux-gnu' => 'SPARC64',
+          'riscv64-linux-gnu' => 'RISC-V 64-bit'
+        }
+      end
+
+      it 'returns true for 64-bit Linux systems' do
+        linux_distros.each do |host_os, description|
+          result = test_linux64_with_config(host_os, 8)
+          expect(result).to be_truthy, "Expected linux64? to return true for #{host_os} (#{description})"
+        end
+      end
+    end
+
+    context 'with different Linux distributions on 32-bit architectures' do
+      let(:linux_32bit_distros) do
+        {
+          'i386-linux-gnu' => '32-bit x86',
+          'i486-linux-gnu' => '32-bit x86',
+          'i586-linux-gnu' => '32-bit x86',
+          'i686-linux-gnu' => '32-bit x86',
+          'arm-linux-gnueabihf' => 'ARM 32-bit hard-float',
+          'armv7l-linux-gnueabihf' => 'ARMv7 32-bit',
+          'mips-linux-gnu' => 'MIPS 32-bit',
+          'mipsel-linux-gnu' => 'MIPS 32-bit little-endian',
+          'powerpc-linux-gnu' => 'PowerPC 32-bit',
+          's390-linux-gnu' => 'IBM S/390 32-bit'
+        }
+      end
+
+      it 'returns false for 32-bit Linux systems' do
+        linux_32bit_distros.each do |host_os, description|
+          result = test_linux64_with_config(host_os, 4)
+          expect(result).to be_falsey, "Expected linux64? to return false for #{host_os} (#{description})"
+        end
+      end
+    end
+
+    context 'with non-Linux operating systems' do
+      let(:non_linux_os) do
+        {
+          'darwin21.6.0' => 'macOS',
+          'freebsd13.1' => 'FreeBSD',
+          'openbsd7.2' => 'OpenBSD',
+          'netbsd9.3' => 'NetBSD',
+          'dragonfly6.4' => 'DragonFlyBSD',
+          'solaris2.11' => 'Solaris',
+          'aix7.2.0.0' => 'AIX',
+          'mingw32' => 'Windows MSYS2',
+          'cygwin' => 'Cygwin'
+        }
+      end
+
+      it 'returns false for non-Linux systems regardless of architecture' do
+        non_linux_os.each do |host_os, description|
+          # Test both 32-bit and 64-bit scenarios
+          [4, 8].each do |pointer_size|
+            result = test_linux64_with_config(host_os, pointer_size)
+            expect(result).to be_falsey,
+              "Expected linux64? to return false for #{host_os} (#{description}) with #{pointer_size * 8}-bit pointers"
+          end
+        end
+      end
+    end
+
+    context 'with JRuby on different platforms' do
+      it 'returns true for 64-bit Linux on JRuby' do
+        result = test_linux64_with_config('x86_64-linux-gnu', nil, 'java', 64)
+        expect(result).to be_truthy
+      end
+
+      it 'returns false for 32-bit Linux on JRuby' do
+        result = test_linux64_with_config('i386-linux-gnu', nil, 'java', 32)
+        expect(result).to be_falsey
+      end
+
+      it 'returns false for non-Linux systems on JRuby' do
+        result = test_linux64_with_config('darwin21.6.0', nil, 'java', 64)
+        expect(result).to be_falsey
+      end
+    end
+
+    context 'edge cases' do
+      it 'handles case-insensitive Linux detection' do
+        ['LINUX-gnu', 'Linux-gnu', 'linux-GNU'].each do |host_os|
+          result = test_linux64_with_config(host_os, 8)
+          expect(result).to be_truthy, "Expected linux64? to handle case-insensitive matching for #{host_os}"
+        end
+      end
+
+      it 'handles partial Linux matches in host_os string' do
+        ['some-linux-variant', 'embedded-linux-system', 'custom-linux-build'].each do |host_os|
+          result = test_linux64_with_config(host_os, 8)
+          expect(result).to be_truthy, "Expected linux64? to match partial Linux strings for #{host_os}"
+        end
+      end
+    end
+
+    context 'multi-check priority order', unless: RUBY_PLATFORM == 'java' do
+      it 'uses arch check first when arch contains 64' do
+        allow(RbConfig::CONFIG).to receive(:[]).and_call_original
+        allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('x86_64-linux-gnu')
+        allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_return('x86_64-linux')
+        allow(RbConfig::CONFIG).to receive(:[]).with('DEFS').and_return('')
+
+        # Should not need to call pack method since arch check succeeds
+        expect_any_instance_of(Array).not_to receive(:pack)
+
+        expect(functions_class.send(:linux64?)).to be_truthy
+      end
+
+      it 'uses DEFS check when arch does not contain 64 but DEFS does' do
+        allow(RbConfig::CONFIG).to receive(:[]).and_call_original
+        allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('special-linux-gnu')
+        allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_return('special-linux')
+        allow(RbConfig::CONFIG).to receive(:[]).with('DEFS').and_return('-D__LP64__=1')
+
+        # Should not need to call pack method since DEFS check succeeds
+        expect_any_instance_of(Array).not_to receive(:pack)
+
+        expect(functions_class.send(:linux64?)).to be_truthy
+      end
+
+      it 'falls back to pack method when neither arch nor DEFS contain 64' do
+        allow(RbConfig::CONFIG).to receive(:[]).and_call_original
+        allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('custom-linux-gnu')
+        allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_return('custom-linux')
+        allow(RbConfig::CONFIG).to receive(:[]).with('DEFS').and_return('-DSOMETHING=1')
+
+        # Should call pack method as last resort
+        allow_any_instance_of(Array).to receive(:pack).with('P').and_return('12345678')
+
+        expect(functions_class.send(:linux64?)).to be_truthy
+      end
+
+      it 'returns false when all checks fail on 32-bit' do
+        allow(RbConfig::CONFIG).to receive(:[]).and_call_original
+        allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('custom-linux-gnu')
+        allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_return('custom-linux')
+        allow(RbConfig::CONFIG).to receive(:[]).with('DEFS').and_return('-DSOMETHING=1')
+
+        # Pack method returns 4 bytes (32-bit)
+        allow_any_instance_of(Array).to receive(:pack).with('P').and_return('1234')
+
+        expect(functions_class.send(:linux64?)).to be_falsey
+      end
+    end
+  end
 end