Class: RFuse::Fuse

Inherits:
Object
  • Object
show all
Defined in:
ext/rfuse/rfuse.c,
lib/rfuse.rb,
ext/rfuse/rfuse.c

Overview

A FUSE filesystem - extend this class implementing the various abstract methods to provide your filesystem.

All file operations take a Context and a path as well as any other necessary parameters

Mount your filesystem by creating an instance of your subclass and call #loop to begin processing

Direct Known Subclasses

FuseDelegator

Instance Method Summary collapse

Constructor Details

#initialize(mountpoint, *options) ⇒ Object

initialize and mount the filesystem

Parameters:

  • mountpoint (String)

    The mountpoint

  • options (Array<String>)

    fuse arguments (-h to see a list)



1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
# File 'ext/rfuse/rfuse.c', line 1779

static VALUE rf_initialize(
  int argc,
  VALUE* argv,
  VALUE self)
{

  VALUE opts;
  VALUE first_opt;
  VALUE mountpoint_arg;
  VALUE mountpoint;
  struct intern_fuse *inf;
  int init_result;
  struct fuse_args *args;

  rb_scan_args(argc, argv, "1*",&mountpoint_arg, &opts);

  // Allow pre 1.0.6 style Fuse which forced options to be passed as an array
  if (RARRAY_LEN(opts) == 1) {
      first_opt = rb_ary_entry(opts,0);
      if (TYPE(first_opt) == T_ARRAY) {
         opts = first_opt;
      }
  }
  //Allow things like Pathname to be sent as a mountpoint
  mountpoint = rb_obj_as_string(mountpoint_arg);

  //Is this redundant if scan_args has populted opts?
  Check_Type(opts, T_ARRAY);

  Data_Get_Struct(self,struct intern_fuse,inf);

  inf->mountpoint = strdup(StringValueCStr(mountpoint));
  
  args = rarray2fuseargs(opts);

  if (RESPOND_TO(self,"getattr"))
    inf->fuse_op.getattr     = rf_getattr;
  if (RESPOND_TO(self,"readlink"))
    inf->fuse_op.readlink    = rf_readlink;
  if (RESPOND_TO(self,"getdir"))
    inf->fuse_op.getdir      = rf_getdir;  // Deprecated
  if (RESPOND_TO(self,"mknod"))
    inf->fuse_op.mknod       = rf_mknod;
  if (RESPOND_TO(self,"mkdir"))
    inf->fuse_op.mkdir       = rf_mkdir;
  if (RESPOND_TO(self,"unlink"))
    inf->fuse_op.unlink      = rf_unlink;
  if (RESPOND_TO(self,"rmdir"))
    inf->fuse_op.rmdir       = rf_rmdir;
  if (RESPOND_TO(self,"symlink"))
    inf->fuse_op.symlink     = rf_symlink;
  if (RESPOND_TO(self,"rename"))
    inf->fuse_op.rename      = rf_rename;
  if (RESPOND_TO(self,"link"))
    inf->fuse_op.link        = rf_link;
  if (RESPOND_TO(self,"chmod"))
    inf->fuse_op.chmod       = rf_chmod;
  if (RESPOND_TO(self,"chown"))
    inf->fuse_op.chown       = rf_chown;
  if (RESPOND_TO(self,"truncate"))
    inf->fuse_op.truncate    = rf_truncate;
  if (RESPOND_TO(self,"utime"))
    inf->fuse_op.utime       = rf_utime;    // Deprecated
  if (RESPOND_TO(self,"open")) {
    inf->fuse_op.open        = rf_open;
    inf->fuse_op.release     = rf_release_ffi; // remove open file reference
  }
  if (RESPOND_TO(self,"create")) {
    inf->fuse_op.create      = rf_create;
    inf->fuse_op.release     = rf_release_ffi; // remove open file reference
  }
  if (RESPOND_TO(self,"read"))
    inf->fuse_op.read        = rf_read;
  if (RESPOND_TO(self,"write"))
    inf->fuse_op.write       = rf_write;
  if (RESPOND_TO(self,"statfs"))
    inf->fuse_op.statfs      = rf_statfs;
  if (RESPOND_TO(self,"flush"))
    inf->fuse_op.flush       = rf_flush;
  if (RESPOND_TO(self,"release"))
    inf->fuse_op.release     = rf_release;
  if (RESPOND_TO(self,"fsync"))
    inf->fuse_op.fsync       = rf_fsync;
  if (RESPOND_TO(self,"setxattr"))
    inf->fuse_op.setxattr    = rf_setxattr;
  if (RESPOND_TO(self,"getxattr"))
    inf->fuse_op.getxattr    = rf_getxattr;
  if (RESPOND_TO(self,"listxattr"))
    inf->fuse_op.listxattr   = rf_listxattr;
  if (RESPOND_TO(self,"removexattr"))
    inf->fuse_op.removexattr = rf_removexattr;
  if (RESPOND_TO(self,"opendir")) {
    inf->fuse_op.opendir     = rf_opendir;
    inf->fuse_op.release     = rf_release_ffi; // remove open file reference
  }
  if (RESPOND_TO(self,"readdir"))
    inf->fuse_op.readdir     = rf_readdir;
  if (RESPOND_TO(self,"releasedir"))
    inf->fuse_op.releasedir  = rf_releasedir;
  if (RESPOND_TO(self,"fsyncdir"))
    inf->fuse_op.fsyncdir    = rf_fsyncdir;
  if (RESPOND_TO(self,"init"))
    inf->fuse_op.init        = rf_init;
  if (RESPOND_TO(self,"access"))
    inf->fuse_op.access      = rf_access;
  if (RESPOND_TO(self,"ftruncate"))
    inf->fuse_op.ftruncate   = rf_ftruncate;
  if (RESPOND_TO(self,"fgetattr"))
    inf->fuse_op.fgetattr    = rf_fgetattr;
  if (RESPOND_TO(self,"lock"))
    inf->fuse_op.lock        = rf_lock;
  if (RESPOND_TO(self,"utimens"))
    inf->fuse_op.utimens     = rf_utimens;
  if (RESPOND_TO(self,"bmap"))
    inf->fuse_op.bmap        = rf_bmap;
#ifdef RFUSE_BROKEN
  if (RESPOND_TO(self,"ioctl"))
    inf->fuse_op.ioctl       = rf_ioctl;
  if (RESPOND_TO(self,"poll"))
    inf->fuse_op.poll        = rf_poll;
#endif


  // init_result indicates not mounted, but so does inf->fuse == NULL
  // raise exceptions only if we try to use the mount
  // can test with mounted?
  // Note we are storing this Ruby object as the FUSE user_data
  init_result = intern_fuse_init(inf, args, (void *) self);

  //Create the open files hash where we cache FileInfo objects
  if (init_result == 0) {
    VALUE open_files_hash;
    open_files_hash=rb_hash_new();
    rb_iv_set(self,"@open_files",open_files_hash);
    rb_funcall(self,rb_intern("ruby_initialize"),0);
  }
  return self;
}

