Hi,

I try to implement an interface for fuse with ruby but fail to a strange 
  error.

You probably won't try this code because you'd have to install fuse to 
test it so I give some comments:

I'd like to implement this as an extension so the testcode should look 
like this:

#!/usr/bin/ruby
require("RFuse")

class RFuse
   def getdir(path,filler)
     Dir.foreach(path) {|x| filler.push(x,8)}
   end
   def getattr(path)
   end
end

fo=RFuse.new
begin
   fo.main
rescue
   f=File.new("/tmp/error","w+")
   f.puts "Error:" + $!
   f.close
end

The user should just extend the class with some methods which will be 
called back by fuse. So I have to wrap the callbacks. The interesting 
line is at ***.

#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif
//FOR LINUX ONLY
#include <linux/stat.h>

#include <ruby.h>
#include <fuse.h>
#include <errno.h>
#include <sys/statfs.h>
#ifdef HAVE_SETXATTR
#include <sys/xattr.h>
#endif


//This is a wrapper around the filler callback function
struct fill_t {
   fuse_dirfil_t filler;
   fuse_dirh_t handler;
};

static VALUE rfill_new(VALUE class){
   VALUE self;
   struct fill_t *filler;
   self = Data_Make_Struct(class, struct fill_t, 0,free,filler);
   return self;
}

static VALUE rfill_push(VALUE self,VALUE name, VALUE type) {
   struct fill_t *fill;
   Data_Get_Struct(self,struct fill_t,fill);
   fill->filler(fill->handler,STR2CSTR(name),NUM2INT(type));
   return self;
}

//------------------


static VALUE global_self; //TODO: have to avoid global vars

   //call getdir with that an RFiller object
static int rf_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t f)
{
   VALUE rfiller_class;
   VALUE rfiller_instance;
   struct fill_t *fillerc;
   rfiller_class=rb_const_get(rb_cObject,rb_intern("RFiller"));

//***the following line seems to be the problem. If I comment everything 
out between here and "return 0" it runs okay... though nothing happens.

   rfiller_instance=rb_funcall(rfiller_class,rb_intern("new"),0);
//BTW: I can't do the rb_class_new_instance here STRANGE!

//***commenting out from here gives me strange errors (see bellow)

   rb_gc_register_address(&rfiller_instance);//Do I need this?
   Data_Get_Struct(rfiller_instance,struct fill_t,fillerc);
   fillerc->filler=f;//Init the filler by hand....not nice...
   fillerc->handler=h; 
rb_funcall(global_self,rb_intern("getdir"),2,rb_str_new2(path),rfiller_instance); 

   //destroy the filler...
   rb_gc_unregister_address(&rfiller_instance);
   return 0;
}

//calls getattr with path and expects a File::Stat back
static int rf_getattr(const char *path, struct stat *stbuf)
{
   int res; //For testing only
   res = lstat(path, stbuf);
   return 0;
}

static VALUE rf_main(VALUE self){
   char* argv[2];
   int ret;
   argv[0]="test-rfuse";
   argv[1]="/tmp/fuse";
   struct fuse_operations *fuseop;

   Data_Get_Struct(self,struct fuse_operations,fuseop);
   ret = fuse_main(2,argv,fuseop);
   return Qnil;
}

static VALUE rf_init(VALUE self){
   return self;
}

static VALUE rf_new(VALUE class){
   VALUE self;
   struct fuse_operations *fuseop;
   self = Data_Make_Struct(class, struct fuse_operations, 0,free,fuseop);
   fuseop->getattr=rf_getattr;
   fuseop->getdir=rf_getdir;
   rb_obj_call_init(self,0,0);
   global_self=self; //TODO: hide this...
   return self;
}

void Init_RFuse() {
   VALUE cRFuse=rb_define_class("RFuse",rb_cObject);
   rb_define_singleton_method(cRFuse,"new",rf_new,0);
   rb_define_method(cRFuse,"initialize",rf_init,0);
   rb_define_method(cRFuse,"main",rf_main,0);

   VALUE cRFiller=rb_define_class("RFiller",rb_cObject);
   rb_define_singleton_method(cRFiller,"new",rfill_new,0);
   //rb_define_method(cRFiller,"initialize",rfill_init,0);
   rb_define_method(cRFiller,"push",rfill_push,2);
   //  rb_define_method(cRFiller,"test",rfill_test,0);
}

After starting the progam and doing some (=up to 25) "ls /tmp/fuse" the 
programm crashes
cat /tmp/error says:
Error:stack level too deep

I think that I missed some cleanupcode...

Help I very much appreciated (my C isn't the best).
The interface of fuse is at:
http://cvs.sourceforge.net/viewcvs.py/fuse/fuse/include/fuse.h?rev=1.61&view=auto


Bye

Peter