sys-filesystem 1.5.4 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43744bef5f8edef84a4b282c900460fd5aefb7f2d9650e5259d5b0f8a8fae97a
4
- data.tar.gz: 6eddc2f29fb509209addc117e4a9ad4ff80e64f11cb71b9db54672dfefeba4eb
3
+ metadata.gz: 6f90c58ef7ca15379ff41cffcd50a3686e048df7ae8e8a5ad9426983c79da6bc
4
+ data.tar.gz: 2675f569f9a8460f412e2b58084d8c269f20cac30c0d4b14ca042b72268300c0
5
5
  SHA512:
6
- metadata.gz: 59800ffa5e85934f3cc4f360c6cde04168deb1d9b5790750f8584332d2fba5bdf2c8019d1e05261bd3ac71858c3488c8d80a65c2cf4fc4fb2c6db6e032cf2461
7
- data.tar.gz: 001fb9676236d2916836e4690cfdaa8bfb838328c43e1c31fa07669f3da4bba3e814a35cc55122ca825fd7c22c90e24d8ea385bc3d9c70548363b8cfa4594def
6
+ metadata.gz: 72241a34bb1556a24a6ba84b5dfaba655f61e4bb8dc83793994366260fcac80269f5a8cef091def654f30803478ad75766b667f85a6e352402d6effcc4e4f633
7
+ data.tar.gz: b95d9272c4e6a1afee451e571d1b90c61f17a1e95c707892508348fb78acc02425962b93350ae944675a896cf2da04551f2f95225b8d24ef3c4b9bd27d3ca706
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 1.6.0 - 15-Jun-2026
2
+ * Big refactor for BSD mainly, adds statfs, and zfs related properties if
3
+ you're using ZFS. Also works for Linux on ZFS.
4
+ * Split out constants into platform specific files for easier maintenance.
5
+ * Add MNT_NFS4ACLS constant for FreeBSD.
6
+ * Update mount and umount methods, preferring nmount where supported.
7
+
8
+ ## 1.5.5 - 6-Dec-2025
9
+ * Replaced string concatenation operators with addition assignment operators
10
+ since the current code generates a frozen string warning with Ruby 3.4 and
11
+ later.
12
+ * Updated Rakefile to run specs with warnings enabled.
13
+
1
14
  ## 1.5.4 - 7-Sep-2025
2
15
  * Added a fallback check for 64-bit Linux in case the config info doesn't
3
16
  include "64" anywhere in it. Thanks go to Chris Hofstaedtler for the
data/README.md CHANGED
@@ -81,7 +81,7 @@ Apache-2.0
81
81
 
82
82
  ## Copyright
83
83
 
84
- (C) 2003-2025 Daniel J. Berger
84
+ (C) 2003-2026 Daniel J. Berger
85
85
  All Rights Reserved
86
86
 
87
87
  ## Warranty
data/Rakefile CHANGED
@@ -41,7 +41,7 @@ end
41
41
  desc "Run the test suite"
42
42
  RSpec::Core::RakeTask.new(:spec) do |t|
43
43
  t.verbose = false
44
- t.rspec_opts = '-f documentation'
44
+ t.rspec_opts = '-f documentation -w'
45
45
  end
46
46
 
47
47
  # Clean up afterwards
@@ -16,11 +16,25 @@ module Sys
16
16
  # return objects of other types. Do not instantiate.
17
17
  class Filesystem
18
18
  # The version of the sys-filesystem library
19
- VERSION = '1.5.4'
19
+ VERSION = '1.6.0'
20
20
 
21
21
  # Stat objects are returned by the Sys::Filesystem.stat method. Here
22
22
  # we're adding universal methods.
23
23
  class Stat
24
+ ZFS_PROPERTIES = {
25
+ zfs_atime: 'atime',
26
+ zfs_casesensitivity: 'casesensitivity',
27
+ zfs_compression: 'compression',
28
+ zfs_compressratio: 'compressratio',
29
+ zfs_devices: 'devices',
30
+ zfs_exec: 'exec',
31
+ zfs_quota: 'quota',
32
+ zfs_readonly: 'readonly',
33
+ zfs_recordsize: 'recordsize',
34
+ zfs_reservation: 'reservation',
35
+ zfs_setuid: 'setuid'
36
+ }.freeze
37
+
24
38
  # Returns true if the filesystem is case sensitive for the current path.