Instance Method Details

#access(context, path, mode) ⇒ void

This method is abstract.

Fuse operation access

This method returns an undefined value.

Check access permissions

Parameters:

  • context (Context)
  • path (String)
  • mode (Integer)

    the permissions to check

Raises:

  • (Errno::EACCESS)

    if the requested permission isn't available



1287
1288
1289
1290
# File 'ext/rfuse/rfuse.c', line 1287

static VALUE unsafe_access(VALUE* args)
{
  return rb_funcall3(args[0],rb_intern("access"),3,&args[1]);
}

#bmap(context, path, blocksize, index) ⇒ Integer

This method is abstract.

Fuse operation bmap

Map block index within file to block index within device

Note: This makes sense only for block device backed filesystems mounted with the 'blkdev' option

Parameters:

  • context (Context)
  • path (String)
  • blocksize (Integer)
  • index (Integer)

Returns:

  • (Integer)

    device relative block index

Raises:

  • (Errno)


1557
1558
1559
1560
# File 'ext/rfuse/rfuse.c', line 1557

static VALUE unsafe_bmap(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("bmap"),4,&args[1]);
}

#chmod(context, path, mode) ⇒ void

This method is abstract.

Fuse operation chmod

This method returns an undefined value.

Change file permissions

Parameters:

  • context (Context)
  • path (String)
  • mode (Integer)

Raises:

  • (Errno)


