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.
data/lib/ffi/flock.rb CHANGED
@@ -18,32 +18,36 @@ module FFI
18
18
 
19
19
  include(Accessors)
20
20
 
21
- layout(l_type: Enums::LockType, l_whence: Enums::SeekWhenceShort, l_start: :off_t, l_len: :off_t, l_pid: :pid_t)
22
-
23
- l_members = members.grep(/^l_/).map { |m| m[2..].to_sym }
24
-
25
- ffi_attr_reader(*l_members, format: 'l_%s')
26
-
27
- # @!attribute [r] type
28
- # @return [Symbol] lock type, :rdlck, :wrlck, :unlck
29
-
30
- # @!attribute [r] whence
31
- # @return [Symbol] specifies what the offset is relative to, one of :seek_set, :seek_cur or :seek_end
32
- # corresponding to the whence argument to fseek(2) or lseek(2),
33
-
34
- # @!attribute [r] start
35
- # @return [Integer] the offset of the start of the region to which the lock applies, and is given in bytes
36
- # relative to the point specified by #{whence} member.
37
-
38
- # @!attribute [r] len
39
- # @return [Integer] the length of the region to be locked.
40
- #
41
- # A value of 0 means the region extends to the end of the file.
42
-
43
- # @!attribute [r] pid
44
- # @return [Integer] the process ID (see Process Creation Concepts) of the process holding the lock.
45
- # It is filled in by calling fcntl with the F_GETLK command, but is ignored when making a lock. If the
46
- # conflicting lock is an open file description lock (see Open File Description Locks), then this field will be
47
- # set to -1.
21
+ layout(
22
+ # @!attribute [r] type
23
+ # @return [Symbol] lock type, :rdlck, :wrlck, :unlck
24
+ l_type: Enums::LockType,
25
+
26
+ # @!attribute [r] whence
27
+ # @return [Symbol] specifies what the offset is relative to, one of :seek_set, :seek_cur or :seek_end
28
+ # corresponding to the whence argument to fseek(2) or lseek(2),
29
+ l_whence: Enums::SeekWhenceShort,
30
+
31
+ # @!attribute [r] start
32
+ # @return [Integer] the offset of the start of the region to which the lock applies, and is given in bytes
33
+ # relative to the point specified by #{whence} member.
34
+ l_start: :off_t,
35
+
36
+ # @!attribute [r] len
37
+ # @return [Integer] the length of the region to be locked.
38
+ #
39
+ # A value of 0 means the region extends to the end of the file.
40
+ l_len: :off_t,
41
+
42
+ # @!attribute [r] pid
43
+ # @return [Integer] the process ID (see Process Creation Concepts) of the process holding the lock.
44
+ # It is filled in by calling fcntl with the F_GETLK command, but is ignored when making a lock. If the
45
+ # conflicting lock is an open file description lock (see Open File Description Locks), then this field will be
46
+ # set to -1.
47
+ l_pid: :pid_t
48
+ )
49
+
50
+ # Strip leading 'l_' to make attribute names
51
+ ffi_attr_reader(**members.to_h { |m| [m[2..].to_sym, m] })
48
52
  end
49
53
  end
@@ -18,7 +18,7 @@ module FFI
18
18
  )
19
19
  return wrappers unless defined?(super)
20
20
 
21
- super(*wrappers)
21
+ super
22
22
  end
23
23
 
24
24
  module_function
@@ -41,7 +41,7 @@ module FFI
41
41
  wrappers << proc { |fm, *args, &b| debug_callback(fm, *args, **conf, &b) } if debug?
42
42
  return wrappers unless defined?(super)
43
43
 
44
- super(*wrappers)
44
+ super
45
45
  end
46
46
 
47
47
  # @!visibility private
@@ -12,27 +12,27 @@ module FFI
12
12
  if FUSE_MAJOR_VERSION == 2
13
13
  # @!visibility private
14
14
  def getattr(path, stat, fuse_file_info = nil)
