ffi-libfuse 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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