601
602
603
604
# File 'ext/rfuse/rfuse.c', line 601

static VALUE unsafe_chmod(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("chmod"),3,&args[1]);
}

#chown(context, path, uid, gid) ⇒ void

This method is abstract.

Fuse operation chown

This method returns an undefined value.

Change file ownership

Parameters:

  • context (Context)
  • path (String)
  • uid (Integer)

    new user id

  • gid (Integer)

    new group id

Raises:

  • (Errno)


569
570
571
572
# File 'ext/rfuse/rfuse.c', line 569

static VALUE unsafe_chown(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("chown"),4,&args[1]);
}

#create(context, path, mode, ffi) ⇒ void

This method is abstract.

Fuse operation create

This method returns an undefined value.

Create and open a file

If the file does not exist, first create it with the specified mode, and then open it.

Parameters:

  • context (Context)
  • path (String)
  • mode (Integer)

    the file permissions to create

  • ffi (Fileinfo)

Raises:

  • (Errno)


1321
1322
1323
1324
# File 'ext/rfuse/rfuse.c', line 1321

static VALUE unsafe_create(VALUE* args)
{
  return rb_funcall3(args[0],rb_intern("create"),4,&args[1]);
}

#exitObject

Stop processing #loop eg called from signal handlers, or some other monitoring thread



348
349
350
351
# File 'lib/rfuse.rb', line 348

def exit
    @running = false
    send_signal(-1)
end

#fdInteger

Returns /dev/fuse file descriptor for use with IO.select and #process.

Returns:

  • (Integer)

    /dev/fuse file descriptor for use with IO.select and #process

Raises:



1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
# File 'ext/rfuse/rfuse.c', line 1737

VALUE rf_fd(VALUE self)
{
 struct intern_fuse *inf;
 Data_Get_Struct(self,struct intern_fuse,inf);
 if (inf->fuse == NULL) {
   rb_raise(eRFuse_Error,"FUSE not mounted");
   return Qnil;
 } else {
   return INT2NUM(intern_fuse_fd(inf));
 }
}

#fgetattr(context, path, ffi) ⇒ Stat

This method is abstract.

Fuse operation fgetattr

Get attributes of an open file

Parameters:

  • context (Context)
  • path (String)
  • ffi (Fileinfo)

Returns:

  • (Stat)

    file attributes

Raises:

  • (Errno)


1392
1393
1394
1395
# File 'ext/rfuse/rfuse.c', line 1392

static VALUE unsafe_fgetattr(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("fgetattr"),3,&args[1]);
}

#flush(context, path, ffi) ⇒ void

This method is abstract.

Fuse operation flush

This method returns an undefined value.

Possibly flush cached data

BIG NOTE: This is not equivalent to fsync(). It's not a request to sync dirty data.

Flush is called on each close() of a file descriptor. So if a filesystem wants to return write errors in close() and the file has cached dirty data, this is a good place to write back data and return any errors. Since many applications ignore close() errors this is not always useful.

NOTE: The flush() method may be called more than once for each open(). This happens if more than one file descriptor refers to an opened file due to dup(), dup2() or fork() calls. It is not possible to determine if a flush is final, so each flush should be treated equally. Multiple write-flush sequences are relatively rare, so this shouldn't be a problem.

Filesystems shouldn't assume that flush will always be called after some writes, or that if will be called at all.

Parameters:

Raises:

  • (Errno)


471
472
473
474
# File 'ext/rfuse/rfuse.c', line 471

static VALUE unsafe_flush(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("flush"),3,&args[1]);
}

#fsync(context, path, datasync, ffi) ⇒ void

This method is abstract.

Fuse operation fsync

This method returns an undefined value.

Synchronize file contents

Parameters:

  • context (Context)
  • path (String)
  • datasync (Integer)

    if non-zero, then only user data should be flushed, not the metadata

  • ffi (FileInfo)

Raises:

  • (Errno)


428
429
430
# File 'ext/rfuse/rfuse.c', line 428

static VALUE unsafe_fsync(VALUE *args) {
  return rb_funcall3(args[0],rb_intern("fsync"),4,&args[1]);
}

#fsyncdir(context, path, datasync, ffi) ⇒ void

This method is abstract.

Fuse operation fsyncdir

This method returns an undefined value.

Sync directory