25
39
  # Typically this will be any path on MS Windows or Macs using HFS.
26
40
  #
@@ -31,10 +45,15 @@ module Sys
31
45
  def case_insensitive?
32
46
  if path =~ /\w+/
33
47
  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
48
  else
37
- false
49
+ zfs_case = zfs_case_insensitive?
50
+ return zfs_case unless zfs_case.nil?
51
+
52
+ if RbConfig::CONFIG['host_os'] =~ /darwin|mac|windows|mswin|mingw/i
53
+ true # Assumes HFS/APFS on Mac
54
+ else
55
+ false
56
+ end
38
57
  end
39
58
  end
40
59
 
@@ -43,6 +62,57 @@ module Sys
43
62
  def case_sensitive?
44
63
  !case_insensitive?
45
64
  end
65
+
66
+ # Returns a native ZFS property value for this path's dataset.
67
+ # Returns nil if the path is not on ZFS or libzfs is unavailable.
68
+ def zfs_property(property)
69
+ return nil unless base_type == 'zfs'
70
+ return nil unless Sys::Filesystem.respond_to?(:zfs_property, true)
71
+
72
+ dataset = zfs_dataset
73
+ return nil unless dataset
74
+
75
+ Sys::Filesystem.send(:zfs_property, dataset, property.to_s)
76
+ rescue SystemCallError
77
+ nil
78
+ end
79
+
80
+ ZFS_PROPERTIES.each do |method_name, property|
81
+ define_method(method_name) do
82
+ zfs_property(property)
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def zfs_case_insensitive?
89
+ return nil unless base_type == 'zfs'
90
+
91
+ value = zfs_property('casesensitivity')
92
+ return nil unless value
93
+
94
+ case value.strip
95
+ when 'insensitive'
96
+ true
97
+ when 'sensitive'
98
+ false
99
+ else
100
+ nil
101
+ end
102
+ rescue SystemCallError
103
+ nil
104
+ end
105
+
106
+ def zfs_dataset
107
+ return mount_source if respond_to?(:mount_source) && mount_source
108
+
109
+ mount_point = Sys::Filesystem.mount_point(path)
110
+ mount = Sys::Filesystem.mounts.find{ |mnt| mnt.mount_point == mount_point }
111
+
112
+ mount&.name
113
+ rescue SystemCallError
114
+ nil
115
+ end
46
116
  end
47
117
  end