15
- super(path, stat, fuse_file_info)
15
+ super
16
16
  end
17
17
 
18
18
  def truncate(path, size, fuse_file_info = nil)
19
- super(path, size, fuse_file_info)
19
+ super
20
20
  end
21
21
 
22
22
  def init(fuse_conn_info, fuse_config = nil)
23
- super(fuse_conn_info, fuse_config)
23
+ super
24
24
  end
25
25
 
26
26
  def chown(path, uid, gid, fuse_file_info = nil)
27
- super(path, uid, gid, fuse_file_info)
27
+ super
28
28
  end
29
29
 
30
30
  def chmod(path, mode, fuse_file_info = nil)
31
- super(path, mode, fuse_file_info)
31
+ super
32
32
  end
33
33
 
34
34
  def utimens(path, times, fuse_file_info = nil)
35
- super(path, times, fuse_file_info)
35
+ super
36
36
  end
37
37
 
38
38
  def readdir(path, buffer, filler, offset, fuse_file_info, fuse_readdir_flag = 0)
@@ -45,7 +45,7 @@ module FFI
45
45
  # fgetattr and ftruncate already fallback to the respective basic method
46
46
  return false if %i[getdir fgetattr ftruncate].include?(fuse_method)
47
47
 
48
- super(fuse_method)
48
+ super
49
49
  end
50
50
 
51
51
  def fuse_options(args)
@@ -24,24 +24,24 @@ module FFI
24
24
  fi = args.pop
25
25
  return fgetattr(*args, fi) if fi && fuse_super_respond_to?(:fgetattr)
26
26
 
27
- super(*args)
27
+ super
28
28
  end
29
29
 
30
30
  def truncate(*args)
31
31
  fi = args.pop
32
32
  return ftruncate(*args, fi) if fi && fuse_super_respond_to?(:ftruncate)
33
33
 
34
- super(*args)
34
+ super
35
35
  end
36
36
 
37
37
  def chown(*args)
38
38
  args.pop
39
- super(*args)
39
+ super
40
40
  end
41
41
 
42
42
  def chmod(*args)
43
43
  args.pop
44
- super(*args)
44
+ super
45
45
  end
46
46
 
47
47
  # TODO: Fuse3 deprecated flag utime_omit_ok - which meant that UTIME_OMIT and UTIME_NOW are passed through
@@ -50,14 +50,14 @@ module FFI
50
50
  # but there is no way to handle OMIT
51
51
  def utimens(*args)
52
52
  args.pop
53
- super(*args) if defined?(super)
53
+ super if defined?(super)
54
54
  end
55
55
 
56
56
  def init(*args)
57
57
  args.pop
58
58
 
59
59
  # TODO: populate FuseConfig with output from fuse_flags/FuseConnInfo where appropriate
60
- super(*args)
60
+ super
61
61
  end
62
62
 
63
63
  def readdir(*args, &block)
@@ -71,7 +71,7 @@ module FFI
71
71
  proc { |buf, name, stat, off| a.call(buf, name, stat, off, 0) }
72
72
  end
73
73
 
74
- super(*args, &block)
74
+ super
75
75
  end
76
76
 
77
77
  def fuse_respond_to(fuse_callback)
@@ -20,7 +20,7 @@ module FFI
20
20
  }
21
21
  return wrappers unless defined?(super)
22
22
 
23
- super(*wrappers)
23
+ super
24
24
  end
25
25
 
26
26
  module_function
@@ -15,7 +15,7 @@ module FFI
15
15
  }
16
16
  return wrappers unless defined?(super)
17
17
 
18
- super(*wrappers)
18
+ super
19
19
  end
20
20
  end
21
21
  end
@@ -338,7 +338,7 @@ module FFI
338
338
 
339
339
  # Calls super if defined and storing result to protect from GC until {#destroy}
340
340
  def init(*args)