Parameters:

  • context (Context)
  • path (String)
  • datasync (Integer)

    if nonzero sync only data, not metadata

  • ffi (FileInfo)

Raises:

  • (Errno)


1191
1192
1193
1194
# File 'ext/rfuse/rfuse.c', line 1191

static VALUE unsafe_fsyncdir(VALUE *args)
{
  return rb_funcall2(args[0],rb_intern("fsyncdir"),4,&args[1]);
}

#ftruncate(context, path, size, ffi) ⇒ void

This method is abstract.

Fuse operation ftruncate

This method returns an undefined value.

Change the size of an open file

Parameters:

  • context (Context)
  • path (String)
  • size (Integer)
  • ffi (Fileinfo)

Raises:

  • (Errno)


1357
1358
1359
1360
# File 'ext/rfuse/rfuse.c', line 1357

static VALUE unsafe_ftruncate(VALUE* args)
{
  return rb_funcall3(args[0],rb_intern("ftruncate"),4,&args[1]);
}

#getattr(context, path) ⇒ Stat

This method is abstract.

Fuse operation getattr

Get file attributes. Similar to stat(). The 'st_dev' and 'st_blksize' fields are ignored. The 'st_ino' field is ignored except if the 'use_ino' mount option is given.

Parameters:

Returns:

  • (Stat)

    or something that quacks like a stat, or nil if the path does not exist

Raises:

  • (Errno)


267
268
269
270
# File 'ext/rfuse/rfuse.c', line 267

static VALUE unsafe_getattr(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("getattr"),2,&args[1]);
}

#getdirObject

Deprecated.
This method is abstract.

Fuse operation getdir



179
180
181
182
# File 'ext/rfuse/rfuse.c', line 179

static VALUE unsafe_getdir(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("getdir"),3,&args[1]);
}

#getxattr(context, path, name) ⇒ String

This method is abstract.

Fuse operation getxattr

Get extended attribute

Parameters:

  • context (Context)
  • path (String)
  • name (String)

Returns:

  • (String)

    attribute value

Raises:

  • (Errno)

    Errno::ENOATTR if attribute does not exist



994
995
996
997
998
999
1000
# File 'ext/rfuse/rfuse.c', line 994

static VALUE unsafe_getxattr(VALUE *args)
{
  VALUE res;
  res = rb_funcall3(args[0],rb_intern("getxattr"),3,&args[1]);
  //TODO - exception won't should that we're calling getxattr
  return StringValue(res);
}

#init(info) ⇒ void

This method is abstract.

Fuse Operation init

This method returns an undefined value.

Called when filesystem is initialised

Parameters:

  • context (Context)
  • info (Struct)

    connection information



1220
1221
1222
1223
# File 'ext/rfuse/rfuse.c', line 1220

static VALUE unsafe_init(VALUE* args)
{
  return rb_funcall3(args[0],rb_intern("init"),2,&args[1]);
}

#invalidate(path) ⇒ Object

Deprecated.

obsolete in FUSE itself



1726
1727
1728
1729
1730
1731
# File 'ext/rfuse/rfuse.c', line 1726

VALUE rf_invalidate(VALUE self,VALUE path)
{
  struct intern_fuse *inf;
  Data_Get_Struct(self,struct intern_fuse,inf);
  return fuse_invalidate(inf->fuse,StringValueCStr(path)); 
}
This method is abstract.

Fuse operation link

This method returns an undefined value.

Create a hard link to file

Parameters:

  • context (Context)
  • from (String)
  • to (String)

Raises:

  • (Errno)


759
760
761
762
# File 'ext/rfuse/rfuse.c', line 759

static VALUE unsafe_link(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("link"),3,&args[1]);
}

#listxattr(context, path) ⇒ Array<String>

This method is abstract.

Fuse operation listxattr

List extended attributes

Parameters:

Returns:

  • (Array<String>)

    list of attribute names

Raises:

  • (Errno)


1042
1043
1044
1045
1046
1047
1048
1049
1050
# File 'ext/rfuse/rfuse.c', line 1042

static VALUE unsafe_listxattr(VALUE *args)
{
  VALUE res;
  res = rb_funcall3(args[0],rb_intern("listxattr"),2,&args[1]);

  //We'll let Ruby do the hard work of creating a String
  //separated by NULLs
  return rb_funcall(mRFuse,rb_intern("packxattr"),1,res);
}

