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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +8 -0
- data/Rakefile +13 -0
- data/lib/sys/filesystem.rb +17 -16
- data/lib/sys/unix/sys/filesystem/constants.rb +2 -0
- data/lib/sys/unix/sys/filesystem/functions.rb +15 -5
- data/lib/sys/unix/sys/filesystem/structs.rb +84 -70
- data/lib/sys/unix/sys/filesystem.rb +3 -3
- data/lib/sys/windows/sys/filesystem/functions.rb +1 -0
- data/lib/sys/windows/sys/filesystem/helper.rb +3 -0
- data/lib/sys/windows/sys/filesystem.rb +13 -11
- data/lib/sys-filesystem.rb +2 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/sys_filesystem_shared.rb +14 -0
- data/spec/sys_filesystem_unix_spec.rb +240 -124
- data/spec/sys_filesystem_windows_spec.rb +263 -151
- data/sys-filesystem.gemspec +15 -7
- data.tar.gz.sig +0 -0
- metadata +34 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 867cb33509a3fa99a58dbf3e0ee69107470a3cecebe4efc2346f49ec1dc1cea6
|
4
|
+
data.tar.gz: 9b1de11209f227d00584c021323b3de75db44e399823941bbad5bf9dd407cab2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/lib/sys/filesystem.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
|
-
|
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
|
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
|
-
#
|
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,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
|
-
|
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
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
26
|
+
Regexp.last_match(1).to_f < 12.0 ? 88 : 1024
|
24
27
|
else
|
25
28
|
88
|
26
29
|
end
|
27
30
|
|
28
|
-
|
29
|
-
|
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
|
-
:
|
57
|
-
:
|
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, :
|
41
|
+
:f_bavail, :int64,
|
61
42
|
:f_files, :uint64,
|
62
43
|
:f_ffree, :uint64,
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:f_spare, [:
|
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
|
-
:
|
72
|
-
:
|
73
|
-
:f_blocks, :
|
74
|
-
:f_bfree, :
|
75
|
-
:f_bavail, :
|
76
|
-
:f_files, :
|
77
|
-
:f_ffree, :
|
78
|
-
:f_fsid, [:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:f_flags, :
|
82
|
-
:
|
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
|
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,
|
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,
|
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,
|
422
|
+
raise Error, "mount() function failed: #{strerror(FFI.errno)}"
|
423
423
|
end
|
424
424
|
|
425
425
|
self
|
@@ -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
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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
|
|
data/lib/sys-filesystem.rb
CHANGED
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
|