341
- o = super(*args) if fuse_super_respond_to?(:init)
341
+ o = super if fuse_super_respond_to?(:init)
342
342
  handles << o if o
343
343
  end
344
344
 
@@ -23,7 +23,7 @@ module FFI
23
23
  }
24
24
  return wrappers unless defined?(super)
25
25
 
26
- super(*wrappers)
26
+ super
27
27
  end
28
28
 
29
29
  # @return [Integer] the default errno to return for rescued errors. ENOTRECOVERABLE unless overridden
@@ -41,7 +41,7 @@ module FFI
41
41
 
42
42
  def initialize(accounting: Accounting.new)
43
43
  @entries = {}
44
- super(accounting: accounting)
44
+ super
45
45
  end
46
46
 
47
47
  # @!endgroup
@@ -157,7 +157,7 @@ module FFI
157
157
  # TODO: Strictly should understand setgid and sticky bits of this dir's mode when creating new files
158
158
  new_file = file ? file.call(name) : new_file(name)
159
159
  if entry_fuse_respond_to?(new_file, :create)
160
- new_file.public_send(:create, '/', mode, ffi)
160
+ new_file.create('/', mode, ffi)
161
161
  else
162
162
  # TODO: generate a sensible device number
163
163
  entry_send(new_file, :mknod, '/', mode, 0)
@@ -20,7 +20,7 @@ module FFI
20
20
 
21
21
  # Create an empty synthetic file
22
22
  def initialize(accounting: nil)
23
- super(accounting: accounting)
23
+ super
24
24
  end
25
25
 
26
26
  # @!group FUSE Callbacks
@@ -12,7 +12,7 @@ module FFI
12
12
  include VirtualNode
13
13
  def initialize(accounting: nil)
14
14
  @target = target
15
- super(accounting: accounting)
15
+ super
16
16
  end
17
17
 
18
18
  def readlink(_path, size)
@@ -58,12 +58,12 @@ module FFI
58
58
  cmdline_opts = FuseCmdlineOpts.new
59
59
  raise Error unless Libfuse.fuse_parse_cmdline3(args, cmdline_opts).zero?
60
60
 
61
- handler&.fuse_debug(cmdline_opts.debug) if handler.respond_to?(:fuse_debug)
61
+ handler&.fuse_debug(cmdline_opts.debug?) if handler.respond_to?(:fuse_debug)
62
62
 
63
63
  # mimics fuse_main which exits after printing version info, even if -h
64
- if cmdline_opts.show_version
64
+ if cmdline_opts.show_version?
65
65
  show_version(handler)
66
- elsif cmdline_opts.show_help
66
+ elsif cmdline_opts.show_help?
67
67
  show_help(args, handler)
68
68
  end
69
69
 
@@ -145,8 +145,8 @@ module FFI
145
145
 
146
146
  private
147
147
 
148
- def native_fuse_loop_mt(max_idle_threads: 10, **_options)
149
- Libfuse.fuse_loop_mt3(@fuse, FuseLoopConfig.new.fill(max_idle: max_idle_threads))
148
+ def native_fuse_loop_mt(**options)
149
+ Libfuse.fuse_loop_mt3(@fuse, FuseLoopConfig.create(**options))
150
150
  end
151
151
 
152
152
  def unmount
@@ -3,13 +3,17 @@
3
3
  require_relative 'fuse_version'
4
4
  require_relative 'fuse_opt'
5
5
  require_relative '../ruby_object'
6
+ require_relative '../boolean_int'
7
+ require_relative '../accessors'
6
8
 
7
9
  module FFI
8
10
  # Ruby FFI Binding for [libfuse](https://github.com/libfuse/libfuse)
9
11
  module Libfuse
10
12
  # struct fuse_args
11
13
  class FuseArgs < FFI::Struct
12
- layout :argc, :int, :argv, :pointer, :allocated, :int
14
+ include FFI::Accessors
15
+
16
+ layout :argc, :int, :argv, :pointer, :allocated, :bool_int
13
17
 