#lock(context, path, ffi, cmd, flock) ⇒ void

This method is abstract.

Fuse operation lock

TODO:

Some of the attributes of the flock struct should be writable

This method returns an undefined value.

Perform POSIX file locking operation

The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.

For the meaning of fields in 'struct flock' see the man page for fcntl(2). The l_whence field will always be set to SEEK_SET.

For checking lock ownership, the FileInfo#owner argument must be used. (NOT YET IMPLEMENTED)

For F_GETLK operation, the library will first check currently held locks, and if a conflicting lock is found it will return information without calling this method. This ensures, that for local locks the l_pid field is correctly filled in. The results may not be accurate in case of race conditions and in the presence of hard links, but it's unlikly that an application would rely on accurate GETLK results in these cases. If a conflicting lock is not found, this method will be called, and the filesystem may fill out l_pid by a meaningful value, or it may leave this field zero.

For F_SETLK and F_SETLKW the l_pid field will be set to the pid of the process performing the locking operation.

Note: if this method is not implemented, the kernel will still allow file locking to work locally. Hence it is only interesting for network filesystems and similar.

Parameters:

  • context (Context)
  • path (String)
  • ffi (Fileinfo)
  • cmd (Integer)
  • flock (Struct)

Raises:

  • (Errno)


1447
1448
1449
1450
# File 'ext/rfuse/rfuse.c', line 1447

static VALUE unsafe_lock(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("lock"),5,&args[1]);
}

#loopvoid

This method returns an undefined value.

Main processing loop

Use #exit to stop processing (or externally call fusermount -u)

Other ruby threads can continue while loop is running, however no thread can operate on the filesystem itself (ie with File or Dir methods)

Raises:



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/rfuse.rb', line 310

def loop()
    raise RFuse::Error, "Already running!" if @running
    raise RFuse::Error, "FUSE not mounted" unless mounted?
    @running = true
    while @running do
        begin
            ready, ignore, errors  = IO.select([@fuse_io,@pr],[],[@fuse_io])

            if ready.include?(@pr)

                signo = @pr.read_nonblock(1).unpack("c")[0]

                # Signal.signame exist in Ruby 2, but returns horrible errors for non-signals in 2.1.0
                if (signame = Signal.list.invert[signo])
                    call_sigmethod(sigmethod(signame))
                end

            elsif errors.include?(@fuse_io)

                @running = false
                raise RFuse::Error, "FUSE error"

            elsif ready.include?(@fuse_io)
                if process() < 0
                    # Fuse has been unmounted externally
                    # TODO: mounted? should now return false
                    # fuse_exited? is not true...
                    @running = false
                end
            end
        rescue Errno::EWOULDBLOCK, Errno::EAGAIN
            #oh well...
        end
    end
end

#mkdir(context, path, mode) ⇒ void

This method is abstract.

Fuse operation mkdir

This method returns an undefined value.

Create a directory

Parameters:

  • context (Context)
  • path (String)
  • mode (Integer)

    to obtain correct directory permissions use mode | Stat::S_IFDIR

Raises:

  • (Errno)


312
313
314
315
# File 'ext/rfuse/rfuse.c', line 312

static VALUE unsafe_mkdir(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("mkdir"),3,&args[1]);
}

#mknod(context, path, mode, major, minor) ⇒ Object

This method is abstract.

Fuse Operation mknod

Create a file node @return[void]

This is called for creation of all non-directory, non-symlink nodes. If the filesystem defines #create, then for regular files that will be called instead.

Parameters:

  • context (Context)
  • path (String)
  • mode (Integer)

    type & permissions

  • major (Integer)
  • minor (Integer)


230
231
232
233
# File 'ext/rfuse/rfuse.c', line 230

static VALUE unsafe_mknod(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("mknod"),5,&args[1]);
}

#mounted?Boolean

Is the filesystem successfully mounted

Returns:

  • (Boolean)

    true if mounted, false otherwise



1677
1678
1679
1680
1681
1682
1683
1684
# File 'ext/rfuse/rfuse.c', line 1677

