ffi-libfuse 0.0.1.rctest12 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/CHANGELOG.md +60 -0
  4. data/LICENSE +21 -0
  5. data/README.md +127 -44
  6. data/lib/ffi/accessors.rb +6 -6
  7. data/lib/ffi/boolean_int.rb +27 -0
  8. data/lib/ffi/devt.rb +23 -0
  9. data/lib/ffi/encoding.rb +38 -0
  10. data/lib/ffi/flock.rb +7 -5
  11. data/lib/ffi/gnu_extensions.rb +1 -1
  12. data/lib/ffi/libfuse/ackbar.rb +3 -3
  13. data/lib/ffi/libfuse/adapter/context.rb +12 -10
  14. data/lib/ffi/libfuse/adapter/fuse2_compat.rb +52 -51
  15. data/lib/ffi/libfuse/adapter/fuse3_support.rb +7 -4
  16. data/lib/ffi/libfuse/adapter/interrupt.rb +1 -1
  17. data/lib/ffi/libfuse/adapter/ruby.rb +499 -148
  18. data/lib/ffi/libfuse/adapter/safe.rb +12 -11
  19. data/lib/ffi/libfuse/adapter.rb +1 -2
  20. data/lib/ffi/libfuse/callbacks.rb +1 -1
  21. data/lib/ffi/libfuse/filesystem/accounting.rb +116 -0
  22. data/lib/ffi/libfuse/filesystem/mapped_dir.rb +74 -0
  23. data/lib/ffi/libfuse/filesystem/mapped_files.rb +141 -0
  24. data/lib/ffi/libfuse/filesystem/pass_through_dir.rb +55 -0
  25. data/lib/ffi/libfuse/filesystem/pass_through_file.rb +45 -0
  26. data/lib/ffi/libfuse/filesystem/utils.rb +102 -0
  27. data/lib/ffi/libfuse/filesystem/virtual_dir.rb +306 -0
  28. data/lib/ffi/libfuse/filesystem/virtual_file.rb +94 -0
  29. data/lib/ffi/libfuse/filesystem/virtual_fs.rb +196 -0
  30. data/lib/ffi/libfuse/filesystem/virtual_node.rb +101 -0
  31. data/lib/ffi/libfuse/filesystem.rb +25 -0
  32. data/lib/ffi/libfuse/fuse2.rb +32 -24
  33. data/lib/ffi/libfuse/fuse3.rb +28 -18
  34. data/lib/ffi/libfuse/fuse_args.rb +71 -34
  35. data/lib/ffi/libfuse/fuse_buffer.rb +128 -26
  36. data/lib/ffi/libfuse/fuse_callbacks.rb +1 -5
  37. data/lib/ffi/libfuse/fuse_common.rb +60 -61
  38. data/lib/ffi/libfuse/fuse_config.rb +134 -143
  39. data/lib/ffi/libfuse/fuse_conn_info.rb +310 -134
  40. data/lib/ffi/libfuse/fuse_context.rb +45 -3
  41. data/lib/ffi/libfuse/fuse_operations.rb +57 -21
  42. data/lib/ffi/libfuse/fuse_opt.rb +1 -1
  43. data/lib/ffi/libfuse/fuse_version.rb +10 -6
  44. data/lib/ffi/libfuse/gem_version.rb +54 -0
  45. data/lib/ffi/libfuse/main.rb +96 -48
  46. data/lib/ffi/libfuse/test_helper.rb +145 -0
  47. data/lib/ffi/libfuse/version.rb +1 -1
  48. data/lib/ffi/libfuse.rb +13 -4
  49. data/lib/ffi/ruby_object.rb +4 -1
  50. data/lib/ffi/stat/constants.rb +9 -0
  51. data/lib/ffi/stat/native.rb +36 -6
  52. data/lib/ffi/stat/time_spec.rb +26 -10
  53. data/lib/ffi/stat.rb +111 -22
  54. data/lib/ffi/stat_vfs.rb +59 -1
  55. data/lib/ffi/struct_wrapper.rb +22 -1
  56. data/sample/hello_fs.rb +54 -0
  57. data/sample/memory_fs.rb +5 -181
  58. data/sample/no_fs.rb +20 -21
  59. data/sample/pass_through_fs.rb +30 -0
  60. metadata +83 -10
  61. data/lib/ffi/libfuse/adapter/thread_local_context.rb +0 -36
  62. data/lib/ffi/libfuse/test/operations.rb +0 -56
  63. data/lib/ffi/libfuse/test.rb +0 -3
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ffi/libfuse'
5
+
6
+ # Hello World!
7
+ class HelloFS
8
+ include FFI::Libfuse::Adapter::Ruby
9
+ include FFI::Libfuse::Adapter::Fuse2Compat
10
+
11
+ # FUSE Configuration methods
12
+
13
+ def fuse_options(args)
14
+ args.parse!({ 'subject=' => :subject }) do |key:, value:, **|
15
+ raise FFI::Libfuse::Error, 'subject option must be at least 2 characters' unless value.size >= 2
16
+
17
+ @subject = value if key == :subject
18
+ :handled
19
+ end
20
+ end
21
+
22
+ def fuse_help
23
+ '-o subject=<subject> a target to say hello to'
24
+ end
25
+
26
+ def fuse_configure
27
+ @subject ||= 'World!'
28
+ @content = "Hello #{@subject}\n"
29
+ end
30
+
31
+ # FUSE callbacks
32
+
33
+ def getattr(path, stat, *_args)
34
+ case path
35
+ when '/'
36
+ stat.directory(mode: 0o550)
37
+ when '/hello.txt'
38
+ stat.file(mode: 0o440, size: @content.size)
39
+ else
40
+ raise Errno::ENOENT
41
+ end
42
+ end
43
+
44
+ def readdir(_path, *_args)
45
+ yield 'hello.txt'
46
+ end
47
+
48
+ def read(_path, *_args)
49
+ @content
50
+ end
51
+ end
52
+
53
+ # Start the file system
54
+ FFI::Libfuse.fuse_main(operations: HelloFS.new) if __FILE__ == $0
data/sample/memory_fs.rb CHANGED
@@ -2,188 +2,12 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'ffi/libfuse'
5
+ require 'ffi/libfuse/filesystem/virtual_fs'
5
6
 
