sys-filesystem 1.4.3 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b00e624e22bd699630d63b34f90be7758f82630a069f7db2a61e2139cb55888
4
- data.tar.gz: 59add440f0203bade0430b2acd410e785b4ab0de416f272755a72db9276aa767
3
+ metadata.gz: 867cb33509a3fa99a58dbf3e0ee69107470a3cecebe4efc2346f49ec1dc1cea6
4
+ data.tar.gz: 9b1de11209f227d00584c021323b3de75db44e399823941bbad5bf9dd407cab2
5
5
  SHA512:
6
- metadata.gz: eb24f3c965a15d090fd7fff5800cc4c1829a7ddc7f2cbc4e943bb7e57ae92749a6abfccfecd94e8522287e9700916fc22f57af164afa413459321fa9460ba9a3
7
- data.tar.gz: d5d30e84e01f370ac62b77251f2c80c07964a99bebfa0cc30252237bc33830198d3a065c28a546c230327b1b951d45d95bc309f75276d17d7e1e8968ade216f2
6
+ metadata.gz: 29b4307434bda5a5447b45675a447d90421c104ba138f296c932272d6054c1cd81d4a3ddd68bdd9b099c30b012409a66ca9befd0275491d448fc2ae6f2184825
7
+ data.tar.gz: 5a6ee063a349093b3b0161814ce6f3b56af683d2a87960ab26d2975530bce91b4a1b31b1f2af1949fb315589116ef8ce5896a95802739a3e85573b436d6c5b6e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.4.5 - 22-May-2024
2
+ * Handle the possibility that a statvs64 alias may not exist on some Linux
3
+ platforms. Thanks go to Antoine Martin for the report.
4
+
5
+ ## 1.4.4 - 12-Sep-2023
6
+ * Yet another fix for 32-bit vs 64-bit linux, specifically for the Statvfs
7
+ struct. Thanks go to Josh Cooper for the spot and the patch.
8
+
1
9
  ## 1.4.3 - 20-Oct-2021
2
10
  * Another fix for 32-bit vs 64-bit Linux since it was realized we cannot always
3
11
  rely on the host architecture information. Handling for JRuby was improved
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'rake'
2
2
  require 'rake/clean'
3
3
  require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
4
5
 
5
6
  CLEAN.include('**/*.gem', '**/*.rbc', '**/*.rbx', '**/*.lock')
6
7
 
@@ -25,6 +26,18 @@ task :example do
25
26
  sh "ruby -Ilib -Ilib/unix -Ilib/windows examples/example_stat.rb"
26
27
  end
27
28
 
29
+ RuboCop::RakeTask.new
30
+
31
+ namespace :rubocop do
32
+ RuboCop::RakeTask.new(:unix) do |task|
33
+ task.patterns = ['lib/sys/unix/sys/**/*.rb', 'spec/*unix*']
34
+ end
35
+
36
+ RuboCop::RakeTask.new(:windows) do |task|
37
+ task.patterns = ['lib/sys/windows/sys/**/*.rb', 'spec/*windows*']
38
+ end
39
+ end
40
+
28
41
  desc "Run the test suite"
29
42
  RSpec::Core::RakeTask.new(:spec)
30
43
 
@@ -1,9 +1,4 @@
1
- module Sys
2
- class Filesystem
3
- # The version of the sys-filesystem library
4
- VERSION = '1.4.3'.freeze
5
- end
6
- end
1
+ # frozen_string_literal: true
7
2
 
8
3
  require 'rbconfig'
9
4
 
@@ -13,10 +8,18 @@ else
13
8
  require_relative 'unix/sys/filesystem'
14
9
  end
15
10
 
16
- # Methods universal to all platforms
11
+ # Methods and properties universal to all platforms
17
12
 
13
+ # The Sys module serves as a namespace only.
18
14
  module Sys
15
+ # The Filesystem class serves as an abstract base class. Its methods
16
+ # return objects of other types. Do not instantiate.
19
17
  class Filesystem
