rfuse-ng 0.1
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/.gitignore +7 -0
- data/CHANGELOG.txt +2 -0
- data/LICENSE +482 -0
- data/README.ng +11 -0
- data/README.rfuse +57 -0
- data/Rakefile +23 -0
- data/THANKS +1 -0
- data/TODO.txt +6 -0
- data/ext/context.c +47 -0
- data/ext/context.h +5 -0
- data/ext/extconf.rb +12 -0
- data/ext/file_info.c +45 -0
- data/ext/file_info.h +11 -0
- data/ext/filler.c +33 -0
- data/ext/filler.h +13 -0
- data/ext/helper.c +20 -0
- data/ext/helper.h +7 -0
- data/ext/intern_rfuse.c +32 -0
- data/ext/intern_rfuse.h +21 -0
- data/ext/rfuse.c +864 -0
- data/ext/rfuse.h +3 -0
- data/ext/rfuse_mod.c +12 -0
- data/sample/test-ruby.rb +353 -0
- data/test/runtest +7 -0
- metadata +82 -0
data/ext/rfuse.c
ADDED
@@ -0,0 +1,864 @@
|
|
1
|
+
#ifdef linux
|
2
|
+
/* For pread()/pwrite() */
|
3
|
+
#define _XOPEN_SOURCE 500
|
4
|
+
#endif
|
5
|
+
//FOR LINUX ONLY
|
6
|
+
#include <linux/stat.h>
|
7
|
+
|
8
|
+
#include <ruby.h>
|
9
|
+
#include <fuse.h>
|
10
|
+
#include <errno.h>
|
11
|
+
#include <sys/statfs.h>
|
12
|
+
#ifdef HAVE_SETXATTR
|
13
|
+
#include <sys/xattr.h>
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include "helper.h"
|
17
|
+
#include "intern_rfuse.h"
|
18
|
+
#include "filler.h"
|
19
|
+
#include "context.h"
|
20
|
+
#include "file_info.h"
|
21
|
+
|
22
|
+
static VALUE fuse_object; //this is a global variable where we store the fuse object
|
23
|
+
|
24
|
+
static int unsafe_return_error(VALUE *args){
|
25
|
+
VALUE info;
|
26
|
+
info = rb_inspect(ruby_errinfo);
|
27
|
+
rb_backtrace();
|
28
|
+
printf ("ERROR %s\n",STR2CSTR(info));
|
29
|
+
return rb_funcall(info,rb_intern("errno"),0);
|
30
|
+
}
|
31
|
+
static int return_error(int def_error){
|
32
|
+
/*if the raised error has a method errno the return that value else
|
33
|
+
return def(ault)_error */
|
34
|
+
VALUE res;
|
35
|
+
int error = 0;
|
36
|
+
res=rb_protect((VALUE (*)())unsafe_return_error,Qnil,&error);
|
37
|
+
if (error) { //this exception has no errno method or something else
|
38
|
+
//went wrong
|
39
|
+
printf ("ERROR: Not an Errno::xxx error or exception in exception!\n");
|
40
|
+
return def_error;
|
41
|
+
} else {
|
42
|
+
return FIX2INT(res);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
static VALUE unsafe_readdir(VALUE *args){
|
47
|
+
VALUE *values=(VALUE*)args;
|
48
|
+
VALUE path = values[0];
|
49
|
+
VALUE filler = values[1];
|
50
|
+
VALUE offset = values[2];
|
51
|
+
VALUE ffi = values[3];
|
52
|
+
struct fuse_context *ctx = fuse_get_context();
|
53
|
+
return rb_funcall(fuse_object,rb_intern("readdir"),5,wrap_context(ctx),path,filler,
|
54
|
+
offset,ffi);
|
55
|
+
}
|
56
|
+
|
57
|
+
//call readdir with an Filler object
|
58
|
+
static int rf_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
59
|
+
off_t offset,struct fuse_file_info *ffi)
|
60
|
+
{
|
61
|
+
VALUE fuse_module;
|
62
|
+
VALUE rfiller_class;
|
63
|
+
VALUE rfiller_instance;
|
64
|
+
VALUE args[4];
|
65
|
+
VALUE res;
|
66
|
+
struct filler_t *fillerc;
|
67
|
+
int error = 0;
|
68
|
+
|
69
|
+
//create a filler object
|
70
|
+
args[0]=rb_str_new2(path);
|
71
|
+
|
72
|
+
fuse_module = rb_const_get(rb_cObject, rb_intern("RFuse"));
|
73
|
+
rfiller_class=rb_const_get(fuse_module,rb_intern("Filler"));
|
74
|
+
rfiller_instance=rb_funcall(rfiller_class,rb_intern("new"),0);
|
75
|
+
Data_Get_Struct(rfiller_instance,struct filler_t,fillerc);
|
76
|
+
fillerc->filler=filler;//Init the filler by hand.... TODO: cleaner
|
77
|
+
fillerc->buffer=buf;
|
78
|
+
args[1]=rfiller_instance;
|
79
|
+
args[2]=INT2NUM(offset);
|
80
|
+
args[3]=wrap_file_info(ffi);
|
81
|
+
res=rb_protect((VALUE (*)())unsafe_readdir,(VALUE)args,&error);
|
82
|
+
if (error) {
|
83
|
+
return -(return_error(ENOENT));
|
84
|
+
} else {
|
85
|
+
return 0;
|
86
|
+
};
|
87
|
+
}
|
88
|
+
//----------------------------------------------
|
89
|
+
|
90
|
+
static VALUE unsafe_readlink(VALUE *args){
|
91
|
+
VALUE *values=(VALUE*)args;
|
92
|
+
VALUE path = values[0];
|
93
|
+
VALUE size = values[1];
|
94
|
+
struct fuse_context *ctx = fuse_get_context();
|
95
|
+
return rb_funcall(fuse_object,rb_intern("readlink"),3,wrap_context(ctx),path,size);
|
96
|
+
}
|
97
|
+
|
98
|
+
static int rf_readlink(const char *path, char *buf, size_t size)
|
99
|
+
{
|
100
|
+
VALUE args[2];
|
101
|
+
VALUE res;
|
102
|
+
int error = 0;
|
103
|
+
args[0]=rb_str_new2(path);
|
104
|
+
args[1]=INT2NUM(size);
|
105
|
+
char *rbuf;
|
106
|
+
res=rb_protect((VALUE (*)())unsafe_readlink,(VALUE)args,&error);
|
107
|
+
if (error) {
|
108
|
+
return -(return_error(ENOENT));
|
109
|
+
} else {
|
110
|
+
rbuf=STR2CSTR(res);
|
111
|
+
strncpy(buf,rbuf,size);
|
112
|
+
return 0;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
//-----------------------------------------
|
116
|
+
static VALUE unsafe_getattr(VALUE *args){
|
117
|
+
VALUE *values=(VALUE*)args;
|
118
|
+
VALUE path = values[0];
|
119
|
+
struct fuse_context *ctx=fuse_get_context();
|
120
|
+
return rb_funcall(fuse_object,rb_intern("getattr"),2,wrap_context(ctx),path);
|
121
|
+
}
|
122
|
+
|
123
|
+
//calls getattr with path and expects something like FuseStat back
|
124
|
+
static int rf_getattr(const char *path, struct stat *stbuf)
|
125
|
+
{
|
126
|
+
VALUE args[1];
|
127
|
+
VALUE res;
|
128
|
+
int error = 0;
|
129
|
+
args[0]=rb_str_new2(path);
|
130
|
+
res=rb_protect((VALUE (*)())unsafe_getattr,(VALUE) args,&error);
|
131
|
+
if (error || (res == Qnil)) {
|
132
|
+
return -(return_error(ENOENT));
|
133
|
+
} else {
|
134
|
+
rstat2stat(res,stbuf);
|
135
|
+
return 0;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
//----------------------MKDIR
|
139
|
+
static VALUE unsafe_mkdir(VALUE *args){
|
140
|
+
VALUE *values=(VALUE*)args;
|
141
|
+
VALUE path = values[0];
|
142
|
+
VALUE mode = values[1];
|
143
|
+
struct fuse_context *ctx=fuse_get_context();
|
144
|
+
return rb_funcall(fuse_object,rb_intern("mkdir"),3,wrap_context(ctx),path,mode);
|
145
|
+
}
|
146
|
+
|
147
|
+
//calls getattr with path and expects something like FuseStat back
|
148
|
+
static int rf_mkdir(const char *path, mode_t mode)
|
149
|
+
{
|
150
|
+
VALUE args[2];
|
151
|
+
VALUE res;
|
152
|
+
int error = 0;
|
153
|
+
args[0]=rb_str_new2(path);
|
154
|
+
args[1]=INT2FIX(mode);
|
155
|
+
res=rb_protect((VALUE (*)())unsafe_mkdir,(VALUE) args,&error);
|
156
|
+
if (error) {
|
157
|
+
return -(return_error(ENOENT));
|
158
|
+
} else {
|
159
|
+
return 0;
|
160
|
+
};
|
161
|
+
}
|
162
|
+
//----------------------
|
163
|
+
|
164
|
+
//----------------------MKNOD
|
165
|
+
static VALUE unsafe_mknod(VALUE *args){
|
166
|
+
VALUE *values=(VALUE*)args;
|
167
|
+
VALUE path = values[0];
|
168
|
+
VALUE mode = values[1];
|
169
|
+
VALUE dev = values[2];
|
170
|
+
struct fuse_context *ctx=fuse_get_context();
|
171
|
+
return rb_funcall(fuse_object,rb_intern("mknod"),4,wrap_context(ctx),path,mode,dev);
|
172
|
+
}
|
173
|
+
|
174
|
+
//calls getattr with path and expects something like FuseStat back
|
175
|
+
static int rf_mknod(const char *path, mode_t mode,dev_t dev)
|
176
|
+
{
|
177
|
+
VALUE args[3];
|
178
|
+
VALUE res;
|
179
|
+
int error = 0;
|
180
|
+
args[0]=rb_str_new2(path);
|
181
|
+
args[1]=INT2FIX(mode);
|
182
|
+
args[2]=INT2FIX(dev);
|
183
|
+
res=rb_protect((VALUE (*)())unsafe_mknod,(VALUE) args,&error);
|
184
|
+
if (error) {
|
185
|
+
return -(return_error(ENOENT));
|
186
|
+
} else {
|
187
|
+
return 0;
|
188
|
+
};
|
189
|
+
}
|
190
|
+
//----------------------
|
191
|
+
//----------------------OPEN
|
192
|
+
static VALUE unsafe_open(VALUE *args){
|
193
|
+
VALUE *values=(VALUE*)args;
|
194
|
+
VALUE path = values[0];
|
195
|
+
VALUE ffi = values[1];
|
196
|
+
struct fuse_context *ctx=fuse_get_context();
|
197
|
+
return rb_funcall(fuse_object,rb_intern("open"),3,wrap_context(ctx),path,ffi);
|
198
|
+
}
|
199
|
+
|
200
|
+
//calls getattr with path and expects something like FuseStat back
|
201
|
+
static int rf_open(const char *path,struct fuse_file_info *ffi)
|
202
|
+
{
|
203
|
+
VALUE args[2];
|
204
|
+
VALUE res;
|
205
|
+
int error = 0;
|
206
|
+
args[0]=rb_str_new2(path);
|
207
|
+
args[1]=wrap_file_info(ffi);
|
208
|
+
res=rb_protect((VALUE (*)())unsafe_open,(VALUE) args,&error);
|
209
|
+
if (error) {
|
210
|
+
return -(return_error(ENOENT));
|
211
|
+
} else {
|
212
|
+
return 0;
|
213
|
+
};
|
214
|
+
}
|
215
|
+
//----------------------
|
216
|
+
//----------------------RELEASE
|
217
|
+
static VALUE unsafe_release(VALUE *args){
|
218
|
+
VALUE *values=(VALUE*)args;
|
219
|
+
VALUE path = values[0];
|
220
|
+
VALUE ffi = values[1];
|
221
|
+
struct fuse_context *ctx=fuse_get_context();
|
222
|
+
return rb_funcall(fuse_object,rb_intern("release"),3,wrap_context(ctx),path,ffi);
|
223
|
+
}
|
224
|
+
|
225
|
+
static int rf_release(const char *path, struct fuse_file_info *ffi)
|
226
|
+
{
|
227
|
+
VALUE args[2];
|
228
|
+
VALUE res;
|
229
|
+
int error = 0;
|
230
|
+
args[0]=rb_str_new2(path);
|
231
|
+
args[1]=wrap_file_info(ffi);
|
232
|
+
res=rb_protect((VALUE (*)())unsafe_release,(VALUE) args,&error);
|
233
|
+
if (error) {
|
234
|
+
return -(return_error(ENOENT));
|
235
|
+
} else {
|
236
|
+
return 0;
|
237
|
+
};
|
238
|
+
}
|
239
|
+
//----------------------
|
240
|
+
//----------------------FLUSH
|
241
|
+
static VALUE unsafe_flush(VALUE *args){
|
242
|
+
VALUE *values=(VALUE*)args;
|
243
|
+
VALUE path = values[0];
|
244
|
+
VALUE ffi=values[1];
|
245
|
+
struct fuse_context *ctx=fuse_get_context();
|
246
|
+
return rb_funcall(fuse_object,rb_intern("flush"),3,wrap_context(ctx),path,ffi);
|
247
|
+
}
|
248
|
+
|
249
|
+
static int rf_flush(const char *path,struct fuse_file_info *ffi)
|
250
|
+
{
|
251
|
+
VALUE args[2];
|
252
|
+
VALUE res;
|
253
|
+
int error = 0;
|
254
|
+
args[0]=rb_str_new2(path);
|
255
|
+
args[1]=wrap_file_info(ffi);
|
256
|
+
res=rb_protect((VALUE (*)())unsafe_flush,(VALUE) args,&error);
|
257
|
+
if (error) {
|
258
|
+
return -(return_error(ENOENT));
|
259
|
+
} else {
|
260
|
+
return 0;
|
261
|
+
};
|
262
|
+
}
|
263
|
+
//----------------------
|
264
|
+
//----------------------TRUNCATE
|
265
|
+
static VALUE unsafe_truncate(VALUE *args){
|
266
|
+
VALUE *values=(VALUE*)args;
|
267
|
+
VALUE path = values[0];
|
268
|
+
VALUE offset = values[1];
|
269
|
+
struct fuse_context *ctx=fuse_get_context();
|
270
|
+
return rb_funcall(fuse_object,rb_intern("truncate"),3,wrap_context(ctx),path,offset);
|
271
|
+
}
|
272
|
+
|
273
|
+
static int rf_truncate(const char *path,off_t offset)
|
274
|
+
{
|
275
|
+
VALUE args[2];
|
276
|
+
VALUE res;
|
277
|
+
int error = 0;
|
278
|
+
args[0]=rb_str_new2(path);
|
279
|
+
args[1]=INT2FIX(offset);
|
280
|
+
res=rb_protect((VALUE (*)())unsafe_truncate,(VALUE) args,&error);
|
281
|
+
if (error) {
|
282
|
+
return -(return_error(ENOENT));
|
283
|
+
} else {
|
284
|
+
return 0;
|
285
|
+
};
|
286
|
+
}
|
287
|
+
//----------------------
|
288
|
+
//----------------------UTIME
|
289
|
+
static VALUE unsafe_utime(VALUE *args){
|
290
|
+
VALUE *values=(VALUE*)args;
|
291
|
+
VALUE path = values[0];
|
292
|
+
VALUE actime = values[1];
|
293
|
+
VALUE modtime = values[2];
|
294
|
+
struct fuse_context *ctx=fuse_get_context();
|
295
|
+
return rb_funcall(fuse_object,rb_intern("utime"),4,wrap_context(ctx),path,actime,modtime);
|
296
|
+
}
|
297
|
+
|
298
|
+
static int rf_utime(const char *path,struct utimbuf *utim)
|
299
|
+
{
|
300
|
+
VALUE args[3];
|
301
|
+
VALUE res;
|
302
|
+
int error = 0;
|
303
|
+
args[0]=rb_str_new2(path);
|
304
|
+
args[1]=INT2NUM(utim->actime);
|
305
|
+
args[2]=INT2NUM(utim->modtime);
|
306
|
+
res=rb_protect((VALUE (*)())unsafe_utime,(VALUE) args,&error);
|
307
|
+
if (error) {
|
308
|
+
return -(return_error(ENOENT));
|
309
|
+
} else {
|
310
|
+
return 0;
|
311
|
+
};
|
312
|
+
}
|
313
|
+
//----------------------
|
314
|
+
//----------------------CHOWN
|
315
|
+
static VALUE unsafe_chown(VALUE *args){
|
316
|
+
VALUE *values=(VALUE*)args;
|
317
|
+
VALUE path = values[0];
|
318
|
+
VALUE uid = values[1];
|
319
|
+
VALUE gid = values[2];
|
320
|
+
struct fuse_context *ctx=fuse_get_context();
|
321
|
+
return rb_funcall(fuse_object,rb_intern("chown"),4,wrap_context(ctx),path,uid,gid);
|
322
|
+
}
|
323
|
+
|
324
|
+
static int rf_chown(const char *path,uid_t uid,gid_t gid)
|
325
|
+
{
|
326
|
+
VALUE args[3];
|
327
|
+
VALUE res;
|
328
|
+
int error = 0;
|
329
|
+
args[0]=rb_str_new2(path);
|
330
|
+
args[1]=INT2FIX(uid);
|
331
|
+
args[2]=INT2FIX(gid);
|
332
|
+
res=rb_protect((VALUE (*)())unsafe_chown,(VALUE) args,&error);
|
333
|
+
if (error) {
|
334
|
+
return -(return_error(ENOENT));
|
335
|
+
} else {
|
336
|
+
return 0;
|
337
|
+
};
|
338
|
+
}
|
339
|
+
//----------------------
|
340
|
+
//----------------------CHMOD
|
341
|
+
static VALUE unsafe_chmod(VALUE *args){
|
342
|
+
VALUE *values=(VALUE*)args;
|
343
|
+
VALUE path = values[0];
|
344
|
+
VALUE mode = values[1];
|
345
|
+
struct fuse_context *ctx=fuse_get_context();
|
346
|
+
return rb_funcall(fuse_object,rb_intern("chmod"),3,wrap_context(ctx),path,mode);
|
347
|
+
}
|
348
|
+
|
349
|
+
static int rf_chmod(const char *path,mode_t mode)
|
350
|
+
{
|
351
|
+
VALUE args[2];
|
352
|
+
VALUE res;
|
353
|
+
int error = 0;
|
354
|
+
args[0]=rb_str_new2(path);
|
355
|
+
args[1]=INT2FIX(mode);
|
356
|
+
res=rb_protect((VALUE (*)())unsafe_chmod,(VALUE) args,&error);
|
357
|
+
if (error) {
|
358
|
+
return -(return_error(ENOENT));
|
359
|
+
} else {
|
360
|
+
return 0;
|
361
|
+
};
|
362
|
+
}
|
363
|
+
//----------------------
|
364
|
+
//----------------------UNLINK
|
365
|
+
static VALUE unsafe_unlink(VALUE *args){
|
366
|
+
VALUE *values=(VALUE*)args;
|
367
|
+
VALUE path = values[0];
|
368
|
+
struct fuse_context *ctx=fuse_get_context();
|
369
|
+
return rb_funcall(fuse_object,rb_intern("unlink"),2,wrap_context(ctx),path);
|
370
|
+
}
|
371
|
+
|
372
|
+
static int rf_unlink(const char *path)
|
373
|
+
{
|
374
|
+
VALUE args[1];
|
375
|
+
VALUE res;
|
376
|
+
int error = 0;
|
377
|
+
args[0]=rb_str_new2(path);
|
378
|
+
res=rb_protect((VALUE (*)())unsafe_unlink,(VALUE) args,&error);
|
379
|
+
if (error) {
|
380
|
+
return -(return_error(ENOENT));
|
381
|
+
} else {
|
382
|
+
return 0;
|
383
|
+
};
|
384
|
+
}
|
385
|
+
//----------------------
|
386
|
+
//----------------------RMDIR
|
387
|
+
static VALUE unsafe_rmdir(VALUE *args){
|
388
|
+
VALUE *values=(VALUE*)args;
|
389
|
+
VALUE path = values[0];
|
390
|
+
struct fuse_context *ctx=fuse_get_context();
|
391
|
+
return rb_funcall(fuse_object,rb_intern("rmdir"),2,wrap_context(ctx),path);
|
392
|
+
}
|
393
|
+
|
394
|
+
static int rf_rmdir(const char *path)
|
395
|
+
{
|
396
|
+
VALUE args[1];
|
397
|
+
VALUE res;
|
398
|
+
int error = 0;
|
399
|
+
args[0]=rb_str_new2(path);
|
400
|
+
res=rb_protect((VALUE (*)())unsafe_rmdir,(VALUE) args,&error);
|
401
|
+
if (error) {
|
402
|
+
return -(return_error(ENOENT));
|
403
|
+
} else {
|
404
|
+
return 0;
|
405
|
+
};
|
406
|
+
}
|
407
|
+
//----------------------
|
408
|
+
//----------------------SYMLINK
|
409
|
+
static VALUE unsafe_symlink(VALUE *args){
|
410
|
+
VALUE *values=(VALUE*)args;
|
411
|
+
VALUE path = values[0];
|
412
|
+
VALUE as = values[1];
|
413
|
+
struct fuse_context *ctx=fuse_get_context();
|
414
|
+
return rb_funcall(fuse_object,rb_intern("symlink"),3,wrap_context(ctx),path,as);
|
415
|
+
}
|
416
|
+
|
417
|
+
static int rf_symlink(const char *path,const char *as)
|
418
|
+
{
|
419
|
+
VALUE args[2];
|
420
|
+
VALUE res;
|
421
|
+
int error = 0;
|
422
|
+
args[0]=rb_str_new2(path);
|
423
|
+
args[1]=rb_str_new2(as);
|
424
|
+
res=rb_protect((VALUE (*)())unsafe_symlink,(VALUE) args,&error);
|
425
|
+
if (error) {
|
426
|
+
return -(return_error(ENOENT));
|
427
|
+
} else {
|
428
|
+
return 0;
|
429
|
+
};
|
430
|
+
}
|
431
|
+
//----------------------
|
432
|
+
//----------------------RENAME
|
433
|
+
static VALUE unsafe_rename(VALUE *args){
|
434
|
+
VALUE *values=(VALUE*)args;
|
435
|
+
VALUE path = values[0];
|
436
|
+
VALUE as = values[1];
|
437
|
+
struct fuse_context *ctx=fuse_get_context();
|
438
|
+
return rb_funcall(fuse_object,rb_intern("rename"),3,wrap_context(ctx),path,as);
|
439
|
+
}
|
440
|
+
|
441
|
+
static int rf_rename(const char *path,const char *as)
|
442
|
+
{
|
443
|
+
VALUE args[2];
|
444
|
+
VALUE res;
|
445
|
+
int error = 0;
|
446
|
+
args[0]=rb_str_new2(path);
|
447
|
+
args[1]=rb_str_new2(as);
|
448
|
+
res=rb_protect((VALUE (*)())unsafe_rename,(VALUE) args,&error);
|
449
|
+
if (error) {
|
450
|
+
return -(return_error(ENOENT));
|
451
|
+
} else {
|
452
|
+
return 0;
|
453
|
+
};
|
454
|
+
}
|
455
|
+
//----------------------
|
456
|
+
//----------------------LINK
|
457
|
+
static VALUE unsafe_link(VALUE *args){
|
458
|
+
VALUE *values=(VALUE*)args;
|
459
|
+
VALUE path = values[0];
|
460
|
+
VALUE as = values[1];
|
461
|
+
struct fuse_context *ctx=fuse_get_context();
|
462
|
+
return rb_funcall(fuse_object,rb_intern("link"),3,wrap_context(ctx),path,as);
|
463
|
+
}
|
464
|
+
|
465
|
+
static int rf_link(const char *path,const char * as)
|
466
|
+
{
|
467
|
+
VALUE args[2];
|
468
|
+
VALUE res;
|
469
|
+
int error = 0;
|
470
|
+
args[0]=rb_str_new2(path);
|
471
|
+
args[1]=rb_str_new2(as);
|
472
|
+
res=rb_protect((VALUE (*)())unsafe_link,(VALUE) args,&error);
|
473
|
+
if (error) {
|
474
|
+
return -(return_error(ENOENT));
|
475
|
+
} else {
|
476
|
+
return 0;
|
477
|
+
};
|
478
|
+
}
|
479
|
+
//----------------------
|
480
|
+
//----------------------READ
|
481
|
+
static VALUE unsafe_read(VALUE *args){
|
482
|
+
VALUE *values=(VALUE*)args;
|
483
|
+
VALUE path = values[0];
|
484
|
+
VALUE size = values[1];
|
485
|
+
VALUE offset = values[2];
|
486
|
+
VALUE ffi = values[3];
|
487
|
+
struct fuse_context *ctx=fuse_get_context();
|
488
|
+
return rb_funcall(fuse_object,rb_intern("read"),5,
|
489
|
+
wrap_context(ctx),path,size,offset,ffi);
|
490
|
+
}
|
491
|
+
|
492
|
+
static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct fuse_file_info *ffi)
|
493
|
+
{
|
494
|
+
VALUE args[4];
|
495
|
+
VALUE res;
|
496
|
+
int error = 0;
|
497
|
+
long length=0;
|
498
|
+
char* rbuf;
|
499
|
+
args[0]=rb_str_new2(path);
|
500
|
+
args[1]=INT2NUM(size);
|
501
|
+
args[2]=INT2NUM(offset);
|
502
|
+
args[3]=wrap_file_info(ffi);
|
503
|
+
res=rb_protect((VALUE (*)())unsafe_read,(VALUE) args,&error);
|
504
|
+
if (error) {
|
505
|
+
return -(return_error(ENOENT));
|
506
|
+
} else {
|
507
|
+
rbuf=rb_str2cstr(res,&length); //TODO protect this, too
|
508
|
+
if (length<=size) {
|
509
|
+
memcpy(buf,rbuf,length);
|
510
|
+
return length;
|
511
|
+
} else {
|
512
|
+
memcpy(buf,rbuf,size); //TODO: This could be dangerous.
|
513
|
+
//Perhaps raise an exception or return an error
|
514
|
+
return size;
|
515
|
+
}
|
516
|
+
};
|
517
|
+
}
|
518
|
+
//----------------------
|
519
|
+
//----------------------WRITE
|
520
|
+
static VALUE unsafe_write(VALUE *args){
|
521
|
+
VALUE *values=(VALUE*)args;
|
522
|
+
VALUE path = values[0];
|
523
|
+
VALUE buffer = values[1];
|
524
|
+
VALUE size = values[2];
|
525
|
+
VALUE offset = values[3];
|
526
|
+
VALUE ffi = values[4];
|
527
|
+
struct fuse_context *ctx=fuse_get_context();
|
528
|
+
return rb_funcall(fuse_object,rb_intern("write"),6,
|
529
|
+
wrap_context(ctx),path,buffer,size,offset,ffi);
|
530
|
+
}
|
531
|
+
|
532
|
+
static int rf_write(const char *path,const char *buf,size_t size, off_t offset,struct fuse_file_info *ffi)
|
533
|
+
{
|
534
|
+
VALUE args[5];
|
535
|
+
VALUE res;
|
536
|
+
int error = 0;
|
537
|
+
args[0]=rb_str_new2(path);
|
538
|
+
args[1]=rb_str_new2(buf);
|
539
|
+
args[2]=INT2NUM(size);
|
540
|
+
args[3]=INT2NUM(offset);
|
541
|
+
args[4]=wrap_file_info(ffi);
|
542
|
+
res=rb_protect((VALUE (*)())unsafe_write,(VALUE) args,&error);
|
543
|
+
if (error) {
|
544
|
+
return -(return_error(ENOENT));
|
545
|
+
} else {
|
546
|
+
return 0;
|
547
|
+
};
|
548
|
+
}
|
549
|
+
//----------------------
|
550
|
+
//----------------------SETXATTR
|
551
|
+
static VALUE unsafe_setxattr(VALUE *args){
|
552
|
+
VALUE *values=(VALUE*)args;
|
553
|
+
VALUE path = values[0];
|
554
|
+
VALUE name = values[1];
|
555
|
+
VALUE value = values[2];
|
556
|
+
VALUE size = values[3];
|
557
|
+
VALUE flags = values[4];
|
558
|
+
struct fuse_context *ctx=fuse_get_context();
|
559
|
+
return rb_funcall(fuse_object,rb_intern("setxattr"),6,
|
560
|
+
wrap_context(ctx),path,name,value,size,flags);
|
561
|
+
}
|
562
|
+
|
563
|
+
static int rf_setxattr(const char *path,const char *name,
|
564
|
+
const char *value, size_t size, int flags)
|
565
|
+
{
|
566
|
+
VALUE args[5];
|
567
|
+
VALUE res;
|
568
|
+
int error = 0;
|
569
|
+
args[0]=rb_str_new2(path);
|
570
|
+
args[1]=rb_str_new2(name);
|
571
|
+
args[2]=rb_str_new(value,size);
|
572
|
+
args[3]=INT2NUM(size); //TODO:FIX would be faster
|
573
|
+
args[4]=INT2NUM(flags);
|
574
|
+
res=rb_protect((VALUE (*)())unsafe_setxattr,(VALUE) args,&error);
|
575
|
+
if (error) {
|
576
|
+
return -(return_error(ENOENT));
|
577
|
+
} else {
|
578
|
+
return 0;
|
579
|
+
};
|
580
|
+
}
|
581
|
+
//----------------------
|
582
|
+
//----------------------GETXATTR
|
583
|
+
static VALUE unsafe_getxattr(VALUE *args){
|
584
|
+
VALUE *values=(VALUE*)args;
|
585
|
+
VALUE path = values[0];
|
586
|
+
VALUE name = values[1];
|
587
|
+
VALUE size = values[2];
|
588
|
+
struct fuse_context *ctx=fuse_get_context();
|
589
|
+
return rb_funcall(fuse_object,rb_intern("getxattr"),4,
|
590
|
+
wrap_context(ctx),path,name,size);
|
591
|
+
}
|
592
|
+
|
593
|
+
static int rf_getxattr(const char *path,const char *name,char *buf,
|
594
|
+
size_t size)
|
595
|
+
{
|
596
|
+
VALUE args[3];
|
597
|
+
VALUE res;
|
598
|
+
char *rbuf;
|
599
|
+
long length = 0;
|
600
|
+
int error = 0;
|
601
|
+
args[0]=rb_str_new2(path);
|
602
|
+
args[1]=rb_str_new2(name);
|
603
|
+
args[2]=INT2NUM(size);
|
604
|
+
res=rb_protect((VALUE (*)())unsafe_getxattr,(VALUE) args,&error);
|
605
|
+
if (error) {
|
606
|
+
return -(return_error(ENOENT));
|
607
|
+
} else {
|
608
|
+
rbuf=rb_str2cstr(res,&length); //TODO protect this, too
|
609
|
+
if (buf != NULL) {
|
610
|
+
memcpy(buf,rbuf,length); //First call is just to get the length
|
611
|
+
//TODO optimize
|
612
|
+
}
|
613
|
+
return length;
|
614
|
+
}
|
615
|
+
}
|
616
|
+
//----------------------
|
617
|
+
//----------------------LISTXATTR
|
618
|
+
static VALUE unsafe_listxattr(VALUE *args){
|
619
|
+
VALUE *values=(VALUE*)args;
|
620
|
+
VALUE path = values[0];
|
621
|
+
VALUE size = values[1];
|
622
|
+
struct fuse_context *ctx=fuse_get_context();
|
623
|
+
return rb_funcall(fuse_object,rb_intern("listxattr"),3,
|
624
|
+
wrap_context(ctx),path,size);
|
625
|
+
}
|
626
|
+
|
627
|
+
static int rf_listxattr(const char *path,char *buf,
|
628
|
+
size_t size)
|
629
|
+
{
|
630
|
+
VALUE args[2];
|
631
|
+
VALUE res;
|
632
|
+
char *rbuf;
|
633
|
+
size_t length =0;
|
634
|
+
int error = 0;
|
635
|
+
args[0]=rb_str_new2(path);
|
636
|
+
args[1]=INT2NUM(size);
|
637
|
+
res=rb_protect((VALUE (*)())unsafe_listxattr,(VALUE) args,&error);
|
638
|
+
if (error) {
|
639
|
+
return -(return_error(ENOENT));
|
640
|
+
} else {
|
641
|
+
rbuf=rb_str2cstr(res,(long *)&length); //TODO protect this, too
|
642
|
+
if (buf != NULL){
|
643
|
+
if (length<=size) {
|
644
|
+
memcpy(buf,rbuf,length); //check for size
|
645
|
+
} else {
|
646
|
+
return -ERANGE;
|
647
|
+
}
|
648
|
+
printf("destination: %s,%d\n",buf,size);
|
649
|
+
printf("source: %s,%d\n",rbuf,length);
|
650
|
+
return length;
|
651
|
+
//TODO optimize,check lenght
|
652
|
+
} else {
|
653
|
+
printf ("not copied: %s, %d\n",buf,length);
|
654
|
+
return length;
|
655
|
+
}
|
656
|
+
}
|
657
|
+
}
|
658
|
+
//----------------------
|
659
|
+
//----------------------REMOVEXATTR
|
660
|
+
static VALUE unsafe_removexattr(VALUE *args){
|
661
|
+
VALUE *values=(VALUE*)args;
|
662
|
+
VALUE path = values[0];
|
663
|
+
VALUE name = values[1];
|
664
|
+
struct fuse_context *ctx=fuse_get_context();
|
665
|
+
return rb_funcall(fuse_object,rb_intern("removexattr"),3,
|
666
|
+
wrap_context(ctx),path,name);
|
667
|
+
}
|
668
|
+
|
669
|
+
static int rf_removexattr(const char *path,const char *name)
|
670
|
+
{
|
671
|
+
VALUE args[2];
|
672
|
+
VALUE res;
|
673
|
+
int error = 0;
|
674
|
+
args[0]=rb_str_new2(path);
|
675
|
+
args[1]=rb_str_new2(name);
|
676
|
+
res=rb_protect((VALUE (*)())unsafe_removexattr,(VALUE) args,&error);
|
677
|
+
if (error) {
|
678
|
+
return -(return_error(ENOENT));
|
679
|
+
} else {
|
680
|
+
return 0;
|
681
|
+
};
|
682
|
+
}
|
683
|
+
//----------------------
|
684
|
+
//----------------------OPENDIR
|
685
|
+
static VALUE unsafe_opendir(VALUE *args){
|
686
|
+
VALUE *values=(VALUE*)args;
|
687
|
+
VALUE path = values[0];
|
688
|
+
VALUE ffi = values[1];
|
689
|
+
struct fuse_context *ctx=fuse_get_context();
|
690
|
+
return rb_funcall(fuse_object,rb_intern("opendir"),3,wrap_context(ctx),path,ffi);
|
691
|
+
}
|
692
|
+
|
693
|
+
static int rf_opendir(const char *path,struct fuse_file_info *ffi)
|
694
|
+
{
|
695
|
+
VALUE args[2];
|
696
|
+
VALUE res;
|
697
|
+
int error = 0;
|
698
|
+
args[0]=rb_str_new2(path);
|
699
|
+
args[1]=wrap_file_info(ffi);
|
700
|
+
res=rb_protect((VALUE (*)())unsafe_opendir,(VALUE) args,&error);
|
701
|
+
if (error) {
|
702
|
+
return -(return_error(ENOENT));
|
703
|
+
} else {
|
704
|
+
return 0;
|
705
|
+
};
|
706
|
+
}
|
707
|
+
//----------------------
|
708
|
+
//----------------------RELEASEDIR
|
709
|
+
static VALUE unsafe_releasedir(VALUE *args){
|
710
|
+
VALUE *values=(VALUE*)args;
|
711
|
+
VALUE path = values[0];
|
712
|
+
VALUE ffi = values[1];
|
713
|
+
struct fuse_context *ctx=fuse_get_context();
|
714
|
+
return rb_funcall(fuse_object,rb_intern("releasedir"),3,wrap_context(ctx),path,ffi);
|
715
|
+
}
|
716
|
+
|
717
|
+
static int rf_releasedir(const char *path,struct fuse_file_info *ffi)
|
718
|
+
{
|
719
|
+
VALUE args[2];
|
720
|
+
VALUE res;
|
721
|
+
int error = 0;
|
722
|
+
args[0]=rb_str_new2(path);
|
723
|
+
args[1]=wrap_file_info(ffi);
|
724
|
+
res=rb_protect((VALUE (*)())unsafe_releasedir,(VALUE) args,&error);
|
725
|
+
if (error) {
|
726
|
+
return -(return_error(ENOENT));
|
727
|
+
} else {
|
728
|
+
return 0;
|
729
|
+
};
|
730
|
+
}
|
731
|
+
//----------------------
|
732
|
+
//----------------------FSYNCDIR
|
733
|
+
static VALUE unsafe_fsyncdir(VALUE *args){
|
734
|
+
VALUE *values=(VALUE*)args;
|
735
|
+
VALUE path = values[0];
|
736
|
+
VALUE meta = values[1];
|
737
|
+
VALUE ffi = values[2];
|
738
|
+
struct fuse_context *ctx=fuse_get_context();
|
739
|
+
return rb_funcall(fuse_object,rb_intern("fsyncdir"),3,wrap_context(ctx),path,
|
740
|
+
meta,ffi);
|
741
|
+
}
|
742
|
+
|
743
|
+
static int rf_fsyncdir(const char *path,int meta,struct fuse_file_info *ffi)
|
744
|
+
{
|
745
|
+
VALUE args[3];
|
746
|
+
VALUE res;
|
747
|
+
int error = 0;
|
748
|
+
args[0]=rb_str_new2(path);
|
749
|
+
args[1]=INT2NUM(meta);
|
750
|
+
args[2]=wrap_file_info(ffi);
|
751
|
+
res=rb_protect((VALUE (*)())unsafe_fsyncdir,(VALUE) args,&error);
|
752
|
+
if (error) {
|
753
|
+
return -(return_error(ENOENT));
|
754
|
+
} else {
|
755
|
+
return 0;
|
756
|
+
};
|
757
|
+
}
|
758
|
+
//----------------------
|
759
|
+
|
760
|
+
static VALUE rf_loop(VALUE self){
|
761
|
+
struct intern_fuse *inf;
|
762
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
763
|
+
fuse_loop(inf->fuse);
|
764
|
+
return Qnil;
|
765
|
+
}
|
766
|
+
|
767
|
+
/*static VALUE rf_loop_mt(VALUE self){
|
768
|
+
struct intern_fuse *inf;
|
769
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
770
|
+
fuse_loop_mt(inf->fuse);
|
771
|
+
return Qnil;
|
772
|
+
}*/
|
773
|
+
|
774
|
+
VALUE rf_exit(VALUE self){
|
775
|
+
struct intern_fuse *inf;
|
776
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
777
|
+
fuse_exit(inf->fuse);
|
778
|
+
return Qnil;
|
779
|
+
}
|
780
|
+
|
781
|
+
VALUE rf_unmount(VALUE self){
|
782
|
+
struct intern_fuse *inf;
|
783
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
784
|
+
fuse_unmount(inf->mountname);
|
785
|
+
return Qnil;
|
786
|
+
}
|
787
|
+
|
788
|
+
VALUE rf_mountname(VALUE self){
|
789
|
+
struct intern_fuse *inf;
|
790
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
791
|
+
return rb_str_new2(inf->mountname);
|
792
|
+
}
|
793
|
+
VALUE rf_invalidate(VALUE self,VALUE path){
|
794
|
+
struct intern_fuse *inf;
|
795
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
796
|
+
return fuse_invalidate(inf->fuse,STR2CSTR(path)); //TODO: check if str?
|
797
|
+
}
|
798
|
+
//-------------RUBY
|
799
|
+
|
800
|
+
|
801
|
+
static VALUE rf_initialize(VALUE self,VALUE mountpoint,VALUE kernelopts,
|
802
|
+
VALUE libopts) {
|
803
|
+
struct intern_fuse *inf;
|
804
|
+
Data_Get_Struct(self,struct intern_fuse,inf);
|
805
|
+
inf->fuse_op.getattr=rf_getattr;
|
806
|
+
// inf->fuse_op.getdir=rf_getdir;
|
807
|
+
inf->fuse_op.readlink=rf_readlink;
|
808
|
+
inf->fuse_op.mkdir=rf_mkdir;
|
809
|
+
inf->fuse_op.mknod=rf_mknod;
|
810
|
+
inf->fuse_op.open=rf_open;
|
811
|
+
inf->fuse_op.release=rf_release; //optional
|
812
|
+
inf->fuse_op.flush=rf_flush; //optional
|
813
|
+
inf->fuse_op.chmod=rf_chmod; //setattr
|
814
|
+
inf->fuse_op.chown=rf_chown; //setattr
|
815
|
+
inf->fuse_op.truncate=rf_truncate;//setattr
|
816
|
+
inf->fuse_op.utime=rf_utime; //settattr
|
817
|
+
inf->fuse_op.unlink=rf_unlink;
|
818
|
+
inf->fuse_op.rmdir=rf_rmdir;
|
819
|
+
inf->fuse_op.symlink=rf_symlink;
|
820
|
+
inf->fuse_op.rename=rf_rename;
|
821
|
+
inf->fuse_op.link=rf_link;
|
822
|
+
inf->fuse_op.read=rf_read;
|
823
|
+
inf->fuse_op.write=rf_write;
|
824
|
+
inf->fuse_op.setxattr=rf_setxattr;
|
825
|
+
inf->fuse_op.getxattr=rf_getxattr;
|
826
|
+
inf->fuse_op.listxattr=rf_listxattr;
|
827
|
+
inf->fuse_op.removexattr=rf_removexattr;
|
828
|
+
inf->fuse_op.readdir=rf_readdir;
|
829
|
+
inf->fuse_op.opendir=rf_opendir;
|
830
|
+
inf->fuse_op.releasedir=rf_releasedir;
|
831
|
+
inf->fuse_op.fsyncdir=rf_fsyncdir;
|
832
|
+
|
833
|
+
/* TODO
|
834
|
+
inf->fuse_op.statfs=rf_statfs;
|
835
|
+
inf->fuse_op.fsnyc=rf_fsync; //option
|
836
|
+
*/
|
837
|
+
|
838
|
+
intern_fuse_init(inf,STR2CSTR(mountpoint),STR2CSTR(kernelopts),
|
839
|
+
STR2CSTR(libopts));
|
840
|
+
fuse_object=self; // this won't work with multithreading!!!
|
841
|
+
return self;
|
842
|
+
}
|
843
|
+
|
844
|
+
static VALUE rf_new(VALUE class){
|
845
|
+
struct intern_fuse *inf;
|
846
|
+
VALUE self;
|
847
|
+
inf = intern_fuse_new();
|
848
|
+
self=Data_Wrap_Struct(class, 0,intern_fuse_destroy,inf);
|
849
|
+
return self;
|
850
|
+
}
|
851
|
+
|
852
|
+
VALUE rfuse_init(VALUE module){
|
853
|
+
VALUE cFuse=rb_define_class_under(module,"Fuse",rb_cObject);
|
854
|
+
rb_define_alloc_func(cFuse,rf_new);
|
855
|
+
//initialize: string mountpoint,string kernel_opts,string lib_opts
|
856
|
+
rb_define_method(cFuse,"initialize",rf_initialize,3);
|
857
|
+
rb_define_method(cFuse,"loop",rf_loop,0);
|
858
|
+
//rb_define_method(cFuse,"loop_mt",rf_loop_mt,0); TODO: not until RIKE!
|
859
|
+
rb_define_method(cFuse,"exit",rf_exit,0);
|
860
|
+
rb_define_method(cFuse,"invalidate",rf_invalidate,1);
|
861
|
+
rb_define_method(cFuse,"unmount",rf_unmount,0);
|
862
|
+
rb_define_method(cFuse,"mountname",rf_mountname,0);
|
863
|
+
return cFuse;
|
864
|
+
}
|