6
7
  # A simple in-memory filesystem defined with hashes.
7
- #
8
- # It is writable to the user that mounted it may create and edit files within it
9
- #
10
- # === Usage
11
- # root = Memory.new(files: { 'hello' => { 'world.txt' => 'Hello World'}})
12
- # root.mkdir("/hello")
13
- # root.("/hello/world","Hello World!\n")
14
- # root.write("/hello/everybody","Hello Everyone!\n")
15
- #
16
- # Libfuse::fuse_main($0,ARGV,operations: root)
17
- #
18
- #
19
- class MemoryFS
20
- # @return [Hash<String,Object>] list of file objects by path
21
- attr_reader :root
8
+ class MemoryFS < FFI::Libfuse::Filesystem::VirtualFS; end
22
9
 
23
- include FFI::Libfuse::Adapter::Fuse3Support
24
- include FFI::Libfuse::Adapter::Ruby
25
- include FFI::Libfuse::Adapter::Pathname
10
+ # Set this to test multi-threading etc...
11
+ main_class = ENV.fetch('MEMORY_FS_SKIP_DEFAULT_ARGS', 'N') == 'Y' ? FFI::Libfuse::Main : FFI::Libfuse
26
12
 
27
- File = Struct.new(:mode, :content, :ctime, :atime, :mtime) do
28
- def dig(*_args)
29
- raise Errno::ENOTDIR
30
- end
31
-
32
- def fill_stat(stat = FFI::Stat.new)
33
- stat.file(mode: mode, ctime: ctime, atime: atime, mtime: mtime, size: content.size)
34
- end
35
- end
36
-
37
- # rubocop:disable Lint/StructNewOverride
38
- Dir = Struct.new(:mode, :entries, :ctime, :atime, :mtime) do
39
- def dig(*args)
40
- entries.dig(*args)
41
- end
42
-
43
- def fill_stat(stat = FFI::Stat.new)
44
- stat.directory(mode: mode, ctime: ctime, atime: atime, mtime: mtime)
45
- end
46
- end
47
- # rubocop:enable Lint/StructNewOverride
48
-
49
- def initialize(files: {}, max_size: 100_000, max_files: 1_000)
50
- now = Time.now
51
- @root = Dir.new(0x755, {}, now, now, now)
52
- @total_size = 0
53
- @total_files = 1
54
- @max_size = max_size
55
- @max_files = max_files
56
-
57
- build(files)
58
- end
59
-
60
- def build(files, path = ::Pathname.new('/'))
61
- files.each_pair do |basename, content|
62
- raise 'Initial file keys must be String' unless basename.is_a?(String)
63
- raise 'Initial file keys must not contain path separators' if basename =~ %r{[/\\]}
64
-
65
- entry_path = path + basename
66
- case content
67
- when String
68
- create(entry_path, 0x644)
69
- write(entry_path, content, 0)
70
- when Hash
71
- mkdir(entry_path, 0x755)
72
- build(content, entry_path)
73
- else
74
- raise 'Initial files must be String or Hash'
75
- end
76
- end
77
- end
78
-
79
- def fuse_version
80
- 'MemoryFS: Version x.y.z'
81
- end
82
-
83
- def fuse_traps
84
- {
85
- HUP: -> { reload }
86
- }
87
- end
88
-
89
- def statfs(_path, statfs_buf)
90
- blocks = @total_size / 1_000
91
- statfs_buf.bsize = 1 # block size (in Kb)
92
- statfs_buf.frsize = 1 # fragment size pretty much always bsize
93
- statfs_buf.blocks = @max_size
94
- statfs_buf.bfree = @max_size - blocks
95
- statfs_buf.bavail = @max_size - blocks
96
- statfs_buf.files = @max_files
97
- statfs_buf.ffree = @max_files - @total_files
98
- statfs_buf.favail = @max_files - @total_files
99
- 0
100
- end
101
-
102
- def getattr(path, stat_buf)
103
- entry = find(path)
104
- return -Errno::ENOENT::Errno unless entry
105
-
106
- entry.fill_stat(stat_buf)
107
- 0
108
- end
109
-
110
- def readdir(path, _offset, _ffi)
111
- %w[. ..].each { |d| yield(d, nil) }
112
- dir = find(path)
113
- dir.entries.each_pair { |k, e| yield(k, e.fill_stat) }
114
- end
115
-
116
- def create(path, mode, _ffi)
117
- dir_entries = find(path.dirname).entries
118
- now = Time.now
119
- dir_entries[path.basename.to_s] = File.new(mode, String.new, now, now, now)
120
- @total_files += 1
121
- 0
122
- end
123
-
124
- # op[:read] = [:pointer, :size_t, :off_t, FuseFileInfo.by_ref]
125
- def read(path, len, off, _ffi)
126
- file = find(path)
127
- file.atime = Time.now.utc
128
- FFI::Libfuse::ThreadPool.busy
129
- sleep 0.5
130
- file.content[off, len]
131
- end
132
-
133
- # write(const char* path, char *buf, size_t size, off_t offset, struct fuse_file_info* fi)
134
- def write(path, data, offset, _ffi)
135
- file = find(path)
136
- content = file.content
137
- @total_size -= content.size
138
- content[offset, data.length] = data
139
- @total_size += content.size
140
- file.mtime = Time.now.utc
141
- end
142
-
143
- def truncate(path, size)
144
- file = find(path)
145
- @total_size -= file.content.size
146
- file.content[size..-1] = ''
147
- file.mtime = Time.now.utc
148
- @total_size += file.content.size
149
- 0
150
- end
151
-
152
- def unlink(path)
153
- dir = find(path.dirname)
154
- deleted = dir.entries.delete(path.basename.to_s)
155
- @total_files -= 1
156
- @total_size -= deleted.content.size if deleted.is_a?(File)
157
- 0
158
- end
159
-
160
- def mkdir(path, mode)
161
- entries = find(path.dirname).entries
162
- now = Time.now
163
- entries[path.basename.to_s] = Dir.new(mode, {}, now, now, now)
164
- end
165
-
166
- def rmdir(path)
167
- dir = find(path)
168
- raise Errno::ENOTDIR unless dir.is_a?(Dir)
169
- raise Errno::ENOTEMPTY unless dir.entries.empty?
170
-
171
- find(path.dirname).entries.delete(path.basename.to_s)
172
- 0
173
- end
174
-
175
- def utimens(path, atime, mtime)
176
- entry = find(path)
177
- entry.atime = atime if atime
178
- entry.mtime = mtime if mtime
179
- 0
180
- end
181
-
182
- private
183
-
184
- def find(path)
185
- path.root? ? root : root.dig(*path.to_s.split('/')[1..])
186
- end
187
- end
188
-
189
- exit(FFI::Libfuse.fuse_main($0, *ARGV, operations: MemoryFS.new)) if __FILE__ == $0
13
+ exit(main_class.fuse_main(operations: MemoryFS.new)) if __FILE__ == $0
data/sample/no_fs.rb CHANGED
@@ -6,13 +6,21 @@ require 'ffi/libfuse'
6
6
  # An empty file system