18
+ # The version of the sys-filesystem library
19
+ VERSION = '1.4.5'
20
+
21
+ # Stat objects are returned by the Sys::Filesystem.stat method. Here
22
+ # we're adding universal methods.
20
23
  class Stat
21
24
  # Returns true if the filesystem is case sensitive for the current path.
22
25
  # Typically this will be any path on MS Windows or Macs using HFS.
@@ -26,14 +29,12 @@ module Sys
26
29
  # general rule, I do not recommend using this method for a root path.
27
30
  #
28
31
  def case_insensitive?
29
- if path !~ /\w+/
30
- if RbConfig::CONFIG['host_os'] =~ /darwin|mac|windows|mswin|mingw/i
31
- true # Assumes HFS
32
- else
33
- false
34
- end
35
- else
32
+ if path =~ /\w+/
36
33
  File.identical?(path, path.swapcase)
34
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin|mac|windows|mswin|mingw/i
35
+ true # Assumes HFS/APFS on Mac
36
+ else
37
+ false
37
38
  end
38
39
  end
39
40
 
@@ -46,8 +47,8 @@ module Sys
46
47
  end
47
48
  end
48
49
 
49
- # Some convenient methods for converting bytes to kb, mb, and gb.
50
- #
50
+ # Reopen the Numeric class and add some convenient methods
51
+ # for converting bytes to kb, mb, and gb.
51
52
  class Numeric
52
53
  # call-seq:
53
54
  # <tt>num</tt>.to_kb
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sys
2
4
  class Filesystem
3
5
  module Constants
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ffi'
2
4
 
3
5
  module Sys
4
6
  class Filesystem
7
+ # A scoped module for internal FFI functions to be used by the main code.
5
8
  module Functions
6
9
  extend FFI::Library
7
10
 
@@ -9,19 +12,26 @@ module Sys
9
12
 
10
13
  def self.linux64?
11
14
  if RUBY_PLATFORM == 'java'
12
- ENV_JAVA['sun.arch.data.model'].to_i == 64
15
+ RbConfig::CONFIG['host_os'] =~ /linux/i &&
16
+ ENV_JAVA['sun.arch.data.model'].to_i == 64
13
17
  else
14
18
  RbConfig::CONFIG['host_os'] =~ /linux/i &&
