rfuse 1.0.2 → 1.0.3
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.
- data/CHANGES.md +12 -3
- data/README.md +1 -1
- data/ext/rfuse/context.c +0 -1
- data/ext/rfuse/file_info.c +7 -6
- data/ext/rfuse/filler.c +5 -4
- data/ext/rfuse/helper.c +20 -16
- data/ext/rfuse/helper.h +2 -10
- data/ext/rfuse/intern_rfuse.c +5 -10
- data/ext/rfuse/rfuse.c +110 -188
- data/lib/rfuse/version.rb +1 -1
- data/lib/rfuse.rb +87 -3
- data/spec/basic_spec.rb +2 -28
- data/spec/fuse_file_info_spec.rb +41 -12
- data/spec/options_spec.rb +112 -0
- metadata +3 -2
data/CHANGES.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
-
1.0.
|
2
|
-
|
1
|
+
1.0.3 - 2012/08/16
|
2
|
+
------------------
|
3
|
+
|
4
|
+
Cleanup compile warnings
|
5
|
+
|
6
|
+
Bugfixes
|
7
|
+
* {RFuse::Fuse#statfs} potential segfault
|
8
|
+
* {RFuse::Fuse#release} not receiving FileInfo
|
9
|
+
|
10
|
+
1.0.2 - 2012/08/09
|
11
|
+
------------------
|
3
12
|
|
4
13
|
Support Ruby 1.8 (tested with 1.8.7)
|
5
14
|
|
@@ -39,7 +48,7 @@ with API breaking changes since the various 0.x.y series of rfuse and rfuse-ng
|
|
39
48
|
command at a time. This allows the Ruby interpreter to retain control
|
40
49
|
so you can use other threads, Signal.trap etc...
|
41
50
|
|
42
|
-
Various {RFuse::Fuse} methods will throw {
|
51
|
+
Various {RFuse::Fuse} methods will throw {RFuse::Error} if the filesystem is
|
43
52
|
not mounted, which can be tested after initialisation with {RFuse::Fuse#mounted?}
|
44
53
|
|
45
54
|
Implemented {RFuse::FuseDelegator} so your filesystem can be implemented (and tested/debugged)
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@ RFuse
|
|
3
3
|
|
4
4
|
http://rubygems.org/gems/rfuse
|
5
5
|
|
6
|
-
FUSE
|
6
|
+
Ruby FUSE binding
|
7
7
|
|
8
8
|
FUSE (Filesystem in USErspace) is a simple interface for userspace programs to export a virtual filesystem to the linux kernel. FUSE aims to provide a secure method for non privileged users to create and mount their own filesystem implementations.
|
9
9
|
|
data/ext/rfuse/context.c
CHANGED
data/ext/rfuse/file_info.c
CHANGED
@@ -21,7 +21,7 @@ VALUE wrap_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi) {
|
|
21
21
|
|
22
22
|
//also store it in an open_files hash on the fuse_object
|
23
23
|
//so it doesn't get GC'd
|
24
|
-
open_files = rb_iv_get(ctx->private_data,"@open_files");
|
24
|
+
open_files = rb_iv_get((VALUE) ctx->private_data,"@open_files");
|
25
25
|
key = rb_funcall(rffi,rb_intern("object_id"),0);
|
26
26
|
rb_hash_aset(open_files,key,rffi);
|
27
27
|
|
@@ -44,13 +44,15 @@ VALUE release_file_info(struct fuse_context *ctx, struct fuse_file_info *ffi)
|
|
44
44
|
|
45
45
|
if (TYPE(ffi->fh) == T_DATA) {
|
46
46
|
VALUE rffi = ffi->fh;
|
47
|
-
VALUE fuse_object = ctx->private_data;
|
47
|
+
VALUE fuse_object = (VALUE) ctx->private_data;
|
48
48
|
VALUE open_files = rb_iv_get(fuse_object,"@open_files");
|
49
49
|
VALUE key = rb_funcall(rffi,rb_intern("object_id"),0);
|
50
50
|
rb_hash_delete(open_files,key);
|
51
|
-
|
52
|
-
return
|
53
|
-
}
|
51
|
+
|
52
|
+
return rffi;
|
53
|
+
}
|
54
|
+
|
55
|
+
return Qnil;
|
54
56
|
|
55
57
|
}
|
56
58
|
|
@@ -136,5 +138,4 @@ void file_info_init(VALUE module) {
|
|
136
138
|
Filehandle - can be any ruby object
|
137
139
|
*/
|
138
140
|
rb_define_attr(cFileInfo,"fh",1,1);
|
139
|
-
return cFileInfo;
|
140
141
|
}
|
data/ext/rfuse/filler.c
CHANGED
@@ -27,18 +27,19 @@ VALUE rfiller_new(VALUE class){
|
|
27
27
|
*/
|
28
28
|
VALUE rfiller_push(VALUE self, VALUE name, VALUE stat, VALUE offset) {
|
29
29
|
struct filler_t *f;
|
30
|
+
int result;
|
31
|
+
|
30
32
|
Data_Get_Struct(self,struct filler_t,f);
|
31
|
-
//Allow nil return instead of a stat
|
32
33
|
|
33
|
-
int result;
|
34
34
|
|
35
|
+
//Allow nil return instead of a stat
|
35
36
|
if (NIL_P(stat)) {
|
36
|
-
result = f->filler(f->buffer,
|
37
|
+
result = f->filler(f->buffer,StringValueCStr(name),NULL,NUM2LONG(offset));
|
37
38
|
} else {
|
38
39
|
struct stat st;
|
39
40
|
memset(&st, 0, sizeof(st));
|
40
41
|
rstat2stat(stat,&st);
|
41
|
-
result = f->filler(f->buffer,
|
42
|
+
result = f->filler(f->buffer,StringValueCStr(name),&st,NUM2LONG(offset));
|
42
43
|
}
|
43
44
|
|
44
45
|
return result ? Qnil : self;
|
data/ext/rfuse/helper.c
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
#include "helper.h"
|
2
2
|
|
3
|
-
char*
|
4
|
-
rb_compat_str2cstr(VALUE x)
|
5
|
-
{
|
6
|
-
return StringValuePtr(x);
|
7
|
-
}
|
8
|
-
|
9
3
|
void rstat2stat(VALUE rstat, struct stat *statbuf)
|
10
4
|
{
|
5
|
+
ID to_i;
|
6
|
+
VALUE r_atime,r_mtime,r_ctime;
|
7
|
+
|
11
8
|
statbuf->st_dev = FIX2ULONG(rb_funcall(rstat,rb_intern("dev"),0));
|
12
9
|
statbuf->st_ino = FIX2ULONG(rb_funcall(rstat,rb_intern("ino"),0));
|
13
10
|
statbuf->st_mode = FIX2UINT(rb_funcall(rstat,rb_intern("mode"),0));
|
@@ -19,11 +16,11 @@ void rstat2stat(VALUE rstat, struct stat *statbuf)
|
|
19
16
|
statbuf->st_blksize = NUM2ULONG(rb_funcall(rstat,rb_intern("blksize"),0));
|
20
17
|
statbuf->st_blocks = NUM2ULONG(rb_funcall(rstat,rb_intern("blocks"),0));
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
r_atime = rb_funcall(rstat,rb_intern("atime"),0);
|
20
|
+
r_mtime = rb_funcall(rstat,rb_intern("mtime"),0);
|
21
|
+
r_ctime = rb_funcall(rstat,rb_intern("ctime"),0);
|
25
22
|
|
26
|
-
|
23
|
+
to_i = rb_intern("to_i");
|
27
24
|
|
28
25
|
statbuf->st_atime = NUM2ULONG(rb_funcall(r_atime,to_i,0));
|
29
26
|
statbuf->st_mtime = NUM2ULONG(rb_funcall(r_mtime,to_i,0));
|
@@ -31,7 +28,9 @@ void rstat2stat(VALUE rstat, struct stat *statbuf)
|
|
31
28
|
|
32
29
|
//TODO: Find out the correct way to test for nano second resolution availability
|
33
30
|
#ifdef _STATBUF_ST_NSEC
|
34
|
-
|
31
|
+
{
|
32
|
+
ID nsec;
|
33
|
+
nsec = rb_intern("nsec");
|
35
34
|
|
36
35
|
if (rb_respond_to(r_atime,nsec))
|
37
36
|
statbuf->st_atim.tv_nsec = NUM2ULONG(rb_funcall(r_atime,nsec,0));
|
@@ -41,6 +40,7 @@ void rstat2stat(VALUE rstat, struct stat *statbuf)
|
|
41
40
|
|
42
41
|
if (rb_respond_to(r_ctime,nsec))
|
43
42
|
statbuf->st_ctim.tv_nsec = NUM2ULONG(rb_funcall(r_ctime,nsec,0));
|
43
|
+
}
|
44
44
|
#endif
|
45
45
|
|
46
46
|
}
|
@@ -71,22 +71,26 @@ void rfuseconninfo2fuseconninfo(VALUE rfuseconninfo,struct fuse_conn_info *fusec
|
|
71
71
|
|
72
72
|
struct fuse_args * rarray2fuseargs(VALUE rarray){
|
73
73
|
|
74
|
+
int i;
|
75
|
+
struct fuse_args *args;
|
76
|
+
//TODO - we probably don't want to execute the rest if the type check fails
|
74
77
|
Check_Type(rarray, T_ARRAY);
|
75
|
-
|
78
|
+
|
79
|
+
args = malloc(sizeof(struct fuse_args));
|
76
80
|
args->argc = RARRAY_LEN(rarray) + 1;
|
77
81
|
args->argv = malloc((args->argc + 1) * sizeof(char *));
|
78
82
|
args->allocated = 1;
|
79
83
|
|
80
|
-
int i;
|
81
|
-
VALUE v;
|
82
84
|
|
83
85
|
args->argv[0] = strdup("");
|
84
86
|
|
85
87
|
for(i = 0; i < args->argc - 1; i++) {
|
88
|
+
VALUE v;
|
86
89
|
v = RARRAY_PTR(rarray)[i];
|
87
90
|
Check_Type(v, T_STRING);
|
88
|
-
args->argv[i+1] = strdup(rb_string_value_ptr(&v));
|
89
|
-
|
91
|
+
args->argv[i+1] = strdup(rb_string_value_ptr(&v));
|
92
|
+
}
|
93
|
+
|
90
94
|
args->argv[args->argc] = NULL;
|
91
95
|
|
92
96
|
return args;
|
data/ext/rfuse/helper.h
CHANGED
@@ -3,20 +3,12 @@
|
|
3
3
|
#include <ruby.h>
|
4
4
|
#include <fuse.h>
|
5
5
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
8
|
-
|
9
|
-
#define STR2CSTR(x) rb_compat_str2cstr(x)
|
10
|
-
char *rb_compat_str2cstr(VALUE);
|
6
|
+
#ifndef _RFUSE_HELPER_H
|
7
|
+
#define _RFUSE_HELPER_H
|
11
8
|
|
12
9
|
void rstat2stat(VALUE rstat,struct stat *statbuf);
|
13
10
|
void rstatvfs2statvfs(VALUE rstatvfs,struct statvfs *statvfsbuf);
|
14
11
|
void rfuseconninfo2fuseconninfo(VALUE rfuseconninfo,struct fuse_conn_info *fuseconninfo);
|
15
12
|
struct fuse_args * rarray2fuseargs(VALUE rarray);
|
16
13
|
|
17
|
-
#if defined(RUBY_VERSION) && RUBY_VERSION >= 19
|
18
|
-
#define STR2CSTR(X) StringValuePtr(X)
|
19
|
-
#endif
|
20
|
-
|
21
|
-
|
22
14
|
#endif
|
data/ext/rfuse/intern_rfuse.c
CHANGED
@@ -23,15 +23,9 @@ int intern_fuse_destroy(struct intern_fuse *inf){
|
|
23
23
|
return 0;
|
24
24
|
}
|
25
25
|
|
26
|
-
int intern_fuse_init(
|
27
|
-
struct intern_fuse *inf,
|
28
|
-
struct fuse_args *args,
|
29
|
-
void* user_data
|
30
|
-
)
|
26
|
+
int intern_fuse_init(struct intern_fuse *inf, struct fuse_args *args, void* user_data)
|
31
27
|
{
|
32
28
|
struct fuse_chan* fc;
|
33
|
-
int res;
|
34
|
-
|
35
29
|
char* mountpoint;
|
36
30
|
mountpoint = inf->mountpoint;
|
37
31
|
fc = fuse_mount(mountpoint,args);
|
@@ -41,6 +35,7 @@ int intern_fuse_init(
|
|
41
35
|
}
|
42
36
|
|
43
37
|
inf->fuse=fuse_new(fc, args, &(inf->fuse_op), sizeof(struct fuse_operations), user_data);
|
38
|
+
|
44
39
|
if (inf->fuse == NULL) {
|
45
40
|
fuse_unmount(inf->mountpoint, fc);
|
46
41
|
return -1;
|
@@ -58,13 +53,14 @@ int intern_fuse_fd(struct intern_fuse *inf)
|
|
58
53
|
return -1;
|
59
54
|
}
|
60
55
|
|
61
|
-
|
62
|
-
return fuse_chan_fd(fc);
|
56
|
+
return fuse_chan_fd(inf->fc);
|
63
57
|
}
|
64
58
|
|
65
59
|
//Process one fuse command (ie after IO.select)
|
66
60
|
int intern_fuse_process(struct intern_fuse *inf)
|
67
61
|
{
|
62
|
+
struct fuse_cmd *cmd;
|
63
|
+
|
68
64
|
if (inf->fuse == NULL) {
|
69
65
|
return -1;
|
70
66
|
}
|
@@ -73,7 +69,6 @@ int intern_fuse_process(struct intern_fuse *inf)
|
|
73
69
|
return -1;
|
74
70
|
}
|
75
71
|
|
76
|
-
struct fuse_cmd *cmd;
|
77
72
|
cmd = fuse_read_cmd(inf->fuse);
|
78
73
|
|
79
74
|
if (cmd != NULL) {
|