static VALUE rf_mounted(VALUE self)
{
  struct intern_fuse *inf;
  Data_Get_Struct(self,struct intern_fuse,inf);
 
  // Never mounted, unmounted via fusermount, or via rf_unmount
  return (inf->fuse == NULL || fuse_exited(inf->fuse) ) ? Qfalse : Qtrue; 
}

#mountnameString Also known as: mountpoint

Returns directory where this filesystem is mounted.

Returns:

  • (String)

    directory where this filesystem is mounted



1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
# File 'ext/rfuse/rfuse.c', line 1710

VALUE rf_mountname(VALUE self)
{
  struct intern_fuse *inf;
  VALUE result;
  
  Data_Get_Struct(self,struct intern_fuse,inf);

  result = rb_str_new2(inf->mountpoint);
  rb_filesystem_encode(result);

  return result;
}

#open(context, path, ffi) ⇒ void

This method is abstract.

Fuse operation open

This method returns an undefined value.

File open operation

Parameters:

  • context (Context)
  • path (String)
  • ffi (FileInfo)

    file open flags etc. The fh attribute may be used to store an arbitrary filehandle object which will be passed to all subsequent operations on this file

Raises:

  • (Errno::ENOPERM)

    if user is not permitted to open the file

  • (Errno)

    for other errors



347
348
349
350
# File 'ext/rfuse/rfuse.c', line 347

static VALUE unsafe_open(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("open"),3,&args[1]);
}

#opendir(context, path, name) ⇒ void

This method is abstract.

Fuse operation opendir

This method returns an undefined value.

Open directory

Unless the 'default_permissions' mount option is given, this method should check if opendir is permitted for this directory. Optionally opendir may also return an arbitrary filehandle in the fuse_file_info structure, which will be available to #readdir, #fsyncdir, #releasedir.

Parameters:

Raises:

  • (Errno)


1126
1127
1128
1129
# File 'ext/rfuse/rfuse.c', line 1126

static VALUE unsafe_opendir(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("opendir"),3,&args[1]);
}

#processInteger

Process one fuse command from the kernel

Returns:

  • (Integer)

    0 if successful

Raises:



1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
# File 'ext/rfuse/rfuse.c', line 1755

VALUE rf_process(VALUE self)
{
 struct intern_fuse *inf;
 Data_Get_Struct(self,struct intern_fuse,inf);
 if (inf->fuse == NULL) {
   rb_raise(eRFuse_Error,"FUSE not mounted");
   return Qnil;
 } else {
    return INT2NUM(intern_fuse_process(inf));
 }
}

#read(context, path, size, offset, ffi) ⇒ String

This method is abstract.

Fuse operation read

Read data from an open file

Parameters:

  • context (Context)
  • path (String)
  • size (Integer)
  • offset (Integer)
  • ffi (FileInfo)

Returns:

  • (String)

    should be exactly the number of bytes requested, or empty string on EOF

Raises:

  • (Errno)


794
795
796
797
798
799
800
801
802
# File 'ext/rfuse/rfuse.c', line 794

static VALUE unsafe_read(VALUE *args)
{
  VALUE res;
  
  res = rb_funcall3(args[0],rb_intern("read"),5,&args[1]);
  //TODO If res does not implement to_str then you'll get an exception here that
  //is hard to debug
  return StringValue(res);
}

#readdir(context, path, filler, offset, ffi) ⇒ void

This method is abstract.

Fuse operation readdir

TODO:

the API for the filler could be more ruby like - eg yield

This method returns an undefined value.

List contents of a directory

Parameters:

Raises:

  • (Errno)


101
102
103
104
# File 'ext/rfuse/rfuse.c', line 101

static VALUE unsafe_readdir(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("readdir"),5,&args[1]);
}
This method is abstract.

Fuse operation readlink

Resolve target of symbolic link

Parameters:

  • context (Context)
  • path (String)
  • size (Integer)

    if the resolved path is greater than this size it should be truncated

Returns:

  • (String)

    the resolved link path

Raises:

  • (Errno)


146
147
148
149
# File 'ext/rfuse/rfuse.c', line 146

static VALUE unsafe_readlink(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("readlink"),3,&args[1]);
}

#release(context, path, ffi) ⇒ void

This method is abstract.

Fuse operation release

This method returns an undefined value.

Release an open file

Release is called when there are no more references to an open file: all file descriptors are closed and all memory mappings are unmapped.