14
18
  # Create a fuse_args struct from command line options
15
19
  # @param [Array<String>] argv command line args
@@ -34,33 +38,17 @@ module FFI
34
38
  @arg_vector[argv.size].put_pointer(0, FFI::Pointer::NULL)
35
39
  self[:argv] = @arg_vector
36
40
  self[:argc] = argv.size
37
- self[:allocated] = 0
41
+ self[:allocated] = false # ie libfuse did not allocate
38
42
  self
39
43
  end
40
44
 
41
- # @!attribute [r] argc
42
- # @return [Integer] count of args
43
- def argc
44
- self[:argc]
45
- end
46
-
47
45
  # @!attribute [r] argv
48
46
  # @return [Array<String>] list of args
49
- def argv
47
+ ffi_attr_reader(:argv) do
50
48
  # noinspection RubyResolve
51
49
  self[:argv].get_array_of_pointer(0, argc).map(&:read_string)
52
50
  end
53
51
 
54
- # @!visibility private
55
- def allocated
56
- self[:allocated]
57
- end
58
-
59
- # @!visibility private
60
- def inspect
61
- "#{self.class.name} - #{%i[argc argv allocated].to_h { |m| [m, send(m)] }}"
62
- end
63
-
64
52
  # Add an arg to this arg list
65
53
  # @param [String] arg
66
54
  def add(arg)
@@ -151,6 +139,8 @@ module FFI
151
139
  # Valid return values from parse! block
152
140
  FUSE_OPT_PROC_RETURN = { error: -1, keep: 1, handled: 0, discard: 0 }.freeze
153
141
 
142
+ ffi_attr_reader(:argc, :allocated?)
143
+
154
144
  def fuse_opt_proc(symbols, bool_opts, param_opts, ignore, &block)
155
145
  proc do |data, arg, key, out|
156
146
  key = symbols[key]
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../accessors'
4
+ require_relative '../boolean_int'
4
5
  require_relative 'fuse_loop_config'
5
6
  module FFI
6
7
  module Libfuse
7
- #
8
8
  # struct fuse_cmdline_opts {
9
9
  # int singlethread;
10
10
  # int foreground;
@@ -16,29 +16,32 @@ module FFI
16
16
  # int clone_fd;
17
17
  # unsigned int max_idle_threads;
18
18
  # };
19
+
20
+ # Command line options
19
21
  # @!visibility private
20
22
  class FuseCmdlineOpts < FFI::Struct
21
23
  include(FFI::Accessors)
22
24
 
23
- layout(
24
- single_thread: :int,
25
- foreground: :int,
26
- debug: :int,
27
- nodefault_subtype: :int,
25
+ spec = {
26
+ single_thread: :bool_int,
27
+ foreground: :bool_int,
28
+ debug: :bool_int,
29
+ nodefault_subtype: :bool_int,
28
30
  mountpoint: :string,
29
- show_version: :int,
30
- show_help: :int,
31
- clone_fd: :int,
32
- max_idle_threads: :int
33
- )
31
+ show_version: :bool_int,
32
+ show_help: :bool_int,
33
+ clone_fd: :bool_int,
34
+ max_idle_threads: :uint
35
+ }
36
+ spec[:max_threads] = :uint if FUSE_MINOR_VERSION >= 12
37
+
38
+ layout(spec)
34
39
 
35
- # int to booleans
36
- ffi_attr_reader(:single_thread, :foreground, :debug, :nodefault_subtype, :show_version, :show_help,
37
- :clone_fd) do |v|
38
- v != 0
39
- end
40
+ bool, = spec.partition { |_, v| v == :bool_int }
41
+ ffi_attr_reader(*bool.map { |k, _| "#{k}?" })
40
42
 
41
43
  ffi_attr_reader(:max_idle_threads, :mountpoint)
44
+ ffi_attr_reader(:max_threads) if FUSE_MINOR_VERSION >= 12
42
45
  end
