rfuse 1.0.4 → 1.0.5.RC0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/rfuse/extconf.rb +3 -3
- data/ext/rfuse/filler.c +2 -2
- data/ext/rfuse/helper.c +3 -3
- data/ext/rfuse/helper.h +1 -0
- data/ext/rfuse/rfuse.c +11 -30
- data/ext/rfuse/ruby-compat.h +39 -0
- data/lib/rfuse/version.rb +1 -1
- data/lib/rfuse.rb +1 -1
- data/rfuse.gemspec +1 -0
- data/spec/basic_spec.rb +69 -19
- metadata +24 -10
data/ext/rfuse/extconf.rb
CHANGED
@@ -6,9 +6,9 @@ $CFLAGS << ' -D_FILE_OFFSET_BITS=64'
|
|
6
6
|
$CFLAGS << ' -DFUSE_USE_VERSION=26'
|
7
7
|
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
have_func("rb_errinfo")
|
10
|
+
|
11
|
+
have_func("rb_set_errinfo")
|
12
12
|
|
13
13
|
if have_library('fuse')
|
14
14
|
create_makefile('rfuse/rfuse')
|
data/ext/rfuse/filler.c
CHANGED
@@ -34,12 +34,12 @@ VALUE rfiller_push(VALUE self, VALUE name, VALUE stat, VALUE offset) {
|
|
34
34
|
|
35
35
|
//Allow nil return instead of a stat
|
36
36
|
if (NIL_P(stat)) {
|
37
|
-
result = f->filler(f->buffer,StringValueCStr(name),NULL,
|
37
|
+
result = f->filler(f->buffer,StringValueCStr(name),NULL,NUM2OFFT(offset));
|
38
38
|
} else {
|
39
39
|
struct stat st;
|
40
40
|
memset(&st, 0, sizeof(st));
|
41
41
|
rstat2stat(stat,&st);
|
42
|
-
result = f->filler(f->buffer,StringValueCStr(name),&st,
|
42
|
+
result = f->filler(f->buffer,StringValueCStr(name),&st,NUM2OFFT(offset));
|
43
43
|
}
|
44
44
|
|
45
45
|
return result ? Qnil : self;
|
data/ext/rfuse/helper.c
CHANGED
@@ -12,9 +12,9 @@ void rstat2stat(VALUE rstat, struct stat *statbuf)
|
|
12
12
|
statbuf->st_uid = FIX2UINT(rb_funcall(rstat,rb_intern("uid"),0));
|
13
13
|
statbuf->st_gid = FIX2UINT(rb_funcall(rstat,rb_intern("gid"),0));
|
14
14
|
statbuf->st_rdev = FIX2ULONG(rb_funcall(rstat,rb_intern("rdev"),0));
|
15
|
-
statbuf->st_size =
|
16
|
-
statbuf->st_blksize =
|
17
|
-
statbuf->st_blocks =
|
15
|
+
statbuf->st_size = NUM2OFFT(rb_funcall(rstat,rb_intern("size"),0));
|
16
|
+
statbuf->st_blksize = NUM2SIZET(rb_funcall(rstat,rb_intern("blksize"),0));
|
17
|
+
statbuf->st_blocks = NUM2SIZET(rb_funcall(rstat,rb_intern("blocks"),0));
|
18
18
|
|
19
19
|
r_atime = rb_funcall(rstat,rb_intern("atime"),0);
|
20
20
|
r_mtime = rb_funcall(rstat,rb_intern("mtime"),0);
|
data/ext/rfuse/helper.h
CHANGED
data/ext/rfuse/rfuse.c
CHANGED
@@ -7,9 +7,11 @@
|
|
7
7
|
#include <linux/kdev_t.h>
|
8
8
|
|
9
9
|
#include <ruby.h>
|
10
|
+
#include "ruby-compat.h"
|
10
11
|
#include <fuse.h>
|
11
12
|
#include <errno.h>
|
12
13
|
#include <sys/statfs.h>
|
14
|
+
|
13
15
|
#ifdef HAVE_SETXATTR
|
14
16
|
#include <sys/xattr.h>
|
15
17
|
#endif
|
@@ -23,27 +25,6 @@
|
|
23
25
|
#include "pollhandle.h"
|
24
26
|
#include "bufferwrapper.h"
|
25
27
|
|
26
|
-
// Ruby 1.8 compatibility
|
27
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
28
|
-
#include <ruby/encoding.h>
|
29
|
-
#endif
|
30
|
-
|
31
|
-
#ifndef HAVE_RB_ERRINFO
|
32
|
-
static VALUE rb_errinfo()
|
33
|
-
{
|
34
|
-
return ruby_errinfo;
|
35
|
-
}
|
36
|
-
#endif
|
37
|
-
|
38
|
-
static VALUE rb_filesystem_encode(VALUE str)
|
39
|
-
{
|
40
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
41
|
-
return rb_enc_associate(str,rb_filesystem_encoding());
|
42
|
-
#else
|
43
|
-
return str;
|
44
|
-
#endif
|
45
|
-
}
|
46
|
-
//end 1.8 compat
|
47
28
|
|
48
29
|
static VALUE mRFuse;
|
49
30
|
static VALUE eRFuse_Error;
|
@@ -144,7 +125,7 @@ static int rf_readdir(const char *path, void *buf,
|
|
144
125
|
fillerc->filler=filler;
|
145
126
|
fillerc->buffer=buf;
|
146
127
|
args[3]=rfiller_instance;
|
147
|
-
args[4]=
|
128
|
+
args[4]=OFFT2NUM(offset);
|
148
129
|
args[5]=get_file_info(ffi);
|
149
130
|
|
150
131
|
rb_protect((VALUE (*)())unsafe_readdir,(VALUE)args,&error);
|
@@ -177,7 +158,7 @@ static int rf_readlink(const char *path, char *buf, size_t size)
|
|
177
158
|
struct fuse_context *ctx=fuse_get_context();
|
178
159
|
init_context_path_args(args,ctx,path);
|
179
160
|
|
180
|
-
args[3]=
|
161
|
+
args[3]=SIZET2NUM(size);
|
181
162
|
res=rb_protect((VALUE (*)())unsafe_readlink,(VALUE)args,&error);
|
182
163
|
if (error)
|
183
164
|
{
|
@@ -844,8 +825,8 @@ static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct
|
|
844
825
|
struct fuse_context *ctx=fuse_get_context();
|
845
826
|
init_context_path_args(args,ctx,path);
|
846
827
|
|
847
|
-
args[3]=
|
848
|
-
args[4]=
|
828
|
+
args[3]=SIZET2NUM(size);
|
829
|
+
args[4]=OFFT2NUM(offset);
|
849
830
|
args[5]=get_file_info(ffi);
|
850
831
|
|
851
832
|
res=rb_protect((VALUE (*)())unsafe_read,(VALUE) args,&error);
|
@@ -873,7 +854,7 @@ static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct
|
|
873
854
|
/*
|
874
855
|
Write data to an open file
|
875
856
|
|
876
|
-
@overload write(context,path,
|
857
|
+
@overload write(context,path,data,offset,ffi)
|
877
858
|
|
878
859
|
@abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#897d1ece4b8b04c92d97b97b2dbf9768 write}
|
879
860
|
|
@@ -883,7 +864,7 @@ static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct
|
|
883
864
|
@param [Integer] offset
|
884
865
|
@param [FileInfo] ffi
|
885
866
|
|
886
|
-
@return [Integer] exactly the number of bytes
|
867
|
+
@return [Integer] exactly the number of bytes requested except on error
|
887
868
|
@raise [Errno]
|
888
869
|
*/
|
889
870
|
static VALUE unsafe_write(VALUE *args)
|
@@ -901,7 +882,7 @@ static int rf_write(const char *path,const char *buf,size_t size,
|
|
901
882
|
init_context_path_args(args,ctx,path);
|
902
883
|
|
903
884
|
args[3]=rb_str_new(buf, size);
|
904
|
-
args[4]=
|
885
|
+
args[4]=OFFT2NUM(offset);
|
905
886
|
args[5]=get_file_info(ffi);
|
906
887
|
|
907
888
|
res = rb_protect((VALUE (*)())unsafe_write,(VALUE) args, &error);
|
@@ -1387,7 +1368,7 @@ static int rf_ftruncate(const char *path, off_t size,
|
|
1387
1368
|
|
1388
1369
|
struct fuse_context *ctx = fuse_get_context();
|
1389
1370
|
init_context_path_args(args,ctx,path);
|
1390
|
-
args[3] =
|
1371
|
+
args[3] = OFFT2NUM(size);
|
1391
1372
|
args[4] = get_file_info(ffi);
|
1392
1373
|
|
1393
1374
|
rb_protect((VALUE (*)())unsafe_ftruncate,(VALUE) args,&error);
|
@@ -1587,7 +1568,7 @@ static int rf_bmap(const char *path, size_t blocksize, uint64_t *idx)
|
|
1587
1568
|
|
1588
1569
|
struct fuse_context *ctx = fuse_get_context();
|
1589
1570
|
init_context_path_args(args,ctx,path);
|
1590
|
-
args[3] =
|
1571
|
+
args[3] = SIZET2NUM(blocksize);
|
1591
1572
|
args[4] = LL2NUM(*idx);
|
1592
1573
|
|
1593
1574
|
res = rb_protect((VALUE (*)())unsafe_bmap,(VALUE) args, &error);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
2
|
+
#include <ruby/encoding.h>
|
3
|
+
#define rb_filesystem_encode(STR) (rb_enc_associate(STR,rb_filesystem_encoding()))
|
4
|
+
#else
|
5
|
+
#define rb_filesystem_encode(STR)
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#ifndef HAVE_RB_ERRINFO
|
9
|
+
#define rb_errinfo() ruby_errinfo
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#ifndef HAVE_RB_SET_ERRINFO
|
13
|
+
#define rb_set_errinfo(v) /*no-op*/
|
14
|
+
#endif
|
15
|
+
|
16
|
+
/* SIZET macros from ruby 1.9 */
|
17
|
+
#ifndef SIZET2NUM
|
18
|
+
#if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
|
19
|
+
# define SIZET2NUM(v) ULL2NUM(v)
|
20
|
+
# define SSIZET2NUM(v) LL2NUM(v)
|
21
|
+
#elif SIZEOF_SIZE_T == SIZEOF_LONG
|
22
|
+
# define SIZET2NUM(v) ULONG2NUM(v)
|
23
|
+
# define SSIZET2NUM(v) LONG2NUM(v)
|
24
|
+
#else
|
25
|
+
# define SIZET2NUM(v) UINT2NUM(v)
|
26
|
+
# define SSIZET2NUM(v) INT2NUM(v)
|
27
|
+
#endif
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#ifndef NUM2SIZET
|
31
|
+
#if defined(HAVE_LONG_LONG) && SIZEOF_SIZE_T > SIZEOF_LONG
|
32
|
+
# define NUM2SIZET(x) ((size_t)NUM2ULL(x))
|
33
|
+
# define NUM2SSIZET(x) ((ssize_t)NUM2LL(x))
|
34
|
+
#else
|
35
|
+
# define NUM2SIZET(x) NUM2ULONG(x)
|
36
|
+
# define NUM2SSIZET(x) NUM2LONG(x)
|
37
|
+
#endif
|
38
|
+
#endif
|
39
|
+
|
data/lib/rfuse/version.rb
CHANGED
data/lib/rfuse.rb
CHANGED
@@ -316,7 +316,7 @@ module RFuse
|
|
316
316
|
def initialize(values={ })
|
317
317
|
@f_bsize, @f_frsize, @f_blocks, @f_bfree, @f_bavail, @f_files, @f_ffree, @f_favail,@f_fsid, @f_flag,@f_namemax = Array.new(13,0)
|
318
318
|
values.each_pair do |k,v|
|
319
|
-
prefix = k.
|
319
|
+
prefix = k.to_s.start_with?("f_") ? "" : "f_"
|
320
320
|
instance_variable_set("@#{prefix}#{k}",v)
|
321
321
|
end
|
322
322
|
end
|
data/rfuse.gemspec
CHANGED
data/spec/basic_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'pathname'
|
3
3
|
require 'tempfile'
|
4
|
+
require 'sys/filesystem'
|
4
5
|
|
5
6
|
describe RFuse::Fuse do
|
6
7
|
|
@@ -138,7 +139,7 @@ describe RFuse::Fuse do
|
|
138
139
|
file_stat.size = 12
|
139
140
|
mockfs.stub(:getattr).with(anything(),"/test").and_return(file_stat)
|
140
141
|
|
141
|
-
|
142
|
+
|
142
143
|
reads = 0
|
143
144
|
mockfs.stub(:read) { |ctx,path,size,offset,ffi|
|
144
145
|
reads += 2
|
@@ -154,27 +155,63 @@ describe RFuse::Fuse do
|
|
154
155
|
end
|
155
156
|
|
156
157
|
it "should read over null characters in a real file" do
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
158
|
+
file_stat.size = 2
|
159
|
+
File.open("/tmp/nulltest","w") { |f| f.print "\000\000" }
|
160
|
+
|
161
|
+
mockfs.stub(:getattr).with(anything(),"/testnull").and_return(file_stat)
|
162
|
+
|
163
|
+
mockfs.stub(:read) { |ctx,path,size,offset,ffi|
|
164
|
+
IO.read("/tmp/nulltest",size,offset)
|
165
|
+
}
|
166
|
+
|
167
|
+
with_fuse(mountpoint,mockfs) do
|
168
|
+
File.open("#{mountpoint}/testnull") do |f|
|
169
|
+
val = f.gets
|
170
|
+
val.should == "\000\000"
|
171
|
+
val.size.should == 2
|
172
|
+
puts val
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
175
176
|
|
176
177
|
end
|
177
178
|
|
179
|
+
context "filesystem statistics" do
|
180
|
+
|
181
|
+
let (:statvfs) {
|
182
|
+
RFuse::StatVfs.new(
|
183
|
+
:bsize => 2048,
|
184
|
+
"frsize" => 1024,
|
185
|
+
"blocks" => 9999,
|
186
|
+
"bfree" => 8888,
|
187
|
+
"bavail" => 7777,
|
188
|
+
"files" => 6000,
|
189
|
+
"ffree" => 5555)
|
190
|
+
}
|
191
|
+
|
192
|
+
it "should report filesystem statistics" do
|
193
|
+
mockfs.stub(:getattr).with(anything(),"/test").and_return(dir_stat)
|
194
|
+
mockfs.stub(:getattr).with(anything(),"/test/statfs").and_return(file_stat)
|
195
|
+
|
196
|
+
mockfs.should_receive(:statfs).with(anything(),"/test/statfs").and_return(statvfs)
|
197
|
+
|
198
|
+
#also exercise StatVfs
|
199
|
+
statvfs.f_files=6666
|
200
|
+
|
201
|
+
with_fuse(mountpoint,mockfs) do
|
202
|
+
|
203
|
+
results = Sys::Filesystem.stat("#{mountpoint}/test/statfs")
|
204
|
+
results.block_size.should == 2048
|
205
|
+
results.fragment_size.should == 1024
|
206
|
+
results.blocks.should == 9999
|
207
|
+
results.blocks_available.should == 7777
|
208
|
+
results.blocks_free.should == 8888
|
209
|
+
results.files.should == 6666
|
210
|
+
results.files_available == 5555
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
178
215
|
context "exceptions" do
|
179
216
|
|
180
217
|
it "should capture exceptions appropriately" do
|
@@ -191,5 +228,18 @@ describe RFuse::Fuse do
|
|
191
228
|
end
|
192
229
|
end
|
193
230
|
|
231
|
+
it "should pass Errno exceptions through" do
|
232
|
+
mockfs.should_receive(:getattr).with(anything(),"/exceptions").and_raise(Errno::EPERM)
|
233
|
+
|
234
|
+
with_fuse(mountpoint,mockfs) do
|
235
|
+
begin
|
236
|
+
File.stat("#{mountpoint}/exceptions")
|
237
|
+
raise "should not get here"
|
238
|
+
rescue Errno::EPERM
|
239
|
+
#all good
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
194
244
|
end
|
195
245
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfuse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.5.RC0
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Grant Gardner
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: sys-filesystem
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
110
126
|
description: Write userspace filesystems in Ruby
|
111
127
|
email:
|
112
128
|
- grant@lastweekend.com.au
|
@@ -143,6 +159,7 @@ files:
|
|
143
159
|
- ext/rfuse/rfuse.c
|
144
160
|
- ext/rfuse/rfuse.h
|
145
161
|
- ext/rfuse/rfuse_mod.c
|
162
|
+
- ext/rfuse/ruby-compat.h
|
146
163
|
- lib/rfuse-ng.rb
|
147
164
|
- lib/rfuse.rb
|
148
165
|
- lib/rfuse/compat.rb
|
@@ -170,19 +187,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
187
|
version: '0'
|
171
188
|
segments:
|
172
189
|
- 0
|
173
|
-
hash: -
|
190
|
+
hash: -1417159270195176123
|
174
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
192
|
none: false
|
176
193
|
requirements:
|
177
|
-
- - ! '
|
194
|
+
- - ! '>'
|
178
195
|
- !ruby/object:Gem::Version
|
179
|
-
version:
|
180
|
-
segments:
|
181
|
-
- 0
|
182
|
-
hash: -1177971616363714193
|
196
|
+
version: 1.3.1
|
183
197
|
requirements: []
|
184
198
|
rubyforge_project:
|
185
|
-
rubygems_version: 1.8.
|
199
|
+
rubygems_version: 1.8.23
|
186
200
|
signing_key:
|
187
201
|
specification_version: 3
|
188
202
|
summary: Ruby language binding for FUSE
|