7
7
  class NoFS
8
8
  include FFI::Libfuse::Adapter::Context
9
- include FFI::Libfuse::Adapter::Fuse3Support
10
9
  include FFI::Libfuse::Adapter::Ruby
10
+ include FFI::Libfuse::Adapter::Fuse3Support # must run outside of Adapter::Ruby
11
11
 
12
12
  OPTIONS = { 'log=' => :log }.freeze
13
13
 
14
- def fuse_options
15
- OPTIONS
14
+ def fuse_options(args)
15
+ args.parse!(OPTIONS) do |key:, value:, **|
16
+ case key
17
+ when :log
18
+ @logfile = value
19
+ else
20
+ next :keep
21
+ end
22
+ :handled
23
+ end
16
24
  end
17
25
 
18
26
  def fuse_help
@@ -24,46 +32,37 @@ class NoFS
24
32
  end
25
33
 
26
34
  def fuse_version
27
- 'NoFS: Version x.y.z'
28
- end
29
-
30
- def fuse_opt_proc(_data, arg, key, _outargs)
31
- case key
32
- when :log
33
- @logfile = arg[4..]
34
- return :handled
35
- end
36
- :keep
35
+ "NoFS: Version x.y.z. Fuse3Compat=#{fuse3_compat?}"
37
36
  end
