rfuse 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,140 @@
1
+ #include "file_info.h"
2
+ #include <fuse.h>
3
+
4
+ //creates a FileInfo object from an already allocated ffi
5
+ VALUE wrap_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi) {
6
+ VALUE rRFuse;
7
+ VALUE rFileInfo;
8
+
9
+ VALUE rffi;
10
+
11
+ VALUE open_files;
12
+ VALUE key;
13
+
14
+ rRFuse=rb_const_get(rb_cObject,rb_intern("RFuse"));
15
+ rFileInfo=rb_const_get(rRFuse,rb_intern("FileInfo"));
16
+
17
+ rffi = Data_Wrap_Struct(rFileInfo,0,0,ffi);
18
+
19
+ //store the wrapped ffi back into the struct so we don't have to keep wrapping it
20
+ ffi->fh = rffi;
21
+
22
+ //also store it in an open_files hash on the fuse_object
23
+ //so it doesn't get GC'd
24
+ open_files = rb_iv_get(ctx->private_data,"@open_files");
25
+ key = rb_funcall(rffi,rb_intern("object_id"),0);
26
+ rb_hash_aset(open_files,key,rffi);
27
+
28
+ return rffi;
29
+ };
30
+
31
+ //returns a previously wrapped ffi
32
+ VALUE get_file_info(struct fuse_file_info *ffi) {
33
+
34
+ if (TYPE(ffi->fh) == T_DATA )
35
+ return (VALUE) ffi->fh;
36
+ else
37
+ return Qnil;
38
+
39
+ };
40
+
41
+ //Allow the FileInfo object to be GC'd
42
+ VALUE release_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi)
43
+ {
44
+
45
+ if (TYPE(ffi->fh) == T_DATA) {
46
+ VALUE rffi = ffi->fh;
47
+ VALUE fuse_object = ctx->private_data;
48
+ VALUE open_files = rb_iv_get(fuse_object,"@open_files");
49
+ VALUE key = rb_funcall(rffi,rb_intern("object_id"),0);
50
+ rb_hash_delete(open_files,key);
51
+ } else {
52
+ return Qnil;
53
+ }
54
+
55
+ }
56
+
57
+ VALUE file_info_initialize(VALUE self){
58
+ return self;
59
+ }
60
+
61
+ //TODO FT: test: this _should_not_ be called, an exception would do the trick :)
62
+ VALUE file_info_new(VALUE class){
63
+ rb_raise(rb_eNotImpError, "new() not implemented (it has no use), and should not be called");
64
+ return Qnil;
65
+ }
66
+
67
+ VALUE file_info_writepage(VALUE self) {
68
+ struct fuse_file_info *f;
69
+ Data_Get_Struct(self,struct fuse_file_info,f);
70
+ return INT2FIX(f->writepage);
71
+ }
72
+
73
+ VALUE file_info_flags(VALUE self) {
74
+ struct fuse_file_info *f;
75
+ Data_Get_Struct(self,struct fuse_file_info,f);
76
+ return INT2FIX(f->flags);
77
+ }
78
+
79
+ VALUE file_info_direct(VALUE self) {
80
+ struct fuse_file_info *f;
81
+ Data_Get_Struct(self,struct fuse_file_info,f);
82
+ if (TYPE(f->direct_io) != T_NONE) {
83
+ return (VALUE) f->direct_io;
84
+ } else {
85
+ return Qnil;
86
+ }
87
+ }
88
+
89
+ VALUE file_info_direct_assign(VALUE self,VALUE value) {
90
+ struct fuse_file_info *f;
91
+ Data_Get_Struct(self,struct fuse_file_info,f);
92
+ f->direct_io = value;
93
+ return value;
94
+ }
95
+
96
+ VALUE file_info_nonseekable(VALUE self) {
97
+ struct fuse_file_info *f;
98
+ Data_Get_Struct(self,struct fuse_file_info,f);
99
+ if (TYPE(f->nonseekable) != T_NONE) {
100
+ return (VALUE) f->nonseekable;
101
+ } else {
102
+ return Qnil;
103
+ }
104
+ }
105
+
106
+ VALUE file_info_nonseekable_assign(VALUE self,VALUE value) {
107
+ struct fuse_file_info *f;
108
+ Data_Get_Struct(self,struct fuse_file_info,f);
109
+ f->nonseekable = value;
110
+ return value;
111
+ }
112
+
113
+ /*
114
+ Document-class: RFuse::FileInfo
115
+
116
+ Represents an open file (or directory) that is reused
117
+ across multiple fuse operations
118
+
119
+ */
120
+ void file_info_init(VALUE module) {
121
+ #if 0
122
+ //Trick Yardoc
123
+ module = rb_define_module("RFuse");
124
+ #endif
125
+ VALUE cFileInfo=rb_define_class_under(module,"FileInfo",rb_cObject);
126
+ rb_define_alloc_func(cFileInfo,file_info_new);
127
+ rb_define_method(cFileInfo,"initialize",file_info_initialize,0);
128
+ rb_define_method(cFileInfo,"flags",file_info_flags,0);
129
+ rb_define_method(cFileInfo,"writepage",file_info_writepage,0);
130
+ rb_define_method(cFileInfo,"direct",file_info_direct,0);
131
+ rb_define_method(cFileInfo,"direct=",file_info_direct_assign,1);
132
+ rb_define_method(cFileInfo,"nonseekable",file_info_nonseekable,0);
133
+ rb_define_method(cFileInfo,"nonseekable=",file_info_nonseekable_assign,1);
134
+
135
+ /*
136
+ Filehandle - can be any ruby object
137
+ */
138
+ rb_define_attr(cFileInfo,"fh",1,1);
139
+ return cFileInfo;
140
+ }
@@ -0,0 +1,13 @@
1
+ #include <fuse.h>
2
+ #include <ruby.h>
3
+
4
+ VALUE wrap_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi);
5
+ VALUE get_file_info(struct fuse_file_info *ffi);
6
+ VALUE release_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi);
7
+
8
+ VALUE file_info_initialize(VALUE self);
9
+ VALUE file_info_new(VALUE class);
10
+ VALUE file_info_flags(VALUE self);
11
+ VALUE file_info_writepage(VALUE self);
12
+
13
+ void file_info_init(VALUE module);
@@ -0,0 +1,60 @@
1
+ #include "filler.h"
2
+ #include <fuse.h>
3
+ #include "helper.h"
4
+
5
+ VALUE rfiller_initialize(VALUE self){
6
+ return self;
7
+ }
8
+
9
+ /*
10
+ * @api private Never called
11
+ */
12
+ VALUE rfiller_new(VALUE class){
13
+ VALUE self;
14
+ struct filler_t *f;
15
+ self = Data_Make_Struct(class, struct filler_t, 0,free,f);
16
+ return self;
17
+ }
18
+
19
+ /*
20
+ * Add a value into the filler
21
+ * @param [String] name a file name
22
+ * @param [Stat] stat Stat info representing the file, may be nil
23
+ * @param [Integer] offset index of next entry, or zero
24
+ *
25
+ * @return self or nil if the buffer is full
26
+ *
27
+ */
28
+ VALUE rfiller_push(VALUE self, VALUE name, VALUE stat, VALUE offset) {
29
+ struct filler_t *f;
30
+ Data_Get_Struct(self,struct filler_t,f);
31
+ //Allow nil return instead of a stat
32
+
33
+ int result;
34
+
35
+ if (NIL_P(stat)) {
36
+ result = f->filler(f->buffer,STR2CSTR(name),NULL,NUM2LONG(offset));
37
+ } else {
38
+ struct stat st;
39
+ memset(&st, 0, sizeof(st));
40
+ rstat2stat(stat,&st);
41
+ result = f->filler(f->buffer,STR2CSTR(name),&st,NUM2LONG(offset));
42
+ }
43
+
44
+ return result ? Qnil : self;
45
+ }
46
+
47
+ /*
48
+ * Document-class: RFuse::Filler
49
+ * Used by {Fuse#readdir} to collect directory entries
50
+ */
51
+ void rfiller_init(VALUE module) {
52
+
53
+ #if 0
54
+ module = rb_define_module("RFuse");
55
+ #endif
56
+ VALUE cFiller=rb_define_class_under(module,"Filler",rb_cObject);
57
+ rb_define_alloc_func(cFiller,rfiller_new);
58
+ rb_define_method(cFiller,"initialize",rfiller_initialize,0);
59
+ rb_define_method(cFiller,"push",rfiller_push,3);
60
+ }
@@ -0,0 +1,15 @@
1
+ #include <fuse.h>
2
+ #include <ruby.h>
3
+
4
+ struct filler_t {
5
+ fuse_fill_dir_t filler;
6
+ void *buffer;
7
+ fuse_dirh_t dh;
8
+ fuse_dirfil_t df;
9
+ };
10
+
11
+ VALUE rfiller_initialize(VALUE self);
12
+ VALUE rfiller_new(VALUE class);
13
+ VALUE rfiller_push(VALUE self, VALUE name, VALUE stat, VALUE offset);
14
+
15
+ void rfiller_init(VALUE module);
@@ -0,0 +1,93 @@
1
+ #include "helper.h"
2
+
3
+ char*
4
+ rb_compat_str2cstr(VALUE x)
5
+ {
6
+ return StringValuePtr(x);
7
+ }
8
+
9
+ void rstat2stat(VALUE rstat, struct stat *statbuf)
10
+ {
11
+ statbuf->st_dev = FIX2ULONG(rb_funcall(rstat,rb_intern("dev"),0));
12
+ statbuf->st_ino = FIX2ULONG(rb_funcall(rstat,rb_intern("ino"),0));
13
+ statbuf->st_mode = FIX2UINT(rb_funcall(rstat,rb_intern("mode"),0));
14
+ statbuf->st_nlink = FIX2UINT(rb_funcall(rstat,rb_intern("nlink"),0));
15
+ statbuf->st_uid = FIX2UINT(rb_funcall(rstat,rb_intern("uid"),0));
16
+ statbuf->st_gid = FIX2UINT(rb_funcall(rstat,rb_intern("gid"),0));
17
+ statbuf->st_rdev = FIX2ULONG(rb_funcall(rstat,rb_intern("rdev"),0));
18
+ statbuf->st_size = FIX2ULONG(rb_funcall(rstat,rb_intern("size"),0));
19
+ statbuf->st_blksize = NUM2ULONG(rb_funcall(rstat,rb_intern("blksize"),0));
20
+ statbuf->st_blocks = NUM2ULONG(rb_funcall(rstat,rb_intern("blocks"),0));
21
+
22
+ VALUE r_atime = rb_funcall(rstat,rb_intern("atime"),0);
23
+ VALUE r_mtime = rb_funcall(rstat,rb_intern("mtime"),0);
24
+ VALUE r_ctime = rb_funcall(rstat,rb_intern("ctime"),0);
25
+
26
+ ID to_i = rb_intern("to_i");
27
+
28
+ statbuf->st_atime = NUM2ULONG(rb_funcall(r_atime,to_i,0));
29
+ statbuf->st_mtime = NUM2ULONG(rb_funcall(r_mtime,to_i,0));
30
+ statbuf->st_ctime = NUM2ULONG(rb_funcall(r_ctime,to_i,0));
31
+
32
+ //TODO: Find out the correct way to test for nano second resolution availability
33
+ #ifdef _STATBUF_ST_NSEC
34
+ ID nsec = rb_intern("nsec");
35
+
36
+ if (rb_respond_to(r_atime,nsec))
37
+ statbuf->st_atim.tv_nsec = NUM2ULONG(rb_funcall(r_atime,nsec,0));
38
+
39
+ if (rb_respond_to(r_mtime,nsec))
40
+ statbuf->st_mtim.tv_nsec = NUM2ULONG(rb_funcall(r_mtime,nsec,0));
41
+
42
+ if (rb_respond_to(r_ctime,nsec))
43
+ statbuf->st_ctim.tv_nsec = NUM2ULONG(rb_funcall(r_ctime,nsec,0));
44
+ #endif
45
+
46
+ }
47
+
48
+ void rstatvfs2statvfs(VALUE rstatvfs,struct statvfs *statvfsbuf) {
49
+ statvfsbuf->f_bsize = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_bsize"),0));
50
+ statvfsbuf->f_frsize = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_frsize"),0));
51
+ statvfsbuf->f_blocks = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_blocks"),0));
52
+ statvfsbuf->f_bfree = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_bfree"),0));
53
+ statvfsbuf->f_bavail = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_bavail"),0));
54
+ statvfsbuf->f_files = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_files"),0));
55
+ statvfsbuf->f_ffree = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_ffree"),0));
56
+ statvfsbuf->f_favail = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_favail"),0));
57
+ statvfsbuf->f_fsid = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_fsid"),0));
58
+ statvfsbuf->f_flag = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_flag"),0));
59
+ statvfsbuf->f_namemax = FIX2ULONG(rb_funcall(rstatvfs,rb_intern("f_namemax"),0));
60
+ }
61
+
62
+ void rfuseconninfo2fuseconninfo(VALUE rfuseconninfo,struct fuse_conn_info *fuseconninfo) {
63
+ fuseconninfo->proto_major = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("proto_major"),0));
64
+ fuseconninfo->proto_minor = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("proto_minor"),0));
65
+ fuseconninfo->async_read = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("async_read"),0));
66
+ fuseconninfo->max_write = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("max_write"),0));
67
+ fuseconninfo->max_readahead = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("max_readahead"),0));
68
+ fuseconninfo->capable = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("capable"),0));
69
+ fuseconninfo->want = FIX2UINT(rb_funcall(rfuseconninfo,rb_intern("want"),0));
70
+ }
71
+
72
+ struct fuse_args * rarray2fuseargs(VALUE rarray){
73
+
74
+ Check_Type(rarray, T_ARRAY);
75
+ struct fuse_args *args = malloc(sizeof(struct fuse_args));
76
+ args->argc = RARRAY_LEN(rarray) + 1;
77
+ args->argv = malloc((args->argc + 1) * sizeof(char *));
78
+ args->allocated = 1;
79
+
80
+ int i;
81
+ VALUE v;
82
+
83
+ args->argv[0] = strdup("");
84
+
85
+ for(i = 0; i < args->argc - 1; i++) {
86
+ v = RARRAY_PTR(rarray)[i];
87
+ Check_Type(v, T_STRING);
88
+ args->argv[i+1] = strdup(rb_string_value_ptr(&v)); //STR2CSTR(RSTRING(v));
89
+ }
90
+ args->argv[args->argc] = NULL;
91
+
92
+ return args;
93
+ }
@@ -0,0 +1,22 @@
1
+ #include <sys/stat.h>
2
+ #include <sys/statvfs.h>
3
+ #include <ruby.h>
4
+ #include <fuse.h>
5
+
6
+ #ifndef _RHUSE_HELPER_H
7
+ #define _RHUSE_HELPER_H
8
+
9
+ #define STR2CSTR(x) rb_compat_str2cstr(x)
10
+ char *rb_compat_str2cstr(VALUE);
11
+
12
+ void rstat2stat(VALUE rstat,struct stat *statbuf);
13
+ void rstatvfs2statvfs(VALUE rstatvfs,struct statvfs *statvfsbuf);
14
+ void rfuseconninfo2fuseconninfo(VALUE rfuseconninfo,struct fuse_conn_info *fuseconninfo);
15
+ struct fuse_args * rarray2fuseargs(VALUE rarray);
16
+
17
+ #if defined(RUBY_VERSION) && RUBY_VERSION >= 19
18
+ #define STR2CSTR(X) StringValuePtr(X)
19
+ #endif
20
+
21
+
22
+ #endif
@@ -0,0 +1,84 @@
1
+ #include "intern_rfuse.h"
2
+ #include <fuse/fuse_lowlevel.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ struct intern_fuse *intern_fuse_new() {
8
+ struct intern_fuse *inf;
9
+ inf = (struct intern_fuse *) malloc(sizeof(struct intern_fuse));
10
+ memset(inf, 0, sizeof(*inf));
11
+ memset(&inf->fuse_op, 0, sizeof(struct fuse_operations));
12
+ return inf;
13
+ }
14
+
15
+
16
+ int intern_fuse_destroy(struct intern_fuse *inf){
17
+ //you have to take care, that fuse is unmounted yourself!
18
+ if(inf->fuse)
19
+ fuse_destroy(inf->fuse);
20
+ if(inf->mountpoint)
21
+ free(inf->mountpoint);
22
+ free(inf);
23
+ return 0;
24
+ }
25
+
26
+ int intern_fuse_init(
27
+ struct intern_fuse *inf,
28
+ struct fuse_args *args,
29
+ void* user_data
30
+ )
31
+ {
32
+ struct fuse_chan* fc;
33
+ int res;
34
+
35
+ char* mountpoint;
36
+ mountpoint = inf->mountpoint;
37
+ fc = fuse_mount(mountpoint,args);
38
+
39
+ if (fc == NULL) {
40
+ return -1;
41
+ }
42
+
43
+ inf->fuse=fuse_new(fc, args, &(inf->fuse_op), sizeof(struct fuse_operations), user_data);
44
+ if (inf->fuse == NULL) {
45
+ fuse_unmount(inf->mountpoint, fc);
46
+ return -1;
47
+ }
48
+
49
+ inf->fc = fc;
50
+
51
+ return 0;
52
+ }
53
+
54
+ // Return the /dev/fuse file descriptor for use with IO.select
55
+ int intern_fuse_fd(struct intern_fuse *inf)
56
+ {
57
+ if (inf->fc == NULL) {
58
+ return -1;
59
+ }
60
+
61
+ struct fuse_chan *fc = inf->fc;
62
+ return fuse_chan_fd(fc);
63
+ }
64
+
65
+ //Process one fuse command (ie after IO.select)
66
+ int intern_fuse_process(struct intern_fuse *inf)
67
+ {
68
+ if (inf->fuse == NULL) {
69
+ return -1;
70
+ }
71
+
72
+ if (fuse_exited(inf->fuse)) {
73
+ return -1;
74
+ }
75
+
76
+ struct fuse_cmd *cmd;
77
+ cmd = fuse_read_cmd(inf->fuse);
78
+
79
+ if (cmd != NULL) {
80
+ fuse_process_cmd(inf->fuse, cmd);
81
+ }
82
+
83
+ return 0;
84
+ }
@@ -0,0 +1,22 @@
1
+ #include <fuse.h>
2
+
3
+ #define MOUNTNAME_MAX 1024
4
+
5
+ struct intern_fuse {
6
+ struct fuse_chan *fc;
7
+ struct fuse *fuse;
8
+ struct fuse_operations fuse_op;
9
+ char *mountpoint;
10
+ };
11
+
12
+ struct intern_fuse *intern_fuse_new();
13
+
14
+ int intern_fuse_init(
15
+ struct intern_fuse *inf,
16
+ struct fuse_args *args,
17
+ void *user_data
18
+ );
19
+
20
+ int intern_fuse_fd(struct intern_fuse *inf);
21
+ int intern_fuse_process(struct intern_fuse *inf);
22
+ int intern_fuse_destroy(struct intern_fuse *inf);
@@ -0,0 +1,54 @@
1
+ #include <ruby.h>
2
+ #include <fuse.h>
3
+
4
+ #include "pollhandle.h"
5
+
6
+ static int pollhandle_destroy(struct fuse_pollhandle *ph)
7
+ {
8
+ fuse_pollhandle_destroy(ph);
9
+ return 0;
10
+ }
11
+
12
+ VALUE pollhandle_new(VALUE class)
13
+ {
14
+ rb_raise(rb_eNotImpError, "new() not implemented (it has no use), and should not be called");
15
+ return Qnil;
16
+ }
17
+
18
+ VALUE pollhandle_initialize(VALUE self)
19
+ {
20
+ return self;
21
+ }
22
+
23
+ VALUE pollhandle_notify_poll(VALUE self)
24
+ {
25
+ struct fuse_pollhandle *ph;
26
+ Data_Get_Struct(self, struct fuse_pollhandle, ph);
27
+ return INT2FIX(fuse_notify_poll(ph));
28
+ }
29
+
30
+ VALUE wrap_pollhandle(struct fuse_pollhandle *ph)
31
+ {
32
+ VALUE rRFuse;
33
+ VALUE rPollHandle;
34
+
35
+ rRFuse = rb_const_get(rb_cObject,rb_intern("RFuse"));
36
+ rPollHandle = rb_const_get(rRFuse,rb_intern("PollHandle"));
37
+
38
+ // We need a mark function here to ensure the ph is not GC'd
39
+ // between poll and notify_poll
40
+ return Data_Wrap_Struct(rPollHandle, NULL, pollhandle_destroy, ph);
41
+
42
+ }
43
+
44
+ VALUE pollhandle_init(VALUE module)
45
+ {
46
+ VALUE cPollHandle = rb_define_class_under(module,"PollHandle",rb_cObject);
47
+
48
+ rb_define_alloc_func(cPollHandle,pollhandle_new);
49
+
50
+ rb_define_method(cPollHandle,"initialize",pollhandle_initialize,0);
51
+ rb_define_method(cPollHandle,"notifyPoll",pollhandle_notify_poll,0);
52
+
53
+ return cPollHandle;
54
+ }
@@ -0,0 +1,10 @@
1
+ #include <fuse.h>
2
+ #include <ruby.h>
3
+
4
+ VALUE wrap_pollhandle(struct fuse_pollhandle *ph);
5
+
6
+ VALUE pollhandle_new(VALUE class);
7
+ VALUE pollhandle_initialize(VALUE self);
8
+ VALUE pollhandle_notify_poll(VALUE self);
9
+
10
+ VALUE pollhandle_init(VALUE module);