ffi-libfuse 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,43 +1,91 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../accessors'
4
+ require_relative '../boolean_int'
4
5
 
5
6
  module FFI
6
7
  module Libfuse
7
- # struct fuse_loop_config {
8
- # int clone_fd;
9
- # unsigned int max_idle_threads;
10
- # };
8
+ # For native fuse_loop_mt only
11
9
  class FuseLoopConfig < FFI::Struct
12
10
  include(FFI::Accessors)
13
11
 
14
- layout(
15
- clone_fd: :int,
16
- max_idle: :int
17
- )
18
-
19
- # @!attribute [rw] clone_fd
12
+ # @!attribute [w] clone_fd?
20
13
  # whether to use separate device fds for each thread (may increase performance)
21
14
  # Unused by ffi-libfuse as we do not call fuse_loop_mt
22
15
  # @return [Boolean]
23
- ffi_attr_reader(:clone_fd) do |v|
24
- v != 0
25
- end
26
-
27
- ffi_attr_writer(:clone_fd) do |v|
28
- v ? 1 : 0
29
- end
30
16
 
31
- # @!attribute [rw] max_idle_threads
17
+ # @!attribute [w] max_idle_threads
32
18
  # The maximum number of available worker threads before they start to get deleted when they become idle. If not
33
19
  # specified, the default is 10.
34
20
  #
35
21
  # Adjusting this has performance implications; a very small number of threads in the pool will cause a lot of
36
22
  # thread creation and deletion overhead and performance may suffer. When set to 0, a new thread will be created
37
23
  # to service every operation.
38
- #
24
+ # @deprecated at Fuse 3.12. Use max_threads instead
39
25
  # @return [Integer] the maximum number of threads to leave idle
40
- ffi_attr_accessor(:max_idle)
26
+
27
+ # @!attribute [w] max_threads
28
+ # @return [Integer]
29
+ # @since Fuse 3.12
30
+
31
+ if FUSE_VERSION >= 312
32
+ layout(
33
+ version_id: :int,
34
+ clone_fd: :bool_int,
35
+ max_idle_threads: :uint,
36
+ max_threads: :uint
37
+ )
38
+
39
+ Libfuse.attach_function :fuse_loop_cfg_create, [], by_ref
40
+ Libfuse.attach_function :fuse_loop_cfg_destroy, [:pointer], :void
41
+
42
+ ffi_attr_reader(:clone_fd?)
43
+ Libfuse.attach_function :fuse_loop_cfg_set_clone_fd, %i[pointer uint], :void
44
+ def clone_fd=(bool_val)
45
+ Libfuse.fuse_loop_cfg_set_clone_fd(to_ptr, bool_val ? 1 : 0)
46
+ end
47
+
48
+ ffi_attr_reader(:max_idle_threads)
49
+ Libfuse.attach_function :fuse_loop_cfg_set_idle_threads, %i[pointer uint], :uint
50
+ def max_idle_threads=(val)
51
+ Libfuse.fuse_loop_cfg_set_idle_threads(to_ptr, val) if val
52
+ end
53
+
54
+ Libfuse.attach_function :fuse_loop_cfg_set_max_threads, %i[pointer uint], :uint
55
+ ffi_attr_reader(:max_threads)
56
+ def max_threads=(val)
57
+ Libfuse.fuse_loop_cfg_set_max_threads(to_ptr, val) if val
58
+ end
59
+
60
+ class << self
61
+ def create(max_idle_threads: nil, max_threads: 10, clone_fd: false, **_)
62
+ cfg = Libfuse.fuse_loop_cfg_create
63
+ ObjectSpace.define_finalizer(cfg, finalizer(cfg.to_ptr))
64
+ cfg.clone_fd = clone_fd
65
+ cfg.max_idle_threads = max_idle_threads if max_idle_threads
66
+ cfg.max_threads = max_threads if max_threads
67
+ cfg
68
+ end
69
+
70
+ def finalizer(ptr)
71
+ proc { |_| Libfuse.fuse_loop_cfg_destroy(ptr) }
72
+ end
73
+ end
74
+ else
75
+ layout(
76
+ clone_fd: :bool_int,
77
+ max_idle_threads: :uint
78
+ )
79
+
80
+ ffi_attr_accessor(:clone_fd?)
81
+ ffi_attr_accessor(:max_idle_threads)
82
+
83
+ class << self
84
+ def create(clone_fd: false, max_idle_threads: 10, **_)
85
+ new.fill(max_idle_threads: max_idle_threads, clone_fd: clone_fd)
86
+ end
87
+ end
88
+ end
41
89
  end