38
37
 
39
- def getattr(_ctx, path, stat)
38
+ def getattr(path, stat)
40
39
  raise Errno::ENOENT unless path == '/'
41
40
 
42
41
  stat.directory(mode: 0o555)
43
42
  end
44
43
 
45
- def readdir(_ctx, _path, _offset, _ffi)
46
- %w[. ..].each { |d| yield(d, nil) }
44
+ def readdir(_path, _offset, _ffi, &block)
45
+ puts "NOFS Readdir: #{block}"
46
+ %w[. ..].each(&block)
47
47
  end
48
48
 
49
49
  def log
50
50
  @log ||= File.open(@logfile || '/tmp/no_fs.out', 'a')
51
51
  end
52
52
 
53
- def init(ctx, conn, cfg = nil)
53
+ def init(_conn)
54
+ ctx = FFI::Libfuse::Adapter::Context.fuse_context
54
55
  log.puts("NoFS init ctx- #{ctx.inspect}") if ctx
55
- log.puts("NoFS init conn - #{conn.inspect}") if conn && !conn.null?
56
- log.puts "NoFS init cfg #{cfg.inspect}" if cfg && !cfg.null?
57
56
  warn 'NoFS: DEBUG enabled' if debug?
58
57
  log.flush
59
58
  'INIT_DATA'
60
59
  end
61
60
 
62
- def destroy(obj, *_rest)
61
+ def destroy(obj)
63
62
  # If the fs is not cleanly unmounted the init data will have been GC'd by the time this is called
64
63
  log.puts("NoFS destroy- #{obj.inspect}") if !obj.is_a?(WeakRef) || obj.weakref_alive?
65
64
  log.puts "NoFS destroy- pid=#{Process.pid}"
66
65
  end
67
66
  end
68
67
 