For every #open call there will be exactly one #release call with the same flags and file descriptor. It is possible to have a file opened more than once, in which case only the last release will mean, that no more reads/writes will happen on the file.

Parameters:



394
395
396
397
# File 'ext/rfuse/rfuse.c', line 394

static VALUE unsafe_release(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("release"),3,&args[1]);
}

#releasedir(context, path, ffi) ⇒ void

This method is abstract.

Fuse operation releasedir

This method returns an undefined value.

Release directory

Parameters:

Raises:

  • (Errno)


1157
1158
1159
1160
# File 'ext/rfuse/rfuse.c', line 1157

static VALUE unsafe_releasedir(VALUE *args)
{
 return rb_funcall3(args[0],rb_intern("releasedir"),3,&args[1]);
}

#removexattr(context, path, name) ⇒ void

This method is abstract.

Fuse operation removexattr

This method returns an undefined value.

Remove extended attribute

Parameters:

  • context (Context)
  • path (String)
  • name (String)

    attribute to remove

Raises:

  • (Errno)


1092
1093
1094
1095
# File 'ext/rfuse/rfuse.c', line 1092

static VALUE unsafe_removexattr(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("removexattr"),3,&args[1]);
}

#rename(context, from, to) ⇒ void

This method is abstract.

Fuse operation rename

This method returns an undefined value.

Rename the file, directory, or other object "from" to the target "to". Note that the source and target don't have to be in the same directory, so it may be necessary to move the source to an entirely new directory. See rename(2) for full details.

Parameters:

  • context (Context)
  • from (String)
  • to (String)

Raises:

  • (Errno)


725
726
727
728
# File 'ext/rfuse/rfuse.c', line 725

static VALUE unsafe_rename(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("rename"),3,&args[1]);
}

#run(signals = Signal.list.keys) ⇒ void

This method returns an undefined value.

Convenience method to run a mounted filesystem to completion.

Parameters:

  • signals (Array<String|Integer>) (defaults to: Signal.list.keys)

    list of signals to handle. Default is all available signals. See #trap_signals

See Also:

Since:

  • 1.1.0



289
290
291
292
293
294
295
296
297
298
299
# File 'lib/rfuse.rb', line 289

def run(signals=Signal.list.keys)
    if mounted?
        begin
            traps = trap_signals(*signals)
            self.loop()
        ensure
            traps.each { |t| Signal.trap(t,"DEFAULT") }
            unmount()
        end
    end
end

#setxattr(context, path, name, data, flags) ⇒ void

This method is abstract.

Fuse operation setxattr

This method returns an undefined value.

Set extended attributes

Parameters:

  • context (Context)
  • path (String)
  • name (String)
  • data (String)
  • flags (Integer)

Raises:

  • (Errno)


957
958
959
960
# File 'ext/rfuse/rfuse.c', line 957

static VALUE unsafe_setxattr(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("setxattr"),5,&args[1]);
}

#sigtermvoid Also known as: sigint

This method returns an undefined value.

Default signal handler to exit on TERM/INT

See Also:



401
402
403
# File 'lib/rfuse.rb', line 401

def sigterm
    @running = false
end

#statfs(context, path) ⇒ StatVfs

This method is abstract.

Fuse operation statfs

Get file system statistics

The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored

Parameters:

Returns:

  • (StatVfs)

    or something that quacks like a statVfs

Raises:

  • (Errno)


914
915
916
917
# File 'ext/rfuse/rfuse.c', line 914

static VALUE unsafe_statfs(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("statfs"),2,&args[1]);
}
This method is abstract.

Fuse operation symlink

This method returns an undefined value.

Create a symbolic link

Create a symbolic link named "from" which, when evaluated, will lead to "to".

Parameters:

  • context (Context)
  • to (String)
  • from (String)

Raises:

  • (Errno)


692
693
694
# File 'ext/rfuse/rfuse.c', line 692

static VALUE unsafe_symlink(VALUE *args){
  return rb_funcall3(args[0],rb_intern("symlink"),3,&args[1]);
}

#trap_signals(*signames) ⇒ Array<String>

Set traps

The filesystem supports a signal by providing a sig<name> method. eg #sigint