48
118
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sys
4
+ class Filesystem
5
+ module Constants
6
+ MNT_RDONLY = 0x00000001 # read only filesystem
7
+ MNT_SYNCHRONOUS = 0x00000002 # file system written synchronously
8
+ MNT_NOEXEC = 0x00000004 # can't exec from filesystem
9
+ MNT_NOSUID = 0x00000008 # don't honor setuid bits on fs
10
+ MNT_UNION = 0x00000020 # union with underlying filesystem
11
+ MNT_ASYNC = 0x00000040 # file system written asynchronously
12
+ MNT_EXPORTED = 0x00000100 # filesystem is exported
13
+ MNT_LOCAL = 0x00001000 # filesystem is stored locally
14
+ MNT_QUOTA = 0x00002000 # quotas are enabled on filesystem
15
+ MNT_ROOTFS = 0x00004000 # identifies the root filesystem
16
+ MNT_NOATIME = 0x10000000 # disable update of file access time
17
+
18
+ MNT_VISFLAGMASK = (
19
+ MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC |
20
+ MNT_NOSUID | MNT_UNION | MNT_ASYNC |
21
+ MNT_EXPORTED | MNT_LOCAL | MNT_QUOTA |
22
+ MNT_ROOTFS | MNT_NOATIME
23
+ )
24
+
25
+ MNT_FORCE = 1
26
+
27
+ MOUNT_OPTION_NAMES = {
28
+ MNT_RDONLY => 'read-only',
29
+ MNT_SYNCHRONOUS => 'synchronous',
30
+ MNT_NOEXEC => 'noexec',
31
+ MNT_NOSUID => 'nosuid',
32
+ MNT_UNION => 'union',
33
+ MNT_ASYNC => 'asynchronous',
34
+ MNT_EXPORTED => 'exported',
35
+ MNT_LOCAL => 'local',
36
+ MNT_QUOTA => 'quotas',
37
+ MNT_ROOTFS => 'rootfs',
38
+ MNT_NOATIME => 'noatime'
39
+ }.freeze
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sys
4
+ class Filesystem
5
+ module Constants
6
+ MNT_RDONLY = 0x00000001 # read only filesystem
7
+ MNT_SYNCHRONOUS = 0x00000002 # file system written synchronously
8
+ MNT_NOEXEC = 0x00000004 # can't exec from filesystem
9
+ MNT_NOSUID = 0x00000008 # don't honor setuid bits on fs
10
+ MNT_NODEV = 0x00000010 # don't interpret special files
11
+ MNT_UNION = 0x00000020 # union with underlying filesystem
12
+ MNT_ASYNC = 0x00000040 # file system written asynchronously
13
+ MNT_CPROTECT = 0x00000080 # file system supports content protection
14
+ MNT_EXPORTED = 0x00000100 # file system is exported
15
+ MNT_QUARANTINE = 0x00000400 # file system is quarantined
16
+ MNT_LOCAL = 0x00001000 # filesystem is stored locally
17
+ MNT_QUOTA = 0x00002000 # quotas are enabled on filesystem
18
+ MNT_ROOTFS = 0x00004000 # identifies the root filesystem
19
+ MNT_DOVOLFS = 0x00008000 # FS supports volfs (deprecated)
20
+ MNT_DONTBROWSE = 0x00100000 # FS is not appropriate path to user data
21
+ MNT_IGNORE_OWNERSHIP = 0x00200000 # VFS will ignore ownership info on FS objects
22
+ MNT_AUTOMOUNTED = 0x00400000 # filesystem was mounted by automounter
23
+ MNT_JOURNALED = 0x00800000 # filesystem is journaled
24
+ MNT_NOUSERXATTR = 0x01000000 # Don't allow user extended attributes
25
+ MNT_DEFWRITE = 0x02000000 # filesystem should defer writes
26
+ MNT_MULTILABEL = 0x04000000 # MAC support for individual labels
27
+ MNT_NOATIME = 0x10000000 # disable update of file access time
28
+ MNT_NOCLUSTERR = 0x40000000 # disable cluster read
29
+ MNT_NOCLUSTERW = 0x80000000 # disable cluster write
30
+
31
+ MNT_VISFLAGMASK = (
32
+ MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC |
33
+ MNT_NOSUID | MNT_NODEV | MNT_UNION |
34
+ MNT_ASYNC | MNT_EXPORTED | MNT_QUARANTINE |
35
+ MNT_LOCAL | MNT_QUOTA |
36
+ MNT_ROOTFS | MNT_DOVOLFS | MNT_DONTBROWSE |
37
+ MNT_IGNORE_OWNERSHIP | MNT_AUTOMOUNTED | MNT_JOURNALED |
38
+ MNT_NOUSERXATTR | MNT_DEFWRITE | MNT_MULTILABEL |
39
+ MNT_NOATIME | MNT_CPROTECT
40
+ )
41
+
42
+ MNT_FORCE = 1
43
+
44
+ MOUNT_OPTION_NAMES = {
45
+ MNT_RDONLY => 'read-only',
46
+ MNT_SYNCHRONOUS => 'synchronous',
47
+ MNT_NOEXEC => 'noexec',
48
+ MNT_NOSUID => 'nosuid',
49
+ MNT_NODEV => 'nodev',
50
+ MNT_UNION => 'union',
51
+ MNT_ASYNC => 'asynchronous',
52
+ MNT_CPROTECT => 'content-protection',
53
+ MNT_EXPORTED => 'exported',
54
+ MNT_QUARANTINE => 'quarantined',
55
+ MNT_LOCAL => 'local',
56
+ MNT_QUOTA => 'quotas',
57
+ MNT_ROOTFS => 'rootfs',
58
+ MNT_DONTBROWSE => 'nobrowse',
59
+ MNT_IGNORE_OWNERSHIP => 'noowners',
60
+ MNT_AUTOMOUNTED => 'automounted',
61
+ MNT_JOURNALED => 'journaled',
62
+ MNT_NOUSERXATTR => 'nouserxattr',
63
+ MNT_DEFWRITE => 'defwrite',
64
+ MNT_NOATIME => 'noatime'
65
+ }.freeze
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'bsd'
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sys
4
+ class Filesystem
5
+ module Constants
6
+ MNT_RDONLY = 0x0000000000000001 # read only filesystem
7
+ MNT_SYNCHRONOUS = 0x0000000000000002 # file system written synchronously
8
+ MNT_NOEXEC = 0x0000000000000004 # can't exec from filesystem
9
+ MNT_NOSUID = 0x0000000000000008 # don't honor setuid bits on fs
10
+ MNT_NFS4ACLS = 0x0000000000000010 # enable NFS version 4 ACLs
11
+ MNT_UNION = 0x0000000000000020 # union with underlying filesystem
12
+ MNT_ASYNC = 0x0000000000000040 # file system written asynchronously
13
+ MNT_EXRDONLY = 0x0000000000000080 # exported read only
14
+ MNT_EXPORTED = 0x0000000000000100 # filesystem is exported
15
+ MNT_DEFEXPORTED = 0x0000000000000200 # exported to the world
16
+ MNT_EXPORTANON = 0x0000000000000400 # anon uid mapping for all
17
+ MNT_EXKERB = 0x0000000000000800 # exported with Kerberos
18
+ MNT_LOCAL = 0x0000000000001000 # filesystem is stored locally
19
+ MNT_QUOTA = 0x0000000000002000 # quotas are enabled on filesystem
20
+ MNT_ROOTFS = 0x0000000000004000 # identifies the root filesystem
21
+ MNT_USER = 0x0000000000008000 # mounted by a user
22
+ MNT_SUIDDIR = 0x0000000000100000 # special SUID dir handling
23
+ MNT_SOFTDEP = 0x0000000000200000 # using soft updates
24
+ MNT_NOSYMFOLLOW = 0x0000000000400000 # do not follow symlinks
25
+ MNT_IGNORE = 0x0000000000800000 # do not show entry in df
26
+ MNT_GJOURNAL = 0x0000000002000000 # GEOM journal support enabled
27
+ MNT_MULTILABEL = 0x0000000004000000 # MAC support for objects
28
+ MNT_ACLS = 0x0000000008000000 # ACL support enabled
29
+ MNT_NOATIME = 0x0000000010000000 # disable update of file access time
30
+ MNT_EXPUBLIC = 0x0000000020000000 # public export (WebNFS)
31
+ MNT_NOCLUSTERR = 0x0000000040000000 # disable cluster read
32
+ MNT_NOCLUSTERW = 0x0000000080000000 # disable cluster write
33
+ MNT_SUJ = 0x0000000100000000 # using journaled soft updates
34
+ MNT_AUTOMOUNTED = 0x0000000200000000 # filesystem was mounted by automounter
35
+ MNT_VERIFIED = 0x0000000400000000 # filesystem is verified
36
+ MNT_UNTRUSTED = 0x0000000800000000 # filesystem metadata is untrusted
37
+ MNT_NAMEDATTR = 0x0000020000000000 # named attributes enabled
38
+
39
+ MNT_VISFLAGMASK = (
40
+ MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC |
41
+ MNT_NOSUID | MNT_NFS4ACLS | MNT_UNION |
42
+ MNT_ASYNC | MNT_EXRDONLY | MNT_EXPORTED |
43
+ MNT_DEFEXPORTED | MNT_EXPORTANON | MNT_EXKERB |
44
+ MNT_LOCAL | MNT_USER | MNT_QUOTA |
45
+ MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR |
46
+ MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP |
47
+ MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW |
48
+ MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS |
49
+ MNT_NFS4ACLS | MNT_AUTOMOUNTED | MNT_VERIFIED |
50
+ MNT_UNTRUSTED | MNT_NAMEDATTR
51
+ )
52
+
53
+ MNT_UPDATE = 0x0000000000010000
54
+ MNT_DELEXPORT = 0x0000000000020000
55
+ MNT_RELOAD = 0x0000000000040000
56
+ MNT_FORCE = 0x0000000000080000
57
+ MNT_SNAPSHOT = 0x0000000001000000
58
+ MNT_NONBUSY = 0x0000000004000000
59
+ MNT_BYFSID = 0x0000000008000000
60
+ MNT_NOCOVER = 0x0000001000000000
61
+ MNT_EMPTYDIR = 0x0000002000000000
62
+ MNT_RECURSE = 0x0000100000000000
63
+ MNT_DEFERRED = 0x0000200000000000
64
+
65
+ MOUNT_OPTION_NAMES = {
66
+ MNT_RDONLY => 'read-only',
67
+ MNT_SYNCHRONOUS => 'synchronous',
68
+ MNT_NOEXEC => 'noexec',
69
+ MNT_NOSUID => 'nosuid',
70
+ MNT_NFS4ACLS => 'nfsv4acls',
71
+ MNT_UNION => 'union',
72
+ MNT_ASYNC => 'asynchronous',
73
+ MNT_EXRDONLY => 'exported-read-only',
74
+ MNT_EXPORTED => 'exported',
75
+ MNT_DEFEXPORTED => 'defexported',
76
+ MNT_EXPORTANON => 'exportanon',
77
+ MNT_EXKERB => 'exkerb',
78
+ MNT_LOCAL => 'local',
79
+ MNT_USER => 'user',
80
+ MNT_QUOTA => 'quotas',
81
+ MNT_ROOTFS => 'rootfs',
82
+ MNT_NOATIME => 'noatime',
83
+ MNT_NOCLUSTERR => 'noclusterr',
84
+ MNT_NOCLUSTERW => 'noclusterw',
85
+ MNT_SUIDDIR => 'suiddir',
86
+ MNT_SOFTDEP => 'soft-updates',
87
+ MNT_IGNORE => 'ignore',
88
+ MNT_EXPUBLIC => 'public',
89
+ MNT_NOSYMFOLLOW => 'nosymfollow',
90
+ MNT_GJOURNAL => 'gjournal',
91
+ MNT_MULTILABEL => 'multilabel',
92
+ MNT_ACLS => 'acls',
93
+ MNT_AUTOMOUNTED => 'automounted',
94
+ MNT_VERIFIED => 'verified',
95
+ MNT_UNTRUSTED => 'untrusted',
96
+ MNT_NAMEDATTR => 'namedattr'
97
+ }.freeze
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sys
4
+ class Filesystem
5
+ module Constants
6
+ MNT_RDONLY = 0x00000001
7
+ MNT_NOSUID = 0x00000002
8
+
9
+ MNT_VISFLAGMASK = MNT_RDONLY | MNT_NOSUID
10
+
11
+ MNT_FORCE = 1
12
+
13
+ MOUNT_OPTION_NAMES = {
14
+ MNT_RDONLY => 'read-only',
15
+ MNT_NOSUID => 'nosuid'
16
+ }.freeze
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sys
4
+ class Filesystem
5
+ module Constants
6
+ MS_RDONLY = 1
7
+ MS_NOSUID = 2
8
+ MS_NODEV = 4
9
+ MS_NOEXEC = 8
10
+ MS_SYNCHRONOUS = 16
11
+ MS_REMOUNT = 32
12
+ MS_MANDLOCK = 64
13
+ MS_DIRSYNC = 128
14
+ MS_NOATIME = 1024
15
+ MS_NODIRATIME = 2048
16
+ MS_BIND = 4096
17
+ MS_MOVE = 8192
18
+ MS_REC = 16_384
19
+ MS_SILENT = 32_768
20
+ MS_POSIXACL = 1 << 16
21
+ MS_UNBINDABLE = 1 << 17
22
+ MS_PRIVATE = 1 << 18
23
+ MS_SLAVE = 1 << 19
24
+ MS_SHARED = 1 << 20
25
+ MS_RELATIME = 1 << 21
26
+ MS_KERNMOUNT = 1 << 22
27
+ MS_I_VERSION = 1 << 23
28
+ MS_STRICTATIME = 1 << 24
29
+ MS_ACTIVE = 1 << 30
30
+ MS_NOUSER = 1 << 31
31
+
32
+ MNT_RDONLY = MS_RDONLY
33
+ MNT_NOSUID = MS_NOSUID
34
+ MNT_NODEV = MS_NODEV
35
+ MNT_NOEXEC = MS_NOEXEC
36
+
37
+ MNT_FORCE = 1
38
+ MNT_DETACH = 2
39
+ MNT_EXPIRE = 4
40
+ UMOUNT_NOFOLLOW = 8
41
+ end
42
+ end
43
+ end
@@ -1,74 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sys
4
- class Filesystem
5
- module Constants
6
- MNT_RDONLY = 0x00000001 # read only filesystem
7
- MNT_SYNCHRONOUS = 0x00000002 # file system written synchronously
8
- MNT_NOEXEC = 0x00000004 # can't exec from filesystem
9
- MNT_NOSUID = 0x00000008 # don't honor setuid bits on fs
10
- MNT_NODEV = 0x00000010 # don't interpret special files
11
- MNT_UNION = 0x00000020 # union with underlying filesystem
12
- MNT_ASYNC = 0x00000040 # file system written asynchronously
13
- MNT_CPROTECT = 0x00000080 # file system supports content protection
14
- MNT_EXPORTED = 0x00000100 # file system is exported
15
- MNT_QUARANTINE = 0x00000400 # file system is quarantined
16
- MNT_LOCAL = 0x00001000 # filesystem is stored locally
17
- MNT_QUOTA = 0x00002000 # quotas are enabled on filesystem
18
- MNT_ROOTFS = 0x00004000 # identifies the root filesystem
19
- MNT_DOVOLFS = 0x00008000 # FS supports volfs (deprecated)
20
- MNT_DONTBROWSE = 0x00100000 # FS is not appropriate path to user data
21
- MNT_IGNORE_OWNERSHIP = 0x00200000 # VFS will ignore ownership info on FS objects
22
- MNT_AUTOMOUNTED = 0x00400000 # filesystem was mounted by automounter
23
- MNT_JOURNALED = 0x00800000 # filesystem is journaled
24
- MNT_NOUSERXATTR = 0x01000000 # Don't allow user extended attributes
25
- MNT_DEFWRITE = 0x02000000 # filesystem should defer writes
26
- MNT_MULTILABEL = 0x04000000 # MAC support for individual labels
27
- MNT_NOATIME = 0x10000000 # disable update of file access time
28
- MNT_NOCLUSTERR = 0x40000000 # disable cluster read
29
- MNT_NOCLUSTERW = 0x80000000 # disable cluster write
3
+ require 'rbconfig'
30
4
 