69
- exit(FFI::Libfuse.fuse_main($0, *ARGV, operations: NoFS.new, private_data: 'MAIN_DATA')) if __FILE__ == $0
68
+ exit(FFI::Libfuse::Main.fuse_main($0, *ARGV, operations: NoFS.new, private_data: 'MAIN_DATA')) if __FILE__ == $0
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ffi/libfuse'
5
+ require 'ffi/libfuse/filesystem/pass_through_dir'
6
+
7
+ # Pass Through Filesystem - over a base directory
8
+ class PassThroughFS < FFI::Libfuse::Filesystem::PassThroughDir
9
+ def fuse_options(args)
10
+ args.parse!({ 'base_dir=' => :base_dir }) do |key:, value:, **|
11
+ next :keep unless key == :base_dir
12
+
13
+ raise FFI::Libfuse::Error, "#{value} is not a directory" unless Dir.exist?(value)
14
+
15
+ self.base_dir = value
16
+ :handled
17
+ end
18
+ end
19
+
20
+ def fuse_help
21
+ '-o base_dir=<dir>'
22
+ end
23
+
24
+ def fuse_configure
25
+ self.base_dir ||= Dir.pwd
26
+ warn "Using #{self.base_dir} as base directory for file operations" if debug?
27
+ end
28
+ end
29
+
30
+ exit(FFI::Libfuse.fuse_main(operations: PassThroughFS.new)) if __FILE__ == $0
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.0.1.rctest12
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Gardner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-16 00:00:00.000000000 Z
11
+ date: 2023-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -24,6 +24,62 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler-audit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
27
83
  - !ruby/object:Gem::Dependency
28
84
  name: rubocop
29
85
  requirement: !ruby/object:Gem::Requirement
@@ -74,9 +130,13 @@ extensions: []
74
130
  extra_rdoc_files: []
75
131
  files:
76
132
  - ".yardopts"
133
+ - CHANGELOG.md
134
+ - LICENSE
77
135
  - README.md
78
136
  - lib/ffi/accessors.rb
137
+ - lib/ffi/boolean_int.rb
79
138
  - lib/ffi/devt.rb
139
+ - lib/ffi/encoding.rb
80
140
  - lib/ffi/flock.rb
81
141
  - lib/ffi/gnu_extensions.rb
82
142
  - lib/ffi/libfuse.rb
@@ -90,8 +150,18 @@ files:
90
150
  - lib/ffi/libfuse/adapter/pathname.rb
91
151
  - lib/ffi/libfuse/adapter/ruby.rb
92
152
  - lib/ffi/libfuse/adapter/safe.rb
93
- - lib/ffi/libfuse/adapter/thread_local_context.rb
94
153
  - lib/ffi/libfuse/callbacks.rb
154
+ - lib/ffi/libfuse/filesystem.rb
155
+ - lib/ffi/libfuse/filesystem/accounting.rb
156
+ - lib/ffi/libfuse/filesystem/mapped_dir.rb
157
+ - lib/ffi/libfuse/filesystem/mapped_files.rb
158
+ - lib/ffi/libfuse/filesystem/pass_through_dir.rb
159
+ - lib/ffi/libfuse/filesystem/pass_through_file.rb
160
+ - lib/ffi/libfuse/filesystem/utils.rb
161
+ - lib/ffi/libfuse/filesystem/virtual_dir.rb
162
+ - lib/ffi/libfuse/filesystem/virtual_file.rb
163
+ - lib/ffi/libfuse/filesystem/virtual_fs.rb
164
+ - lib/ffi/libfuse/filesystem/virtual_node.rb
95
165
  - lib/ffi/libfuse/fuse2.rb
96
166
  - lib/ffi/libfuse/fuse3.rb
97
167
  - lib/ffi/libfuse/fuse_args.rb
@@ -108,10 +178,10 @@ files:
108
178
  - lib/ffi/libfuse/fuse_opt.rb
109
179
  - lib/ffi/libfuse/fuse_poll_handle.rb
110
180
  - lib/ffi/libfuse/fuse_version.rb
181
+ - lib/ffi/libfuse/gem_version.rb
111
182
  - lib/ffi/libfuse/job_pool.rb
112
183
  - lib/ffi/libfuse/main.rb
