ffi-libfuse 0.3.4 → 0.4.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +1 -1
  4. data/lib/ffi/accessors.rb +21 -7
  5. data/lib/ffi/boolean_int.rb +1 -1
  6. data/lib/ffi/devt.rb +3 -3
  7. data/lib/ffi/libfuse/adapter/debug.rb +53 -15
  8. data/lib/ffi/libfuse/adapter/fuse2_compat.rb +38 -21
  9. data/lib/ffi/libfuse/adapter/fuse3_support.rb +0 -1
  10. data/lib/ffi/libfuse/adapter/ruby.rb +210 -159
  11. data/lib/ffi/libfuse/adapter/safe.rb +69 -21
  12. data/lib/ffi/libfuse/callbacks.rb +2 -1
  13. data/lib/ffi/libfuse/filesystem/accounting.rb +1 -1
  14. data/lib/ffi/libfuse/filesystem/mapped_files.rb +33 -7
  15. data/lib/ffi/libfuse/filesystem/pass_through_dir.rb +0 -1
  16. data/lib/ffi/libfuse/filesystem/virtual_dir.rb +293 -126
  17. data/lib/ffi/libfuse/filesystem/virtual_file.rb +85 -79
  18. data/lib/ffi/libfuse/filesystem/virtual_fs.rb +34 -15
  19. data/lib/ffi/libfuse/filesystem/virtual_link.rb +60 -0
  20. data/lib/ffi/libfuse/filesystem/virtual_node.rb +104 -87
  21. data/lib/ffi/libfuse/filesystem.rb +1 -1
  22. data/lib/ffi/libfuse/fuse2.rb +3 -2
  23. data/lib/ffi/libfuse/fuse3.rb +1 -1
  24. data/lib/ffi/libfuse/fuse_args.rb +5 -2
  25. data/lib/ffi/libfuse/fuse_buf.rb +112 -0
  26. data/lib/ffi/libfuse/fuse_buf_vec.rb +228 -0
  27. data/lib/ffi/libfuse/fuse_common.rb +10 -4
  28. data/lib/ffi/libfuse/fuse_config.rb +16 -7
  29. data/lib/ffi/libfuse/fuse_operations.rb +86 -41
  30. data/lib/ffi/libfuse/gem_helper.rb +2 -9
  31. data/lib/ffi/libfuse/io.rb +56 -0
  32. data/lib/ffi/libfuse/main.rb +27 -24
  33. data/lib/ffi/libfuse/test_helper.rb +68 -60
  34. data/lib/ffi/libfuse/version.rb +1 -1
  35. data/lib/ffi/libfuse.rb +1 -1
  36. data/lib/ffi/stat/native.rb +4 -4
  37. data/lib/ffi/stat.rb +19 -3
  38. data/lib/ffi/struct_array.rb +2 -1
  39. data/sample/hello_fs.rb +1 -1
  40. metadata +6 -3
  41. data/lib/ffi/libfuse/fuse_buffer.rb +0 -257