31
- MNT_VISFLAGMASK = (
32
- MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC |
33
- MNT_NOSUID | MNT_NODEV | MNT_UNION |
34
- MNT_ASYNC | MNT_EXPORTED | MNT_QUARANTINE |
35
- MNT_LOCAL | MNT_QUOTA |
36
- MNT_ROOTFS | MNT_DOVOLFS | MNT_DONTBROWSE |
37
- MNT_IGNORE_OWNERSHIP | MNT_AUTOMOUNTED | MNT_JOURNALED |
38
- MNT_NOUSERXATTR | MNT_DEFWRITE | MNT_MULTILABEL |
39
- MNT_NOATIME | MNT_CPROTECT
40
- )
41
-
42
- MS_RDONLY = 1
43
- MS_NOSUID = 2
44
- MS_NODEV = 4
45
- MS_NOEXEC = 8
46
- MS_SYNCHRONOUS = 16
47
- MS_REMOUNT = 32
48
- MS_MANDLOCK = 64
49
- MS_DIRSYNC = 128
50
- MS_NOATIME = 1024
51
- MS_NODIRATIME = 2048
52
- MS_BIND = 4096
53
- MS_MOVE = 8192
54
- MS_REC = 16384
55
- MS_SILENT = 32768
56
- MS_POSIXACL = 1 << 16
57
- MS_UNBINDABLE = 1 << 17
58
- MS_PRIVATE = 1 << 18
59
- MS_SLAVE = 1 << 19
60
- MS_SHARED = 1 << 20
61
- MS_RELATIME = 1 << 21
62
- MS_KERNMOUNT = 1 << 22
63
- MS_I_VERSION = 1 << 23
64
- MS_STRICTATIME = 1 << 24
65
- MS_ACTIVE = 1 << 30
66
- MS_NOUSER = 1 << 31
67
-
68
- MNT_FORCE = 1
69
- MNT_DETACH = 2
70
- MNT_EXPIRE = 4
71
- UMOUNT_NOFOLLOW = 8
72
- end
73
- end
5
+ case RbConfig::CONFIG['host_os']
6
+ when /linux/i
7
+ require_relative 'constants/linux'
8
+ when /freebsd/i
9
+ require_relative 'constants/freebsd'
10
+ when /darwin|osx|mach/i
11
+ require_relative 'constants/darwin'
12
+ when /dragonfly/i
13
+ require_relative 'constants/dragonfly'
14
+ else
15
+ require_relative 'constants/generic'
74
16
  end
