ffi-libfuse 0.0.1.rctest12 → 0.3.3

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.
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'