Charles Mills
1/13/2005 4:53:00 PM
Peter Schrammel wrote:
>(...)
> I'd like to implement this as an extension so the testcode should
look
> like this:
It may help if you explain what your trying to do a bit more.
>
> #!/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;
> };
>
the function below should be registered using rb_define_alloc_func()
and is typically called rfill_alloc()
> 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.
>
*** see above ***
> 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)
>
you don't need this, if your worried about rfiller_instance being GC'ed
make it volatile.
> 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;
not sure how the flow of control goes in your program but seems pretty
obvious you have infinite recursion going on right here.
>
rb_funcall(global_self,rb_intern("getdir"),2,rb_str_new2(path),rfiller_instance);
>
don't need this either
> //destroy the filler...
> rb_gc_unregister_address(&rfiller_instance);
> return 0;
> }
>
(...)
>
> void Init_RFuse() {
> VALUE cRFuse=rb_define_class("RFuse",rb_cObject);
should be using rb_define_alloc_func() as noted above
> 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);
> }
>
(...)
-Charlie