@@ -20,7 +20,12 @@ module Sys
20
20
  end
21
21
  end
22
22
 
23
+ def self.zfs_supported?
24
+ !!(RbConfig::CONFIG['host_os'] =~ /freebsd|linux/i)
25
+ end
26
+
23
27
  private_class_method :linux64?
28
+ private_class_method :zfs_supported?
24
29
 
25
30
  if linux64?
26
31
  begin
@@ -32,8 +37,40 @@ module Sys
32
37
  attach_function(:statvfs, %i[string pointer], :int)
33
38
  end
34
39
 
40
+ if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach|bsd|dragonfly/i
41
+ attach_function(:statfs, %i[string pointer], :int)
42
+ end
43
+
35
44
  attach_function(:strerror, [:int], :string)
36
- attach_function(:mount_c, :mount, %i[string string string ulong string], :int)
45
+
46
+ if RbConfig::CONFIG['host_os'] =~ /linux/i
47
+ attach_function(:mount_c, :mount, %i[string string string ulong string], :int)
48
+ else
49
+ attach_function(:mount_c, :mount, %i[string string int pointer], :int)
50
+ end
51
+
52
+ if RbConfig::CONFIG['host_os'] =~ /freebsd/i
53
+ attach_function(:nmount_c, :nmount, %i[pointer uint int], :int)
54
+ end
55
+
56
+ if zfs_supported?
57
+ begin
58
+ ffi_lib FFI::Library::LIBC, 'zfs'
59
+
60
+ attach_function(:libzfs_init, [], :pointer)
61
+ attach_function(:libzfs_fini, [:pointer], :void)
62
+ attach_function(:zfs_open, %i[pointer string int], :pointer)
63
+ attach_function(:zfs_close, [:pointer], :void)
64
+ attach_function(:zfs_name_to_prop, [:string], :int)
65
+ attach_function(
66
+ :zfs_prop_get,
67
+ %i[pointer int pointer size_t pointer pointer size_t int],
68
+ :int
69
+ )
70
+ rescue FFI::NotFoundError, LoadError
71
+ # libzfs is optional. ZFS-specific helpers fall back when unavailable.
72
+ end
73
+ end
37
74
 