@@ -1,257 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'fuse_version'
4
-
5
- module FFI
6
- # Ruby FFI Binding for [libfuse](https://github.com/libfuse/libfuse)
7
- module Libfuse
8
- bitmask :fuse_buf_flags, [:is_fd, 1, :fd_seek, :fd_retry]
9
- bitmask :fuse_buf_copy_flags, [:no_splice, 1, :force_splice, 2, :splice_move, 4, :splice_nonblock, 8]
10
-
11
- #
12
- # Single data buffer
13
- #
14
- # Generic data buffer for I/O, extended attributes, etc...Data may be supplied as a memory pointer or as a file
15
- # descriptor
16
- #
17
- class FuseBuf < FFI::Struct
18
- layout(
19
- size: :size_t, # Size of data in bytes
20
- flags: :fuse_buf_flags, # Buffer flags
21
- mem: :pointer, # Memory pointer - used if :is_fd flag is not set
22
- fd: :int, # File descriptor - used if :is_fd is set
23
- pos: :off_t # File position - used if :fd_seek flag is set.
24
- )
25
-
26
- # rubocop:disable Naming/MethodParameterName
27
-
28
- # @!attribute [r] mem
29
- # @return [FFI::Pointer] the memory in the buffer
30
- def mem
31
- self[:mem]
32
- end
33
- alias memory mem
34
-
35
- # @!attribute [r] fd
36
- # @return [Integer] the file descriptor number
37
- def fd
38
- self[:fd]
39
- end
40
- alias file_descriptor fd
41
-
42
- # @return [Boolean] true if this a memory buffer
43
- def mem?
44
- !fd?
45
- end
46
-
47
- # @return [Boolean] true if this is a file descriptor buffer
48
- def fd?
49
- self[:flags].include?(:is_fd)
50
- end
51
- alias file_descriptor? fd?
52
-
53
- # Resize mem to smaller than initially allocated
54
- # @param [Integer] new_size
55
- # @return [void]
56
- def resize(new_size)
57
- self[:size] = new_size
58
- end
59
-
60
- # @overload fill(size:, mem:, auto_release)
61
- # Fill as a Memory buffer
62
- # @param [Integer] size Size of data in bytes
63
- # @param [FFI::Pointer] mem Memory pointer allocated to size if required
64
- # @param [Boolean] autorelease
65
- #
66
- # @overload fill(fd:, fd_retry:, pos:)
67
- # Fill as a FileDescriptor buffer
68
- # @param [Integer] fd File descriptor
69
- # @param [Boolean] fd_retry
70
- # Retry operations on file descriptor
71
- #
72
- # If this flag is set then retry operation on file descriptor until .size bytes have been copied or an error
73
- # or EOF is detected.
74
- #
75
- # @param [Integer] pos
76
- # If > 0 then used to seek to the given offset before performing operation on file descriptor.
77
- # @return [self]
78
- def fill(mem: FFI::Pointer::NULL, size: mem.null? ? 0 : mem.size, fd: -1, fd_retry: false, pos: 0)
79
- mem = FFI::MemoryPointer.new(:char, size, true) if fd == -1 && mem.null? && size.positive?
80
- mem.autorelease = to_ptr.autorelease? unless mem.null?
81
-
82
- self[:size] = size
83
- self[:mem] = mem
84
- self[:fd] = fd
85
- flags = []
86
- flags << :is_fd if fd != -1
87
- flags << :fd_seek if pos.positive?
88
- flags << :fd_retry if fd_retry
89
- self[:flags] = flags
90
- self[:pos] = pos
91
- self
92
- end
93
- end
94
- # rubocop:enable Naming/MethodParameterName
95
-
96
- #
97
- # Data buffer vector
98
- #
99
- # An array of data buffers, each containing a memory pointer or a file descriptor.
100
- #
101
- # Allocate dynamically to add more than one buffer.
102
- #
103
- class FuseBufVec < FFI::Struct
104
- layout(
105
- count: :size_t,
106
- idx: :size_t,
107
- off: :size_t,
108
- # but is treated as a variable length array of FuseBuf at size +1 following the struct.
109
- buf: [FuseBuf, 1] # struct fuse_buf[1]
110
- )
111
-
112
- # @!attribute [r] count
113
- # @return [Integer] the number of buffers in the array
114
- def count
115
- self[:count]
116
- end
117
-
118
- # @!attribute [r] index
119
- # @return [Integer] index of current buffer within the array
120
- def index
121
- self[:idx]
122
- end
123
- alias idx index
124
-
125
- # @!attribute [r] offset
126
- # @return [Integer] current offset within the current buffer
127
- def offset
128
- self[:off]
129
- end
130
- alias off offset
131
-
132
- # @!attribute [r] buffers
133
- # @return [Array<FuseBuf>] array of buffers
134
- def buffers
135
- @buffers ||= Array.new(count) do |i|
136
- next self[:buf].first if i.zero?
137
-
138
- FuseBuf.new(self[:buf].to_ptr + (i * FuseBuf.size))
139
- end
140
- end
141
-
142
- # @!attribute [r] current
143
- # @return [FuseBuf] the current buffer
144
- def current
145
- return self[:buf].first if index.zero?
146
-
147
- FuseBuf.new(self[:buf].to_ptr + (index * FuseBuf.size))
148
- end
149
-
150
- # Create and initialise a new FuseBufVec
151
- # @param [Boolean] autorelease should the struct be freed on GC (default NO!!!)
152
- # @param [Hash] buf_options options for configuring the initial buffer. See {#init}
153
- # @yield(buf,index)
154
- # @yieldparam [FuseBuf] buf
155
- # @yieldparam [Integer] index
156
- # @yieldreturn [void]
157
- # @return [FuseBufVec]
158
- def self.init(autorelease: true, count: 1, **buf_options)
159
- bufvec_ptr = FFI::MemoryPointer.new(:uchar, FuseBufVec.size + (FuseBuf.size * (count - 1)), true)
160
- bufvec_ptr.autorelease = autorelease
161
- bufvec = new(bufvec_ptr)
162
- bufvec[:count] = count
163
- bufvec.init(**buf_options)
164
-
165
- buffers.each_with_index { |b, i| yield i, b } if block_given?
166
- bufvec
167
- end
168
-
169
- # Set and initialise a specific buffer
170
- #
171
- # See fuse_common.h FUSE_BUFVEC_INIT macro
172
- # @param [Integer] index the index of the buffer
173
- # @param [Hash<Symbol,Object>] buf_options see {FuseBuf#fill}
174
- # @return [FuseBuf] the initial buffer
175
- def init(index: 0, **buf_options)
176
- self[:idx] = index
177
- self[:off] = 0
178
- current.fill(**buf_options) unless buf_options.empty?
179
- self
180
- end
181
-
182
- # Would pref this to be called #size but clashes with FFI::Struct, might need StructWrapper
183
- # @return [Integer] total size of data in a fuse buffer vector
184
- def buf_size
185
- Libfuse.fuse_buf_size(self)
186
- end
187
-
188
- # Copy data from one buffer vector to another
189
- # @param [FuseBufVec] dst Destination buffer vector
190
- # @param [Array<Symbol>] flags Buffer copy flags
191
- # - :no_splice
192
- # Don't use splice(2)
193
- #
194
- # Always fall back to using read and write instead of splice(2) to copy data from one file descriptor to
195
- # another.
196
- #
197
- # If this flag is not set, then only fall back if splice is unavailable.
198
- #
199
- # - :force_splice
200
- #
201
- # Always use splice(2) to copy data from one file descriptor to another. If splice is not available, return
202
- # -EINVAL.
203
- #
204
- # - :splice_move
205
- #
206
- # Try to move data with splice.
207
- #
208
- # If splice is used, try to move pages from the source to the destination instead of copying. See
209
- # documentation of SPLICE_F_MOVE in splice(2) man page.
210
- #
211
- # - :splice_nonblock
212
- #
213
- # Don't block on the pipe when copying data with splice
214
- #
215
- # Makes the operations on the pipe non-blocking (if the pipe is full or empty). See SPLICE_F_NONBLOCK in
216
- # the splice(2) man page.
217
- #
218
- # @return [Integer] actual number of bytes copied or -errno on error
219
- #
220
- def copy_to(dst, *flags)
221
- Libfuse.fuse_buf_copy(dst, self, flags)
222
- end
223
-
224
- # Copy our data direct to file descriptor
225
- # @param [Integer] fileno a file descriptor
226
- # @param [Integer] offset
227
- # @param [Array<Symbol>] flags - see {copy_to}
228
- # @return [Integer] number of bytes copied
229
- def copy_to_fd(fileno, offset = 0, *flags)
230
- dst = self.class.init(size: buf_size, fd: fileno, pos: offset)
231
- copy_to(dst, *flags)
232
- end
233
-
234
- # Copy to string via a temporary buffer
235
- # @param [Array<Symbol>] flags - see {copy_to}
236
- # @return [String] the extracted data
237
- def copy_to_str(*flags)
238
- dst = FuseBufVec.init(size: buf_size)
239
- copied = copy_to(dst, *flags)
240
- dst.current.memory.read_string(copied)
241
- end
242
-
243
- def copy_from(src, *flags)
244
- Libfuse.fuse_buf_copy(self, src, flags)
245
- end
246
- end
247
-
248
- attach_function :fuse_buf_size, [FuseBufVec.by_ref], :size_t
249
- attach_function :fuse_buf_copy, [FuseBufVec.by_ref, FuseBufVec.by_ref, :fuse_buf_copy_flags], :ssize_t
250
-
251
- class << self
252
- # @!visibility private
253
- # @!method fuse_buf_size
254
- # @!method fuse_buf_copy
255
- end
256
- end
257
- end