42
90
  end
43
91
  end
@@ -189,12 +189,16 @@ module FFI
189
189
  # @!method fuse_traps
190
190
  # @abstract
191
191
  # Passed to {FuseCommon#run} to allow filesystem to handle custom signal traps. These traps
192
- # are merged over those from {FuseCommon#default_traps}
193
- # @return [Hash<String|Symbol|Integer,String|Proc>]
192
+ # are merged over those from {FuseCommon#default_traps}. A nil value can be used to avoid a default trap
193
+ # being set.
194
+ # @return [Hash<String|Symbol|Integer,String|Proc|nil>]
194
195
  # map of signal name or number to signal handler as per Signal.trap
195
196
  # @example
196
197
  # def fuse_traps
197
- # { HUP: ->() { reload() }}
198
+ # {
199
+ # HUP: ->() { reload() },
200
+ # INT: nil
201
+ # }
198
202
  # end
199
203
 
200
204
  # @!method fuse_version
@@ -73,7 +73,7 @@ module FFI
73
73
  return [o, e, s.exitstatus] unless err
74
74
 
75
75
  warn "Errors\n#{e}" unless e.empty?
76
- warn "Output\n#{o}" unless o.empty? Minitest::Assertion, StandardError => e
76
+ warn "Output\n#{o}" unless o.empty?
77
77
  raise err
78
78
  end
79
79
 
@@ -87,7 +87,7 @@ module FFI
87
87
  if mac_fuse?
88
88
  system("diskutil unmount force #{mnt} >/dev/null 2>&1")
89
89
  else
90
- system("fusermount -zu #{mnt} >/dev/null 2>&1")
90
+ system("fusermount#{FUSE_MAJOR_VERSION == 3 ? '3' : ''} -zu #{mnt} >/dev/null 2>&1")
91
91
  end
92
92
  end
93
93
 
@@ -107,10 +107,8 @@ module FFI
107
107
  private
108
108
 
109
109
  def open3_filesystem(args, env, filesystem, fsname, mnt)
110
- if defined?(Bundler)
111
- Bundler.with_unbundled_env do
112
- Open3.capture3(env, 'bundle', 'exec', filesystem.to_s, mnt, "-ofsname=#{fsname}", *args, binmode: true)
113
- end
110
+ if ENV['BUNDLER_GEMFILE']
111
+ Open3.capture3(env, 'bundle', 'exec', filesystem.to_s, mnt, "-ofsname=#{fsname}", *args, binmode: true)
114
112
  else
115
113
  Open3.capture3(env, filesystem.to_s, mnt, "-ofsname=#{fsname}", *args, binmode: true)
116
114
  end
@@ -3,6 +3,6 @@
3
3
  module FFI
4
4
  # Ruby FFI Binding for [libfuse](https://github.com/libfuse/libfuse)
5
5
  module Libfuse
6
- VERSION = '0.4.0'
6
+ VERSION = '0.4.1'
7
7
  end
8
8
  end
data/lib/ffi/stat.rb CHANGED
@@ -34,9 +34,9 @@ module FFI
34
34
  int_members = Native
35
35
  .members
36
36
  .select { |m| m.to_s.start_with?('st_') && !m.to_s.end_with?('timespec') }
37
- .map { |m| m[3..].to_sym }
37
+ .to_h { |m| [:"#{m[3..]}", m] }
38
38
 
39
- ffi_attr_accessor(*int_members, format: 'st_%s')
39
+ ffi_attr_accessor(**int_members)
40
40
 
41
41
  # @!attribute [rw] atime
42
42
  # @return [Time] time of last access
@@ -47,12 +47,13 @@ module FFI
47
47
  # @!attribute [rw] ctime