The fuse #loop is notified of the signal via the self-pipe trick, and calls the corresponding sig<name> method, after any current filesystem operation completes.

This method will not override traps that have previously been set to something other than "DEFAULT"

Note: RFuse::Fuse itself provides #sigterm and #sigint.

Examples:

class MyFS < Fuse
   def sighup()
       # do something on HUP signal
   end
end

fuse = MyFS.new(*args)

if fuse.mounted?
    # Below will result in (effectively) Signal.trap("HUP") { fuse.sighup() }
    fuse.trap_signals("HUP","USR1") # ==> ["HUP"]
    fuse.loop()
end

Parameters:

  • signames (Array<String>)

    List of signal names to set traps for, if the filesystem has methods to handle them. Use Signal.list.keys to try all available signals.

Returns:

  • (Array<String>)

    List of signal names that traps have been set for.

Since:

  • 1.1.0



387
388
389
390
391
392
393
394
395
396
# File 'lib/rfuse.rb', line 387

def trap_signals(*signames)
    signames.map { |n| n.to_s.upcase }.map { |n| n.start_with?("SIG") ? n[3..-1] : n }.select do |signame|
        next false unless respond_sigmethod?(sigmethod(signame)) && signo = Signal.list[signame]

        next true if (prev = Signal.trap(signo) { |signo| send_signal(signo) }) == "DEFAULT"

        Signal.trap(signo,prev)
        false
    end
end

#truncate(context, path, offset) ⇒ void

This method is abstract.

Fuse operation truncate

This method returns an undefined value.

Change the size of a file

Parameters:

  • context (Context)
  • path (String)
  • offset (Integer)

Raises:

  • (Errno)


501
502
503
504
# File 'ext/rfuse/rfuse.c', line 501

static VALUE unsafe_truncate(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("truncate"),3,&args[1]);
}
This method is abstract.

Fuse operation unlink

This method returns an undefined value.

Remove a file

Parameters:

Raises:

  • (Errno)


631
632
633
634
# File 'ext/rfuse/rfuse.c', line 631

static VALUE unsafe_unlink(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("unlink"),2,&args[1]);
}

#unmountObject

Unmount filesystem



1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
# File 'ext/rfuse/rfuse.c', line 1689

VALUE rf_unmount(VALUE self)
{
  struct intern_fuse *inf;
  Data_Get_Struct(self,struct intern_fuse,inf);

  rb_funcall(self,rb_intern("ruby_unmount"),0);

  if (inf->fuse != NULL)  {
      fuse_exit(inf->fuse);
  }

  if (inf->fc != NULL) {
      fuse_unmount(inf->mountpoint, inf->fc);
      inf->fc = NULL;
  }
  return Qnil;
}

#utime(context, path, actime, modtime) ⇒ void

Deprecated.
This method is abstract.

Fuse operation utime

This method returns an undefined value.

Change access/modification times of a file

Parameters:

  • context (Context)
  • path (String)
  • actime (Integer)

    access time

  • modtime (Integer)

    modification time

Raises:

  • (Errno)


534
535
536
537
# File 'ext/rfuse/rfuse.c', line 534

static VALUE unsafe_utime(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("utime"),4,&args[1]);
}

#utimens(context, path, actime, modtime) ⇒ void

This method is abstract.

Fuse operation utimens

This method returns an undefined value.

Change access/modification times of a file

Parameters:

  • context (Context)
  • path (String)
  • actime (Integer)

    access time in nanoseconds

  • modtime (Integer)

    modification time in nanoseconds

Raises:

  • (Errno)


1508
1509
1510
1511
# File 'ext/rfuse/rfuse.c', line 1508

static VALUE unsafe_utimens(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("utimens"),4,&args[1]);
}

#write(context, path, data, offset, ffi) ⇒ Integer

This method is abstract.

Fuse operation write

Write data to an open file

Parameters:

  • context (Context)
  • path (String)
  • data (String)
  • offset (Integer)
  • ffi (FileInfo)

Returns:

  • (Integer)

    exactly the number of bytes requested except on error

Raises:

  • (Errno)


870
871
872
873
# File 'ext/rfuse/rfuse.c', line 870

static VALUE unsafe_write(VALUE *args)
{
  return rb_funcall3(args[0],rb_intern("write"),5,&args[1]);
}