15
19
  (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
16
20
  end
17
21
  end
18
22
 
23
+ def self.solaris?
24
+ RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
25
+ end
26
+
19
27
  private_class_method :linux64?
20
28
 
21
- if RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
22
- attach_function(:statvfs, :statvfs64, %i[string pointer], :int)
23
- elsif linux64?
24
- attach_function(:statvfs, :statvfs64, %i[string pointer], :int)
29
+ if linux64? || solaris?
30
+ begin
31
+ attach_function(:statvfs, :statvfs64, %i[string pointer], :int)
32
+ rescue FFI::NotFoundError # Not every Linux distro has an alias
33
+ attach_function(:statvfs, %i[string pointer], :int)
34
+ end
25
35
  else
26
36
  attach_function(:statvfs, %i[string pointer], :int)
27
37
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ffi'
2
4
  require 'rbconfig'
3
5
 
4
6
  module Sys
5
7
  class Filesystem
6
8
  module Structs
9
+ # The Statfs struct is a subclass of FFI::Struct that corresponds to a struct statfs.
7
10
  class Statfs < FFI::Struct
8
-
11
+ # Private method that will determine the layout of the struct on Linux.
9
12
  def self.linux64?
10
13
  if RUBY_PLATFORM == 'java'
11
14
  ENV_JAVA['sun.arch.data.model'].to_i == 64
@@ -20,92 +23,103 @@ module Sys
20
23
  # FreeBSD 12.0 MNAMELEN from 88 => 1024.
21
24
  MNAMELEN =
22
25
  if RbConfig::CONFIG['host_os'] =~ /freebsd(.*)/i
23
- $1.to_f < 12.0 ? 88 : 1024
26
+ Regexp.last_match(1).to_f < 12.0 ? 88 : 1024
24
27
  else
25
28
  88
26
29
  end
27
30
 
28
- if RbConfig::CONFIG['host_os'] =~ /bsd/i
29
- layout(
30
- :f_version, :uint32,
31
- :f_type, :uint32,
32
- :f_flags, :uint64,
33
- :f_bsize, :uint64,
34
- :f_iosize, :int64,
35
- :f_blocks, :uint64,
36
- :f_bfree, :uint64,
37
- :f_bavail, :int64,
38
- :f_files, :uint64,
39
- :f_ffree, :uint64,
40
- :f_syncwrites, :uint64,
41
- :f_asyncwrites, :uint64,
42
- :f_syncreads, :uint64,
43
- :f_asyncreads, :uint64,
44
- :f_spare, [:uint64, 10],
45
- :f_namemax, :uint32,
46
- :f_owner, :int32,
47
- :f_fsid, [:int32, 2],
48
- :f_charspare, [:char, 80],
49
- :f_fstypename, [:char, 16],
50
- :f_mntfromname, [:char, MNAMELEN],
51
- :f_mntonname, [:char, MNAMELEN]
52
- )
53
- elsif RbConfig::CONFIG['host_os'] =~ /linux/i
54
- if linux64?
31
+ case RbConfig::CONFIG['host_os']
32
+ when /bsd/i
55
33
  layout(
56
- :f_type, :ulong,
57
- :f_bsize, :ulong,
34
+ :f_version, :uint32,
35
+ :f_type, :uint32,
36
+ :f_flags, :uint64,
37
+ :f_bsize, :uint64,
38
+ :f_iosize, :int64,
58
39
  :f_blocks, :uint64,
59
40
  :f_bfree, :uint64,
60
- :f_bavail, :uint64,
41
+ :f_bavail, :int64,
61
42
  :f_files, :uint64,
62
43
  :f_ffree, :uint64,
63
- :f_fsid, [:int, 2],
64
- :f_namelen, :ulong,
65
- :f_frsize, :ulong,
66
- :f_flags, :ulong,
67
- :f_spare, [:ulong, 4]
44
+ :f_syncwrites, :uint64,
45
+ :f_asyncwrites, :uint64,
46
+ :f_syncreads, :uint64,
47
+ :f_asyncreads, :uint64,
48
+ :f_spare, [:uint64, 10],
49
+ :f_namemax, :uint32,
50
+ :f_owner, :int32,
51
+ :f_fsid, [:int32, 2],
52
+ :f_charspare, [:char, 80],
53
+ :f_fstypename, [:char, 16],
54
+ :f_mntfromname, [:char, MNAMELEN],
55
+ :f_mntonname, [:char, MNAMELEN]
68
56
  )
57
+ when /linux/i
58
+ if linux64?
59
+ layout(
60
+ :f_type, :ulong,
61
+ :f_bsize, :ulong,
62
+ :f_blocks, :uint64,
63
+ :f_bfree, :uint64,
64
+ :f_bavail, :uint64,
65
+ :f_files, :uint64,
66
+ :f_ffree, :uint64,
67
+ :f_fsid, [:int, 2],
68
+ :f_namelen, :ulong,
69
+ :f_frsize, :ulong,
70
+ :f_flags, :ulong,
71
+ :f_spare, [:ulong, 4]
72
+ )
73
+ else
74
+ layout(
75
+ :f_type, :ulong,
76
+ :f_bsize, :ulong,
77
+ :f_blocks, :uint32,
78
+ :f_bfree, :uint32,
79
+ :f_bavail, :uint32,
80
+ :f_files, :uint32,
81
+ :f_ffree, :uint32,
82
+ :f_fsid, [:int, 2],
83
+ :f_namelen, :ulong,
84
+ :f_frsize, :ulong,
85
+ :f_flags, :ulong,
86
+ :f_spare, [:ulong, 4]
87
+ )
88
+ end
69
89
  else
70
90
  layout(
71
- :f_type, :ulong,
72
- :f_bsize, :ulong,
73
- :f_blocks, :uint32,
74
- :f_bfree, :uint32,
75
- :f_bavail, :uint32,
76
- :f_files, :uint32,
77
- :f_ffree, :uint32,
78
- :f_fsid, [:int, 2],
79
- :f_namelen, :ulong,
80
- :f_frsize, :ulong,
81
- :f_flags, :ulong,
82
- :f_spare, [:ulong, 4]
91
+ :f_bsize, :uint32,
92
+ :f_iosize, :int32,
93
+ :f_blocks, :uint64,
94
+ :f_bfree, :uint64,
95
+ :f_bavail, :uint64,
96
+ :f_files, :uint64,
97
+ :f_ffree, :uint64,
98
+ :f_fsid, [:int32, 2],
99
+ :f_owner, :int32,
100
+ :f_type, :uint32,
101
+ :f_flags, :uint32,
102
+ :f_fssubtype, :uint32,
103
+ :f_fstypename, [:char, 16],
104
+ :f_mntonname, [:char, 1024],
105
+ :f_mntfromname, [:char, 1024],
106
+ :f_reserved, [:uint32, 8]
83
107
  )
84
- end
85
- else
86
- layout(
87
- :f_bsize, :uint32,
88
- :f_iosize, :int32,
89
- :f_blocks, :uint64,
90
- :f_bfree, :uint64,
91
- :f_bavail, :uint64,
92
- :f_files, :uint64,
93
- :f_ffree, :uint64,
94
- :f_fsid, [:int32, 2],
95
- :f_owner, :int32,
96
- :f_type, :uint32,
97
- :f_flags, :uint32,
98
- :f_fssubtype, :uint32,
99
- :f_fstypename, [:char, 16],
100
- :f_mntonname, [:char, 1024],
101
- :f_mntfromname, [:char, 1024],
102
- :f_reserved, [:uint32, 8]
103
- )
104
108
  end
105
109
  end
106
110
 
107
111
  # The Statvfs struct represents struct statvfs from sys/statvfs.h.
108
112
  class Statvfs < FFI::Struct
113
+ # Private method that will determine the layout of the struct on Linux.
114
+ def self.linux64?
115
+ if RUBY_PLATFORM == 'java'
116
+ ENV_JAVA['sun.arch.data.model'].to_i == 64
117
+ else
118
+ RbConfig::CONFIG['host_os'] =~ /linux/i &&
119
+ (RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
120
+ end
121
+ end
122
+
109
123
  if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i
110
124
  layout(
111
125
  :f_bsize, :ulong,
@@ -151,7 +165,7 @@ module Sys
151
165
  :f_fstr, [:char, 32],
152
166
  :f_filler, [:ulong, 16]
153
167
  )
154
- elsif RbConfig::CONFIG['host'] =~ /i686/i
168
+ elsif !linux64?
155
169
  layout(
156
170
  :f_bsize, :ulong,
157
171
  :f_frsize, :ulong,
@@ -224,7 +224,7 @@ module Sys
224
224
  fs = Statvfs.new
225
225
 
226
226
  if statvfs(path, fs) < 0
227
- raise Error, 'statvfs() function failed: ' + strerror(FFI.errno)
227
+ raise Error, "statvfs() function failed: #{strerror(FFI.errno)}"
228
228
  end
229
229
 
230
230
  obj = Sys::Filesystem::Stat.new
@@ -275,7 +275,7 @@ module Sys
275
275
  num = getmntinfo(buf, 2)
276
276
 
277
277
  if num == 0
278
- raise Error, 'getmntinfo() function failed: ' + strerror(FFI.errno)
278
+ raise Error, "getmntinfo() function failed: #{strerror(FFI.errno)}"
279
279
  end
280
280
 
281
281
  ptr = buf.get_pointer(0)
@@ -419,7 +419,7 @@ module Sys
419
419
  #
420
420
  def self.mount(source, target, fstype = 'ext2', flags = 0, data = nil)
421
421
  if mount_c(source, target, fstype, flags, data) != 0
422
- raise Error, 'mount() function failed: ' + strerror(FFI.errno)
422
+ raise Error, "mount() function failed: #{strerror(FFI.errno)}"
423
423
  end
424
424
 
425
425
  self
@@ -2,6 +2,7 @@ require 'ffi'
2
2
 
3
3
  module Sys
4
4
  class Filesystem
5
+ # Wrapper module for Windows related FFI functions.
5
6
  module Functions
6
7
  extend FFI::Library
7
8
  ffi_lib :kernel32
@@ -1,6 +1,9 @@
1
+ # Reopen core Ruby classes here and add some custom methods.
1
2
  class String
2
3
  # Convenience method for converting strings to UTF-16LE for wide character
3
4
  # functions that require it.
5
+ #--
6
+ # TODO: Use a refinement.
4
7
  def wincode
5
8
  (tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
6
9
  end
@@ -9,7 +9,6 @@ require 'time'
9
9
 
10
10
  # The Sys module serves as a namespace only.
11
11
  module Sys
12
-
13
12
  # The Filesystem class encapsulates information about your filesystem.
14
13
  class Filesystem
15
14
  include Sys::Filesystem::Constants
@@ -20,6 +19,7 @@ module Sys
20
19
 
21
20
  private_class_method :new
22
21
 
22
+ # Mount objects are returned by the Sys::Filesystem.mounts method.
23
23
  class Mount
24
24
  # The name of the volume. This is the device mapping.
25
25
  attr_reader :name
@@ -50,6 +50,7 @@ module Sys
50
50
  alias freq frequency
51
51
  end
52
52
 
53
+ # Stat objects are returned by the Sys::Filesystem.stat method.
53
54
  class Stat
54
55
  # The path of the file system.
55
56
  attr_reader :path
@@ -160,6 +161,8 @@ module Sys
160
161
  #--
161
162
  # I couldn't really find a good reason to use the wide functions for this
162
163
  # method. If you have one, patches welcome.
164
+ #--
165
+ # rubocop:disable Metrics/BlockLength
163
166
  #
164
167
  def self.mounts
165
168
  # First call, get needed buffer size
@@ -196,14 +199,14 @@ module Sys
196
199
  filesystem_flags = FFI::MemoryPointer.new(:ulong)
197
200
 
198
201
  bool = GetVolumeInformationA(
199
- drive,
200
- volume,
201
- volume.size,
202
- volume_serial_number,
203
- max_component_length,
204
- filesystem_flags,
205
- fsname,
206
- fsname.size
202
+ drive,
203
+ volume,
204
+ volume.size,
205
+ volume_serial_number,
206
+ max_component_length,
207
+ filesystem_flags,
208
+ fsname,
209
+ fsname.size
207
210
  )
208
211
 
209
212
  # Skip unmounted floppies or cd-roms, or inaccessible drives
@@ -237,6 +240,7 @@ module Sys
237
240
 
238
241
  mounts # Nil if the block form was used.
239
242
  end
243
+ # rubocop:enable Metrics/BlockLength
240
244
 
241
245
  # Returns the mount point for the given +file+. For MS Windows this
242
246
  # means the root of the path.
@@ -250,8 +254,6 @@ module Sys
250
254
 
251
255
  if PathStripToRootW(wfile)
252
256
  wfile.read_string(wfile.size).split("\000\000").first.tr(0.chr, '')
253
- else
254
- nil
255
257
  end
256
258
  end
257
259
 
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'sys/filesystem'
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec'
4
+ require 'sys_filesystem_shared'
2
5
 
3
6
  RSpec.configure do |config|
7
+ config.include_context(Sys::Filesystem)
4
8
  config.filter_run_excluding(:windows) unless Gem.win_platform?
5
9
  config.filter_run_excluding(:unix) if Gem.win_platform?
6
10
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sys-filesystem'
4
+
5
+ RSpec.shared_examples Sys::Filesystem do
6
+ example 'version number is set to the expected value' do
7
+ expect(Sys::Filesystem::VERSION).to eq('1.4.5')
8
+ expect(Sys::Filesystem::VERSION).to be_frozen
9
+ end
10
+
11
+ example 'you cannot instantiate an instance' do
12
+ expect{ described_class.new }.to raise_error(NoMethodError)
13
+ end
14
+ end