48
48
  # @return [Time] time of last status change
49
49
 
50
- time_members = Native.members.select { |m| m.to_s =~ /^st_.*timespec$/ }.map { |m| m[3..-5].to_sym }
50
+ time_members = Native.members.select { |m| m.to_s =~ /^st_.*timespec$/ }.to_h { |m| [:"#{m[3..-5]}", m] }
51
51
 
52
- ffi_attr_reader(*time_members, format: 'st_%sspec', &:time)
52
+ ffi_attr_reader(**time_members, &:time)
53
53
 
54
- ffi_attr_writer(*time_members, format: 'st_%sspec', simple: false) do |sec, nsec = 0|
55
- self[__method__[0..-2].to_sym].set_time(sec, nsec)
54
+ ffi_attr_writer_method(**time_members) do |sec, nsec = 0|
55
+ _attr, member = ffi_attr_writer_member(__method__)
56
+ self[member].set_time(sec, nsec)
56
57
  end
57
58
 
58
59
  # Fill content for a regular file
@@ -164,16 +165,22 @@ module FFI
164
165
  end
165
166
 
166
167
  class << self
167
- # @!method file(stat,**fields)
168
+ # @!method file(**fields)
168
169
  # @return [Stat]
169
170
  # @raise [SystemCallError]
170
171
  # @see Stat#file
171
172
 
172
- # @!method dir(stat,**fields)
173
+ # @!method dir(**fields)
173
174
  # @return [Stat]
174
175
  # @raise [SystemCallError]
175
176
  # @see Stat#dir
176
- %i[file dir].each { |m| define_method(m) { |stat = new, **args| stat.send(m, **args) } }
177
+
178
+ # @!method symlink(**fields)
179
+ # @return [Stat]
180
+ # @raise [SystemCallError]
181
+ # @see Stat#symlink
182
+
183
+ %i[file dir symlink].each { |m| define_method(m) { |stat = new, **args| stat.send(m, **args) } }
177
184
  alias directory dir
178
185
 
179
186
  # @!method from(file, stat = new(), follow: false)
data/lib/ffi/stat_vfs.rb CHANGED
@@ -75,8 +75,7 @@ module FFI
75
75
  # @!attribute [rw] namemax
76
76
  # @return [Integer] Maximum filename length
77
77
 
78
- int_members = members.grep(/^f_/).map { |m| m[2..].to_sym }
79
- ffi_attr_accessor(*int_members, format: 'f_%s')
78
+ ffi_attr_accessor(**members.grep(/^f_/).to_h { |m| [m[2..].to_sym, m] })
80
79
 
81
80
  extend FFI::Library
82
81
  ffi_lib FFI::Library::LIBC
@@ -27,13 +27,13 @@ module FFI
27
27
  return Pointer::NULL if value.nil?
28
28
 
29
29
  value = value.native if value.is_a?(StructWrapper)
30
- super(value, ctx)
30
+ super
31
31
  end
32
32
 
33
33
  def from_native(value, ctx)
34
34
  return nil if value.null?
35
35
 
36
- native = super(value, ctx)
36
+ native = super
37
37
  @wrapper_class.new(native)
38
38
  end
39
39
  end
@@ -100,12 +100,14 @@ module FFI
100
100
 
101
101
  # Get attribute
102
102
  def [](member_or_attr)
103
- @native[self.class.ffi_attr_readers.fetch(member_or_attr, member_or_attr)]
103
+ _attr, member = ffi_attr_reader_member(member_or_attr, member_or_attr)
104
+ @native[member]
104
105
  end
105
106
 
106
107
  # Set attribute
107
108
  def []=(member_or_attr, val)
108
- @native[self.class.ffi_attr_writers.fetch(member_or_attr, member_or_attr)] = val
109
+ _attr, member = ffi_attr_writer_member(member_or_attr, member_or_attr)
110
+ @native[member] = val
109
111
  end
110
112
 
111
113
  # Pass unimplemented methods on to {#native} underlying struct
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-libfuse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Gardner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-21 00:00:00.000000000 Z
11
+ date: 2024-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi