Class: FFI::Libfuse::Adapter::Ruby::ReaddirFiller

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/libfuse/adapter/ruby.rb

Overview

Helper class for FuseOperations#readdir

Examples:

def readdir(path, buf, filler, _offset, _ffi, *flags)
  rdf = FFI::Adapter::Ruby::ReaddirFiller.new(buf, filler)
  %w[. ..].each { |dot_entry| rdf.fill(dot_entry) }
  entries.each { |entry| rdf.fill(entry) }
end
# short version
def readdir(path, buf, filler, _offset, _ffi, *flags)
  %w[. ..].concat(entries).each(&FFI::Adapter::Ruby::ReaddirFiller.new(buf,filler))
end

Instance Method Summary collapse

Constructor Details

#initialize(buf, filler, fuse3: FUSE_MAJOR_VERSION >= 3) ⇒ ReaddirFiller

Returns a new instance of ReaddirFiller.

Parameters:

  • buf (FFI::Pointer)
  • filler (FFI::Function)
  • fuse3 (Boolean) (defaults to: FUSE_MAJOR_VERSION >= 3)

    does the filler function expect fuse 3 compatibility



44
45
46
47
48
49
# File 'lib/ffi/libfuse/adapter/ruby.rb', line 44

def initialize(buf, filler, fuse3: FUSE_MAJOR_VERSION >= 3)
  @buf = buf
  @filler = filler
  @stat_buf = nil
  @fuse3 = fuse3
end

Instance Method Details

#fill(name, stat: nil, offset: 0, fill_dir_plus: false) ⇒ Boolean

Returns true if the buffer accepted the entry.

Parameters:

  • name (String)

    a directory entry

  • stat (FFI::Stat|Hash<Symbol,Integer>|nil) (defaults to: nil)

    or stat fields to fill a Stat

    Note sending nil values will cause Fuse to issue #getattr operations for each entry

    It is safe to reuse the same Stat object between calls

  • offset (Integer) (defaults to: 0)
  • fill_dir_plus (Boolean) (defaults to: false)

    true if stat has full attributes for inode caching

Returns:

  • (Boolean)

    true if the buffer accepted the entry

Raises:

  • (StopIteration)

    if called after a previous call returned false



72
73
74
75
76
77
78
79
80
81
# File 'lib/ffi/libfuse/adapter/ruby.rb', line 72

def fill(name, stat: nil, offset: 0, fill_dir_plus: false)
  raise StopIteration unless @buf

  fill_flags = fill_flags(fill_dir_plus: fill_dir_plus)
  fill_stat = fill_stat(stat)
  return true if @filler.call(@buf, name, fill_stat, offset, *fill_flags).zero?

  @buf = nil
  false
end

#readdir_fh(dir_handle, offset = 0) ⇒ Object

Fill readdir from a directory handle

Parameters:

  • dir_handle (#seek, #read, #tell)
  • offset (Integer) (defaults to: 0)

Raises:

  • (Errno::ENOTSUP)

    unless dir_handle quacks like ::Dir



55
56
57
58
59
60
# File 'lib/ffi/libfuse/adapter/ruby.rb', line 55

def readdir_fh(dir_handle, offset = 0)
  raise Errno::ENOTSUP unless %i[seek read tell].all? { |m| dir_handle.respond_to?(m) }

  dir_handle.seek(offset)
  loop while (name = dir_handle.read) && fill(name, offset: dir_handle.tell)
end

#to_procProc

Returns a proc to pass to something that yields like ##fill.

Returns:

  • (Proc)

    a proc to pass to something that yields like ##fill



84
85
86
87
88
# File 'lib/ffi/libfuse/adapter/ruby.rb', line 84

def to_proc
  proc do |name, stat: nil, offset: 0, fill_dir_plus: false|
    fill(name, stat: stat, offset: offset, fill_dir_plus: fill_dir_plus)
  end
end