43
46
  end
44
47
  end
@@ -10,7 +10,7 @@ module FFI
10
10
  # This structure is initialized from the arguments passed to fuse_new(), and then passed to the file system's init()
11
11
  # handler which should ensure that the configuration is compatible with the file system implementation.
12
12
  #
13
- # Some options can only be set via the filesystem init method (use_ino etc..) because the filesystem either
13
+ # Some options can only be set via the filesystem init method (:use_ino etc..) because the filesystem either
14
14
  # supports them or it doesn't.
15
15
  class FuseConfig < FFI::Struct
16
16
  include FFI::Accessors
@@ -40,7 +40,7 @@ module FFI
40
40
  # @!attribute [rw] negative_timeout
41
41
  # The timeout in seconds for which a negative lookup will be cached.
42
42
  #
43
- # This means, that if file did not exist (lookup retuned ENOENT), the lookup will only be redone after the
43
+ # This means, that if file did not exist (lookup returned ENOENT), the lookup will only be redone after the
44
44
  # timeout, and the file/directory will be assumed to not exist until then. A value of zero means that
45
45
  # negative lookups are not cached.
46
46
  #
@@ -55,7 +55,7 @@ module FFI
55
55
  # @return [Float]
56
56
  attr_timeout: :double,
57
57
 
58
- # @!attribute [rw] intr
58
+ # @!attribute [rw] intr?
59
59
  # Allow requests to be interrupted
60
60
  # @return [Boolean]
61
61
  intr: :bool_int,
@@ -80,7 +80,7 @@ module FFI
80
80
  # @return [Integer]
81
81
  remember: :int,
82
82
 
83
- # @!attribute [rw] hard_remove
83
+ # @!attribute [rw] hard_remove?
84
84
  # should open files be removed immediately
85
85
  #
86
86
  # The default behavior is that if an open file is deleted, the file is renamed to a hidden file
@@ -95,7 +95,7 @@ module FFI
95
95
  # @return [Boolean]
96
96
  hard_remove: :bool_int,
97
97
 
98
- # @!attribute [rw] use_ino
98
+ # @!attribute [rw] use_ino?
99
99
  # use filesystem provided inode values
100
100
  #
101
101
  # Honor the st_ino field in the functions getattr() and fill_dir(). This value is used to fill in the st_ino
@@ -109,8 +109,8 @@ module FFI
109
109
  # @return [Boolean]
110
110
  use_ino: :bool_int,
111
111
 
112
- # @!attribute [rw] readdir_ino
113
- # generate inodes for readdir even if {#use_ino} is set
112
+ # @!attribute [rw] readdir_ino?
113
+ # generate inodes for readdir even if {#use_ino?} is set
114
114
  #
115
115
  # If use_ino option is not given, still try to fill in the d_ino field in readdir(2). If the name was
116
116
  # previously looked up, and is still in the cache, the inode number found there will be used. Otherwise it
@@ -118,7 +118,7 @@ module FFI
118
118
  # @return [Boolean]
119
119
  readdir_ino: :bool_int,
120
120
 
121
- # @!attribute [rw] direct_io
121
+ # @!attribute [rw] direct_io?
122
122
  # disables the use of kernel page cache (file content cache) in the kernel for this filesystem.
123
123
  #
124
124
  # This has several affects:
@@ -135,13 +135,13 @@ module FFI
135
135
  # @return [Boolean]
136
136
  direct_io: :bool_int,
137
137
 
138
- # @!attribute [rw] kernel_cache
138
+ # @!attribute [rw] kernel_cache?
139
139
  # disables flushing the cache of the file contents on every open(2).
140
140
  #
141
141
  # This should only be enabled on filesystem where the file data is never changed externally (not through the
142
142
  # mounted FUSE filesystem). Thus it is not suitable for network filesystem and other intermediate filesystem.
143
143
  #