113
- - lib/ffi/libfuse/test.rb
114
- - lib/ffi/libfuse/test/operations.rb
184
+ - lib/ffi/libfuse/test_helper.rb
115
185
  - lib/ffi/libfuse/thread_pool.rb
116
186
  - lib/ffi/libfuse/version.rb
117
187
  - lib/ffi/ruby_object.rb
@@ -122,13 +192,16 @@ files:
122
192
  - lib/ffi/stat_vfs.rb
123
193
  - lib/ffi/struct_array.rb
124
194
  - lib/ffi/struct_wrapper.rb
195
+ - sample/hello_fs.rb
125
196
  - sample/memory_fs.rb
126
197
  - sample/no_fs.rb
198
+ - sample/pass_through_fs.rb
127
199
  homepage:
128
200
  licenses:
129
201
  - MIT
130
202
  metadata:
131
- source_code_uri: http://github.com/lwoggardner/ffi-libfuse
203
+ source_code_uri: https://github.com/lwoggardner/ffi-libfuse
204
+ rubygems_mfa_required: 'true'
132
205
  post_install_message:
133
206
  rdoc_options: []
134
207
  require_paths:
@@ -137,14 +210,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
210
  requirements:
138
211
  - - ">="
139
212
  - !ruby/object:Gem::Version
140
- version: 2.6.0
213
+ version: 2.7.0
141
214
  required_rubygems_version: !ruby/object:Gem::Requirement
142
215
  requirements:
143
- - - ">"
216
+ - - ">="
144
217
  - !ruby/object:Gem::Version
145
- version: 1.3.1
218
+ version: '0'
146
219
  requirements: []
147
- rubygems_version: 3.1.2
220
+ rubygems_version: 3.1.6
148
221
  signing_key:
149
222
  specification_version: 4
150
223
  summary: FFI Bindings for Libfuse
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../fuse_context'
4
-
5
- module FFI
6
- module Libfuse
7
- module Adapter
8
- # Injects a wrapper via #{FuseCallbacks#fuse_wrappers} make the current {FuseContext} object available to
9
- # callbacks (except :destroy) via thread local variable :fuse_context
10
- module ThreadLocalContext
11
- # @!visibility private
12
- def fuse_wrappers(*wrappers)
13
- wrappers.unshift(
14
- {
15
- wrapper: proc { |_fm, *args, **_, &b| self.class.thread_local_context(*args, &b) },
16
- excludes: %i[destroy]
17
- }
18
- )
19
- return wrappers unless defined?(super)
20
-
21
- super(*wrappers)
22
- end
23
-
24
- module_function
25
-
26
- # Stores {FuseContext} in thread local variable :fuse_context before yielding
27
- def thread_local_context(*args)
28
- Thread.current[:fuse_context] = FuseContext.get
29
- yield(*args)
30
- ensure
31
- Thread.current[:fuse_context] = nil
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../fuse_operations'
4
-
5
- module FFI
6
- module Libfuse
7
- module Test
8
- # A FuseOperations that holds callback procs in a Hash rather than FFI objects and allows for direct invocation of
9
- # callback methods
10
- # @!parse FuseOperations
11
- class Operations
12
- include FuseCallbacks
13
-
14
- def initialize(delegate:, fuse_wrappers: [])
15
- @callbacks = {}
16
- initialize_callbacks(delegate: delegate, wrappers: fuse_wrappers)
17
- end
18
-
19
- # @!visibility private
20
- def [](member)
21
- @callbacks[member]
22
- end
23
-
24
- # @!visibility private
25
- def []=(member, value)
26
- @callbacks[member] = value
27
- end
28
-
29
- # @!visibility private
30
- def members
31
- FuseOperations.members
32
- end
33
-
34
- private
35
-
36
- # Allow the fuse operations to be called directly - useful for testing
37
- # @todo some fancy wrapper to convert tests using Fuse2 signatures when Fuse3 is the loaded library
38
- # and vice-versa
39
- def method_missing(method, *args)
40
- callback = callback?(method) && self[method]
41
- return super unless callback
42
-
43
- callback.call(*args)
44
- end
45
-
46
- def respond_to_missing?(method, _private = false)
47
- self[method] && callback?(method)
48
- end
49
-
50
- def callback?(method)
51
- callback_members.include?(method)
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test/operations'