38
75
  if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach|bsd|dragonfly/i
39
76
  attach_function(:umount_c, :unmount, %i[string int], :int)
@@ -42,6 +79,18 @@ module Sys
42
79
  end
43
80
 
44
81
  private_class_method :statvfs, :strerror, :mount_c, :umount_c
82
+ private_class_method :statfs if method_defined?(:statfs)
83
+ private_class_method :nmount_c if method_defined?(:nmount_c)
84
+ if method_defined?(:libzfs_init)
85
+ private_class_method(
86
+ :libzfs_init,
87
+ :libzfs_fini,
88
+ :zfs_open,
89
+ :zfs_close,
90
+ :zfs_name_to_prop,
91
+ :zfs_prop_get
92
+ )
93
+ end
45
94
 
46
95
  begin
47
96
  attach_function(:getmntent, [:pointer], :pointer)
@@ -256,6 +256,14 @@ module Sys
256
256
  :mnt_passno, :int
257
257
  )
258
258
  end
259
+
260
+ # The Iovec struct is used by FreeBSD's nmount(2).
261
+ class Iovec < FFI::Struct
262
+ layout(
263
+ :iov_base, :pointer,
264
+ :iov_len, :size_t
265
+ )
266
+ end
259
267
  end
260
268
  end
261
269
  end