144
- # **Note**: if neither this option or {#direct_io} is specified data is still cached after the open(2),
144
+ # **Note**: if neither this option or {#direct_io?} is specified data is still cached after the open(2),
145
145
  # so a read(2) system call will not always initiate a read operation.
146
146
  #
147
147
  # Internally, enabling this option causes fuse to set {FuseFileInfo#keep_cache} overwriting any value that was
@@ -149,7 +149,7 @@ module FFI
149
149
  # @return [Boolean]
150
150
  kernel_cache: :bool_int,
151
151
 
152
- # @!attribute [rw] auto_cache
152
+ # @!attribute [rw] auto_cache?
153
153
  # invalidate cached data on open based on changes in file attributes
154
154
  #
155
155
  # This option is an alternative to `kernel_cache`. Instead of unconditionally keeping cached data, the cached
@@ -165,7 +165,7 @@ module FFI
165
165
  ac_attr_timeout_set: :bool_int,
166
166
  ac_attr_timeout: :double,
167
167
 
168
- # @!attribute [rw] nullpath_ok
168
+ # @!attribute [rw] nullpath_ok?
169
169
  # operations on open files and directories are ok to receive nil paths
170
170
  #
171
171
  # If this option is given the file-system handlers for the following operations will not receive path
@@ -185,21 +185,24 @@ module FFI
185
185
  layout(spec)
186
186
 
187
187
  # Find the attrs that have a corresponding setter (prefix set_ or suffix _set
188
+ # map attr => setter
188
189
  setters = spec.keys
189
- .map { |k| [k, k.to_s.sub(/^set_/, '').sub(/_set$/, '').to_sym] }
190
- .reject { |(s, a)| s == a }.to_h
190
+ .map { |k| [k.to_s.sub(/^set_/, '').sub(/_set$/, '').to_sym, k] }
191
+ .reject { |(s, a)| s == a }
192
+ .to_h
191
193
 
192
- setters.each do |(setter, attr)|
193
- ffi_attr_reader(attr) { |val| self[setter] ? val : nil }
194
+ ffi_attr_reader_method(*setters.keys) do
195
+ self[setters[__method__]] ? self[__method__] : nil
196
+ end
194
197
 
195
- ffi_attr_writer(attr) do |val|
196
- self[setter] = !val.nil?
197
- val || 0
198
- end
198
+ ffi_attr_writer_method(*setters.keys) do |val|
199
+ self[setters[__method__]] = !val.nil?
200
+ self[__method__] = val || 0
199
201
  end
200
202
 
201
- remaining = (spec.keys - setters.keys - setters.values).map { |a| spec[a] == :bool_int ? "#{a}?" : a }
202
- ffi_attr_accessor(*remaining)
203
+ ffi_attr_reader(:show_help?, :debug?)
204
+ remaining = (spec.keys - setters.keys - setters.values - %i[show_help modules debug])
205
+ ffi_attr_accessor(*remaining.map { |a| spec[a] == :bool_int ? "#{a}?" : a })
203
206
  end
204
207
  end
205
208
  end
@@ -326,7 +326,7 @@ module FFI
326
326
  # or unwanted
327
327
  # @return [Array<Symbol>]
328
328
  # @see capable
329
- ffi_attr_reader(:want, simple: false) do |*caps, **h|
329
+ ffi_attr_reader_method(:want) do |*caps, **h|
330
330
  next self[:want] if caps.empty? && h.empty?
331
331
 
332
332
  h.merge!(caps.pop) if caps.last.is_a?(Hash)
@@ -15,7 +15,8 @@ module FFI
15
15
  base[:umask] = :mode_t if FUSE_VERSION >= 28
16
16
  layout base
17
17
 
18
- ffi_attr_reader(*members, simple: false) do
18
+ # Define readers, safe from null access
19
+ ffi_attr_reader_method(*members) do
19
20
  m = __method__
20
21
 
21
22
  # Use overrides if they are available, or the default context if the underlying memory is invalid