rfuse 1.2.3 → 2.0.0.ffilibfuse

Sign up to get free protection for your applications and to get access to all the features.
data/ext/rfuse/rfuse.c DELETED
@@ -1,2007 +0,0 @@
1
- #ifdef linux
2
- /* For pread()/pwrite() */
3
- #define _XOPEN_SOURCE 500
4
- #endif
5
- //FOR LINUX ONLY
6
- //#include <linux/stat.h>
7
- #include <linux/kdev_t.h>
8
-
9
- #include <ruby.h>
10
- #include "ruby-compat.h"
11
- #include <fuse.h>
12
- #include <errno.h>
13
- #include <sys/statfs.h>
14
-
15
- #ifdef HAVE_SETXATTR
16
- #include <sys/xattr.h>
17
- #endif
18
-
19
- #include "helper.h"
20
- #include "intern_rfuse.h"
21
- #include "filler.h"
22
- #include "context.h"
23
-
24
- #include "file_info.h"
25
- #include "pollhandle.h"
26
- #include "bufferwrapper.h"
27
-
28
-
29
- static VALUE mRFuse;
30
- static VALUE eRFuse_Error;
31
-
32
- static int unsafe_return_error(VALUE *args)
33
- {
34
-
35
- if (rb_respond_to(rb_errinfo(),rb_intern("errno"))) {
36
- VALUE res;
37
- //We expect these and they get passed on the fuse so be quiet...
38
- res = rb_funcall(rb_errinfo(),rb_intern("errno"),0);
39
- rb_set_errinfo(Qnil);
40
- return res;
41
- } else {
42
- VALUE info;
43
- VALUE bt_ary;
44
- int c;
45
-
46
- info = rb_inspect(rb_errinfo());
47
- printf ("ERROR: Exception %s not an Errno:: !respond_to?(:errno) \n",StringValueCStr(info));
48
- //We need the ruby_errinfo backtrace not fuse.loop ... rb_backtrace();
49
- bt_ary = rb_funcall(rb_errinfo(), rb_intern("backtrace"),0);
50
-
51
- for (c=0;c<RARRAY_LEN(bt_ary);c++) {
52
- printf("%s\n",StringValueCStr(RARRAY_PTR(bt_ary)[c]));
53
- }
54
- return Qnil;
55
- }
56
- }
57
-
58
- static int return_error(int def_error)
59
- {
60
- /*if the raised error has a method errno the return that value else
61
- return def(ault)_error */
62
- VALUE res;
63
- int error = 0;
64
- res=rb_protect((VALUE (*)())unsafe_return_error,Qnil,&error);
65
- if (error)
66
- {
67
- //something went wrong resolving the exception
68
- printf ("ERROR: Exception in exception!\n");
69
- return def_error;
70
- }
71
- else
72
- {
73
- return NIL_P(res) ? def_error : FIX2INT(res);
74
- }
75
- }
76
-
77
- //Every call needs this stuff
78
- static void init_context_path_args(VALUE *args,struct fuse_context *ctx,const char *path)
79
- {
80
- args[0] = (VALUE) ctx->private_data;
81
- args[1] = wrap_context(ctx);
82
- args[2] = rb_str_new2(path);
83
- rb_filesystem_encode(args[2]);
84
- }
85
- /*
86
- @overload readdir(context,path,filler,offset,ffi)
87
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#0f634deda31d1e1c42664585ae820076 readdir}
88
-
89
- List contents of a directory
90
-
91
- @param [Context] context
92
- @param [String] path
93
- @param [Filler] filler
94
- @param [Fixnum] offset
95
- @param [FileInfo] ffi
96
-
97
- @return [void]
98
- @raise [Errno]
99
- @todo the API for the filler could be more ruby like - eg yield
100
- */
101
- static VALUE unsafe_readdir(VALUE *args)
102
- {
103
- return rb_funcall3(args[0],rb_intern("readdir"),5,&args[1]);
104
- }
105
-
106
- static int rf_readdir(const char *path, void *buf,
107
- fuse_fill_dir_t filler, off_t offset,struct fuse_file_info *ffi)
108
- {
109
- VALUE fuse_module;
110
- VALUE rfiller_class;
111
- VALUE rfiller_instance;
112
- struct filler_t *fillerc;
113
- VALUE args[6];
114
- int error = 0;
115
-
116
- struct fuse_context *ctx=fuse_get_context();
117
- init_context_path_args(args,ctx,path);
118
-
119
- //create a filler object
120
- fuse_module = rb_const_get(rb_cObject, rb_intern("RFuse"));
121
- rfiller_class=rb_const_get(fuse_module,rb_intern("Filler"));
122
- rfiller_instance=rb_funcall(rfiller_class,rb_intern("new"),0);
123
- Data_Get_Struct(rfiller_instance,struct filler_t,fillerc);
124
-
125
- fillerc->filler=filler;
126
- fillerc->buffer=buf;
127
- args[3]=rfiller_instance;
128
- args[4]=OFFT2NUM(offset);
129
- args[5]=get_file_info(ffi);
130
-
131
- rb_protect((VALUE (*)())unsafe_readdir,(VALUE)args,&error);
132
- return error ? -(return_error(ENOENT)) : 0 ;
133
- }
134
-
135
- /*
136
- Resolve target of symbolic link
137
- @overload readlink(context,path,size)
138
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#b4ce6e6d69dfde3ec550f22d932c5633 readlink}
139
- @param [Context] context
140
- @param [String] path
141
- @param [Integer] size if the resolved path is greater than this size it should be truncated
142
-
143
- @return [String] the resolved link path
144
- @raise [Errno]
145
- */
146
- static VALUE unsafe_readlink(VALUE *args)
147
- {
148
- return rb_funcall3(args[0],rb_intern("readlink"),3,&args[1]);
149
- }
150
-
151
- static int rf_readlink(const char *path, char *buf, size_t size)
152
- {
153
- VALUE args[4];
154
- VALUE res;
155
- int error = 0;
156
- char *rbuf;
157
-
158
- struct fuse_context *ctx=fuse_get_context();
159
- init_context_path_args(args,ctx,path);
160
-
161
- args[3]=SIZET2NUM(size);
162
- res=rb_protect((VALUE (*)())unsafe_readlink,(VALUE)args,&error);
163
- if (error)
164
- {
165
- return -(return_error(ENOENT));
166
- }
167
- else
168
- {
169
- rbuf=StringValueCStr(res);
170
- strncpy(buf,rbuf,size);
171
- return 0;
172
- }
173
- }
174
-
175
- /*
176
- @deprecated see {#readdir}
177
- @abstract Fuse operation getdir
178
- */
179
- static VALUE unsafe_getdir(VALUE *args)
180
- {
181
- return rb_funcall3(args[0],rb_intern("getdir"),3,&args[1]);
182
- }
183
-
184
- //call getdir with an Filler object
185
- static int rf_getdir(const char *path, fuse_dirh_t dh, fuse_dirfil_t df)
186
- {
187
- VALUE fuse_module;
188
- VALUE rfiller_class;
189
- VALUE rfiller_instance;
190
- VALUE args[4];
191
- struct filler_t *fillerc;
192
- int error = 0;
193
-
194
- struct fuse_context *ctx=fuse_get_context();
195
- init_context_path_args(args,ctx,path);
196
-
197
- //create a filler object
198
- fuse_module = rb_const_get(rb_cObject, rb_intern("RFuse"));
199
- rfiller_class = rb_const_get(fuse_module,rb_intern("Filler"));
200
- rfiller_instance = rb_funcall(rfiller_class,rb_intern("new"),0);
201
-
202
- Data_Get_Struct(rfiller_instance,struct filler_t,fillerc);
203
-
204
- fillerc->df = df;
205
- fillerc->dh = dh;
206
-
207
- args[3]=rfiller_instance;
208
-
209
- rb_protect((VALUE (*)())unsafe_getdir, (VALUE)args, &error);
210
-
211
- return error ? -(return_error(ENOENT)) : 0 ;
212
- }
213
-
214
- /*
215
- Create a file node
216
- @overload mknod(context,path,mode,major,minor)
217
- @abstract Fuse Operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#1465eb2268cec2bb5ed11cb09bbda42f mknod}
218
-
219
- @param [Context] context
220
- @param [String] path
221
- @param [Integer] mode type & permissions
222
- @param [Integer] major
223
- @param [Integer] minor
224
-
225
- @return[void]
226
-
227
- This is called for creation of all non-directory, non-symlink nodes. If the filesystem defines {#create}, then for regular files that will be called instead.
228
-
229
- */
230
- static VALUE unsafe_mknod(VALUE *args)
231
- {
232
- return rb_funcall3(args[0],rb_intern("mknod"),5,&args[1]);
233
- }
234
-
235
- static int rf_mknod(const char *path, mode_t mode,dev_t dev)
236
- {
237
- VALUE args[6];
238
- int error = 0;
239
- struct fuse_context *ctx=fuse_get_context();
240
- int major;
241
- int minor;
242
-
243
- init_context_path_args(args,ctx,path);
244
-
245
- major = MAJOR(dev);
246
- minor = MINOR(dev);
247
-
248
- args[3]=INT2FIX(mode);
249
- args[4]=INT2FIX(major);
250
- args[5]=INT2FIX(minor);
251
- rb_protect((VALUE (*)())unsafe_mknod,(VALUE) args,&error);
252
- return error ? -(return_error(ENOENT)) : 0 ;
253
- }
254
-
255
- /*
256
- Get file attributes.
257
- @overload getattr(context,path)
258
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#7a4c5d8eaf7179d819618c0cf3f73724 getattr}
259
- @param [Context] context
260
- @param [String] path
261
-
262
- @return [Stat] or something that quacks like a stat, or nil if the path does not exist
263
- @raise [Errno]
264
-
265
- Similar to stat(). The 'st_dev' and 'st_blksize' fields are ignored. The 'st_ino' field is ignored except if the 'use_ino' mount option is given.
266
- */
267
- static VALUE unsafe_getattr(VALUE *args)
268
- {
269
- return rb_funcall3(args[0],rb_intern("getattr"),2,&args[1]);
270
- }
271
-
272
- //calls getattr with path and expects something like FuseStat back
273
- static int rf_getattr(const char *path, struct stat *stbuf)
274
- {
275
- VALUE args[3];
276
- VALUE res;
277
- int error = 0;
278
- struct fuse_context *ctx=fuse_get_context();
279
- init_context_path_args(args,ctx,path);
280
-
281
- res=rb_protect((VALUE (*)())unsafe_getattr,(VALUE) args,&error);
282
-
283
- if (error)
284
- {
285
- return -(return_error(ENOENT));
286
- }
287
-
288
- if (res == Qnil) {
289
- return -ENOENT;
290
- }
291
- else
292
- {
293
- rstat2stat(res,stbuf);
294
- return 0;
295
- }
296
- }
297
-
298
- /*
299
- Create a directory
300
-
301
- @overload mkdir(context,path,mode)
302
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#0a38aa6ca60e945772d5d21b0c1c8916 mkdir}
303
-
304
- @param [Context] context
305
- @param [String] path
306
- @param [Integer] mode to obtain correct directory permissions use mode | {Stat.S_IFDIR}
307
-
308
- @return [void]
309
- @raise [Errno]
310
-
311
- */
312
- static VALUE unsafe_mkdir(VALUE *args)
313
- {
314
- return rb_funcall3(args[0],rb_intern("mkdir"),3,&args[1]);
315
- }
316
-
317
- static int rf_mkdir(const char *path, mode_t mode)
318
- {
319
- VALUE args[4];
320
- int error = 0;
321
-
322
- struct fuse_context *ctx=fuse_get_context();
323
- init_context_path_args(args,ctx,path);
324
-
325
- args[3]=INT2FIX(mode);
326
- rb_protect((VALUE (*)())unsafe_mkdir,(VALUE) args,&error);
327
-
328
- return error ? -(return_error(ENOENT)) : 0 ;
329
- }
330
-
331
- /*
332
- File open operation
333
-
334
- @overload open(context,path,ffi)
335
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#14b98c3f7ab97cc2ef8f9b1d9dc0709d open}
336
- @param [Context] context
337
- @param [String] path
338
- @param [FileInfo] ffi
339
- file open flags etc.
340
- The fh attribute may be used to store an arbitrary filehandle object which will be passed to all subsequent operations on this file
341
-
342
- @raise [Errno::ENOPERM] if user is not permitted to open the file
343
- @raise [Errno] for other errors
344
-
345
- @return [void]
346
- */
347
- static VALUE unsafe_open(VALUE *args)
348
- {
349
- return rb_funcall3(args[0],rb_intern("open"),3,&args[1]);
350
- }
351
-
352
- static int rf_open(const char *path,struct fuse_file_info *ffi)
353
- {
354
- VALUE args[4];
355
- int error = 0;
356
-
357
- struct fuse_context *ctx=fuse_get_context();
358
- init_context_path_args(args,ctx,path);
359
-
360
- args[3]=wrap_file_info(ctx,ffi);
361
-
362
- rb_protect((VALUE (*)())unsafe_open,(VALUE) args,&error);
363
-
364
- return error ? -(return_error(ENOENT)) : 0;
365
- }
366
-
367
- //This method is registered as a default for release in the case when
368
- //open/create are defined, but a specific release method is not.
369
- //similarly for opendir/releasedir
370
- static int rf_release_ffi(const char *path, struct fuse_file_info *ffi)
371
- {
372
- struct fuse_context *ctx=fuse_get_context();
373
-
374
- release_file_info(ctx,ffi);
375
-
376
- return 0;
377
- }
378
-
379
- /*
380
- Release an open file
381
-
382
- @overload release(context,path,ffi)
383
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#bac8718cdfc1ee273a44831a27393419 release}
384
- @param [Context] context
385
- @param [String] path
386
- @param [FileInfo] ffi
387
-
388
- @return [void]
389
-
390
- Release is called when there are no more references to an open file: all file descriptors are closed and all memory mappings are unmapped.
391
-
392
- For every {#open} call there will be exactly one {#release} call with the same flags and file descriptor. It is possible to have a file opened more than once, in which case only the last release will mean, that no more reads/writes will happen on the file.
393
- */
394
- static VALUE unsafe_release(VALUE *args)
395
- {
396
- return rb_funcall3(args[0],rb_intern("release"),3,&args[1]);
397
- }
398
-
399
- static int rf_release(const char *path, struct fuse_file_info *ffi)
400
- {
401
- VALUE args[4];
402
- int error = 0;
403
-
404
- struct fuse_context *ctx=fuse_get_context();
405
- init_context_path_args(args,ctx,path);
406
-
407
- args[3]=release_file_info(ctx,ffi);
408
-
409
- rb_protect((VALUE (*)())unsafe_release,(VALUE) args,&error);
410
-
411
- return error ? -(return_error(ENOENT)) : 0;
412
- }
413
-
414
- /*
415
- Synchronize file contents
416
-
417
- @overload fsync(context,path,datasync,ffi)
418
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#92bdd6f43ba390a54ac360541c56b528 fsync}
419
-
420
- @param [Context] context
421
- @param [String] path
422
- @param [Integer] datasync if non-zero, then only user data should be flushed, not the metadata
423
- @param [FileInfo] ffi
424
-
425
- @return [void]
426
- @raise [Errno]
427
- */
428
- static VALUE unsafe_fsync(VALUE *args) {
429
- return rb_funcall3(args[0],rb_intern("fsync"),4,&args[1]);
430
- }
431
-
432
- static int rf_fsync(const char *path, int datasync, struct fuse_file_info *ffi)
433
- {
434
- VALUE args[5];
435
- int error = 0;
436
-
437
- struct fuse_context *ctx=fuse_get_context();
438
- init_context_path_args(args,ctx,path);
439
-
440
- args[3] = INT2NUM(datasync);
441
- args[4] = get_file_info(ffi);
442
-
443
- rb_protect((VALUE (*)())unsafe_fsync,(VALUE) args,&error);
444
-
445
- return error ? -(return_error(ENOENT)) : 0;
446
- }
447
-
448
-
449
-
450
- /*
451
- Possibly flush cached data
452
-
453
- @overload flush(context,path,ffi)
454
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#d4ec9c309072a92dd82ddb20efa4ab14 flush}
455
-
456
- @param [Context] context
457
- @param [String] path
458
- @param [FileInfo] ffi
459
-
460
- @return [void]
461
- @raise [Errno]
462
-
463
- BIG NOTE: This is not equivalent to fsync(). It's not a request to sync dirty data.
464
-
465
- Flush is called on each close() of a file descriptor. So if a filesystem wants to return write errors in close() and the file has cached dirty data, this is a good place to write back data and return any errors. Since many applications ignore close() errors this is not always useful.
466
-
467
- NOTE: The flush() method may be called more than once for each open(). This happens if more than one file descriptor refers to an opened file due to dup(), dup2() or fork() calls. It is not possible to determine if a flush is final, so each flush should be treated equally. Multiple write-flush sequences are relatively rare, so this shouldn't be a problem.
468
-
469
- Filesystems shouldn't assume that flush will always be called after some writes, or that if will be called at all.
470
- */
471
- static VALUE unsafe_flush(VALUE *args)
472
- {
473
- return rb_funcall3(args[0],rb_intern("flush"),3,&args[1]);
474
- }
475
-
476
- static int rf_flush(const char *path,struct fuse_file_info *ffi)
477
- {
478
- VALUE args[4];
479
- int error = 0;
480
- struct fuse_context *ctx=fuse_get_context();
481
- init_context_path_args(args,ctx,path);
482
- args[3]=get_file_info(ffi);
483
- rb_protect((VALUE (*)())unsafe_flush,(VALUE) args,&error);
484
-
485
- return error ? -(return_error(ENOENT)) : 0;
486
- }
487
-
488
- /*
489
- Change the size of a file
490
-
491
- @overload truncate(context,path,offset)
492
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#8efb50b9cd975ba8c4c450248caff6ed truncate}
493
-
494
- @param [Context] context
495
- @param [String] path
496
- @param [Integer] offset
497
-
498
- @return [void]
499
- @raise [Errno]
500
- */
501
- static VALUE unsafe_truncate(VALUE *args)
502
- {
503
- return rb_funcall3(args[0],rb_intern("truncate"),3,&args[1]);
504
- }
505
-
506
- static int rf_truncate(const char *path,off_t offset)
507
- {
508
- VALUE args[4];
509
- int error = 0;
510
- struct fuse_context *ctx=fuse_get_context();
511
- init_context_path_args(args,ctx,path);
512
- args[3]=INT2FIX(offset);
513
- rb_protect((VALUE (*)())unsafe_truncate,(VALUE) args,&error);
514
-
515
- return error ? -(return_error(ENOENT)) : 0;
516
- }
517
-
518
-
519
- /*
520
- Change access/modification times of a file
521
-
522
- @overload utime(context,path,actime,modtime)
523
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#cb7452acad1002d418409892b6e54c2e utime}
524
- @deprecated See {#utimens}
525
-
526
- @param [Context] context
527
- @param [String] path
528
- @param [Integer] actime access time
529
- @param [Integer] modtime modification time
530
-
531
- @return [void]
532
- @raise [Errno]
533
- */
534
- static VALUE unsafe_utime(VALUE *args)
535
- {
536
- return rb_funcall3(args[0],rb_intern("utime"),4,&args[1]);
537
- }
538
-
539
- static int rf_utime(const char *path,struct utimbuf *utim)
540
- {
541
- VALUE args[5];
542
- int error = 0;
543
-
544
- struct fuse_context *ctx=fuse_get_context();
545
- init_context_path_args(args,ctx,path);
546
-
547
- args[3]=INT2NUM(utim->actime);
548
- args[4]=INT2NUM(utim->modtime);
549
- rb_protect((VALUE (*)())unsafe_utime,(VALUE) args,&error);
550
-
551
- return error ? -(return_error(ENOENT)) : 0;
552
- }
553
-
554
- /*
555
- Change file ownership
556
-
557
- @overload chown(context,path,uid,gid)
558
-
559
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#40421f8a43e903582c49897894f4692d chown}
560
-
561
- @param [Context] context
562
- @param [String] path
563
- @param [Integer] uid new user id
564
- @param [Integer] gid new group id
565
-
566
- @return [void]
567
- @raise [Errno]
568
- */
569
- static VALUE unsafe_chown(VALUE *args)
570
- {
571
- return rb_funcall3(args[0],rb_intern("chown"),4,&args[1]);
572
- }
573
-
574
- static int rf_chown(const char *path,uid_t uid,gid_t gid)
575
- {
576
- VALUE args[5];
577
- int error = 0;
578
- struct fuse_context *ctx=fuse_get_context();
579
- init_context_path_args(args,ctx,path);
580
- args[3]=INT2FIX(uid);
581
- args[4]=INT2FIX(gid);
582
- rb_protect((VALUE (*)())unsafe_chown,(VALUE) args,&error);
583
-
584
- return error ? -(return_error(ENOENT)) : 0;
585
- }
586
-
587
- /*
588
- Change file permissions
589
-
590
- @overload chmod(context,path,mode)
591
-
592
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#7e75d299efe3a401e8473af7028e5cc5 chmod}
593
-
594
- @param [Context] context
595
- @param [String] path
596
- @param [Integer] mode
597
-
598
- @return [void]
599
- @raise [Errno]
600
- */
601
- static VALUE unsafe_chmod(VALUE *args)
602
- {
603
- return rb_funcall3(args[0],rb_intern("chmod"),3,&args[1]);
604
- }
605
-
606
- static int rf_chmod(const char *path,mode_t mode)
607
- {
608
- VALUE args[4];
609
- int error = 0;
610
- struct fuse_context *ctx=fuse_get_context();
611
- init_context_path_args(args,ctx,path);
612
- args[3]=INT2FIX(mode);
613
- rb_protect((VALUE (*)())unsafe_chmod,(VALUE) args,&error);
614
-
615
- return error ? -(return_error(ENOENT)) : 0;
616
- }
617
-
618
- /*
619
- Remove a file
620
-
621
- @overload unlink(context,path)
622
-
623
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#8bf63301a9d6e94311fa10480993801e unlink}
624
-
625
- @param [Context] context
626
- @param [String] path
627
-
628
- @return [void]
629
- @raise [Errno]
630
- */
631
- static VALUE unsafe_unlink(VALUE *args)
632
- {
633
- return rb_funcall3(args[0],rb_intern("unlink"),2,&args[1]);
634
- }
635
-
636
- static int rf_unlink(const char *path)
637
- {
638
- VALUE args[3];
639
- int error = 0;
640
- struct fuse_context *ctx=fuse_get_context();
641
- init_context_path_args(args,ctx,path);
642
- rb_protect((VALUE (*)())unsafe_unlink,(VALUE) args,&error);
643
-
644
- return error ? -(return_error(ENOENT)) : 0;
645
- }
646
-
647
- /*
648
- Remove a directory
649
-
650
- @overload rmdir(context,path)
651
-
652
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#c59578d18db12f0142ae1ab6e8812d55 rmdir}
653
-
654
- @param [Context] context
655
- @param [String] path
656
-
657
- @return [void]
658
- @raise [Errno]
659
- */
660
- static VALUE unsafe_rmdir(VALUE *args)
661
- {
662
- return rb_funcall3(args[0],rb_intern("rmdir"),2,&args[1]);
663
- }
664
-
665
- static int rf_rmdir(const char *path)
666
- {
667
- VALUE args[3];
668
- int error = 0;
669
- struct fuse_context *ctx=fuse_get_context();
670
- init_context_path_args(args,ctx,path);
671
- rb_protect((VALUE (*)())unsafe_rmdir, (VALUE) args ,&error);
672
-
673
- return error ? -(return_error(ENOENT)) : 0;
674
- }
675
-
676
- /*
677
- Create a symbolic link
678
-
679
- @overload symlink(context,to,from)
680
-
681
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#b86022391e56a8ad3211cf754b5b5ebe symlink}
682
-
683
- @param [Context] context
684
- @param [String] to
685
- @param [String] from
686
-
687
- @return [void]
688
- @raise [Errno]
689
-
690
- Create a symbolic link named "from" which, when evaluated, will lead to "to".
691
- */
692
- static VALUE unsafe_symlink(VALUE *args){
693
- return rb_funcall3(args[0],rb_intern("symlink"),3,&args[1]);
694
- }
695
-
696
- static int rf_symlink(const char *path,const char *as)
697
- {
698
- VALUE args[4];
699
- int error = 0;
700
- struct fuse_context *ctx=fuse_get_context();
701
- init_context_path_args(args,ctx,path);
702
-
703
- args[3]=rb_str_new2(as);
704
- rb_filesystem_encode(args[3]);
705
-
706
- rb_protect((VALUE (*)())unsafe_symlink,(VALUE) args,&error);
707
-
708
- return error ? -(return_error(ENOENT)) : 0;
709
- }
710
-
711
- /*
712
- @overload rename(context,from,to)
713
-
714
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#a777cbddc91887b117ac414e9a2d3cb5 rename}
715
-
716
- @param [Context] context
717
- @param [String] from
718
- @param [String] to
719
-
720
- @return [void]
721
- @raise [Errno]
722
-
723
- Rename the file, directory, or other object "from" to the target "to". Note that the source and target don't have to be in the same directory, so it may be necessary to move the source to an entirely new directory. See rename(2) for full details.
724
- */
725
- static VALUE unsafe_rename(VALUE *args)
726
- {
727
- return rb_funcall3(args[0],rb_intern("rename"),3,&args[1]);
728
- }
729
-
730
- static int rf_rename(const char *path,const char *as)
731
- {
732
- VALUE args[4];
733
- int error = 0;
734
- struct fuse_context *ctx=fuse_get_context();
735
- init_context_path_args(args,ctx,path);
736
-
737
- args[3]=rb_str_new2(as);
738
- rb_filesystem_encode(args[3]);
739
-
740
- rb_protect((VALUE (*)())unsafe_rename,(VALUE) args,&error);
741
-
742
- return error ? -(return_error(ENOENT)) : 0;
743
- }
744
-
745
-
746
- /*
747
- Create a hard link to file
748
- @overload link(context,from,to)
749
-
750
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#1b234c43e826c6a690d80ea895a17f61 link}
751
-
752
- @param [Context] context
753
- @param [String] from
754
- @param [String] to
755
-
756
- @return [void]
757
- @raise [Errno]
758
- */
759
- static VALUE unsafe_link(VALUE *args)
760
- {
761
- return rb_funcall3(args[0],rb_intern("link"),3,&args[1]);
762
- }
763
-
764
- static int rf_link(const char *path,const char * as)
765
- {
766
- VALUE args[4];
767
- int error = 0;
768
- struct fuse_context *ctx=fuse_get_context();
769
- init_context_path_args(args,ctx,path);
770
- args[3]=rb_str_new2(as);
771
- rb_filesystem_encode(args[3]);
772
- rb_protect((VALUE (*)())unsafe_link,(VALUE) args,&error);
773
-
774
- return error ? -(return_error(ENOENT)) : 0;
775
- }
776
-
777
-
778
- /*
779
- Read data from an open file
780
-
781
- @overload read(context,path,size,offset,ffi)
782
-
783
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#2a1c6b4ce1845de56863f8b7939501b5 read}
784
-
785
- @param [Context] context
786
- @param [String] path
787
- @param [Integer] size
788
- @param [Integer] offset
789
- @param [FileInfo] ffi
790
-
791
- @return [String] should be exactly the number of bytes requested, or empty string on EOF
792
- @raise [Errno]
793
- */
794
- static VALUE unsafe_read(VALUE *args)
795
- {
796
- VALUE res;
797
-
798
- res = rb_funcall3(args[0],rb_intern("read"),5,&args[1]);
799
- //TODO If res does not implement to_str then you'll get an exception here that
800
- //is hard to debug
801
- return StringValue(res);
802
- }
803
-
804
-
805
- long rb_strcpy(VALUE str, char *buf, size_t size)
806
- {
807
- long length;
808
-
809
- length = RSTRING_LEN(str);
810
- if (length <= (long) size)
811
- {
812
- memcpy(buf,RSTRING_PTR(str),length);
813
- }
814
-
815
- return length;
816
- }
817
-
818
- static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct fuse_file_info *ffi)
819
- {
820
- VALUE args[6];
821
- VALUE res;
822
- int error = 0;
823
- long length=0;
824
-
825
- struct fuse_context *ctx=fuse_get_context();
826
- init_context_path_args(args,ctx,path);
827
-
828
- args[3]=SIZET2NUM(size);
829
- args[4]=OFFT2NUM(offset);
830
- args[5]=get_file_info(ffi);
831
-
832
- res=rb_protect((VALUE (*)())unsafe_read,(VALUE) args,&error);
833
-
834
- if (error)
835
- {
836
- return -(return_error(ENOENT));
837
- }
838
- else
839
- {
840
-
841
- length = rb_strcpy(res,buf,size);
842
-
843
- if (length <= (long) size) {
844
- return length;
845
- } else {
846
- //This cannot happen => IO error.
847
- return -(return_error(ENOENT));
848
- }
849
-
850
- }
851
- }
852
-
853
-
854
- /*
855
- Write data to an open file
856
-
857
- @overload write(context,path,data,offset,ffi)
858
-
859
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#897d1ece4b8b04c92d97b97b2dbf9768 write}
860
-
861
- @param [Context] context
862
- @param [String] path
863
- @param [String] data
864
- @param [Integer] offset
865
- @param [FileInfo] ffi
866
-
867
- @return [Integer] exactly the number of bytes requested except on error
868
- @raise [Errno]
869
- */
870
- static VALUE unsafe_write(VALUE *args)
871
- {
872
- return rb_funcall3(args[0],rb_intern("write"),5,&args[1]);
873
- }
874
-
875
- static int rf_write(const char *path,const char *buf,size_t size,
876
- off_t offset,struct fuse_file_info *ffi)
877
- {
878
- VALUE args[6];
879
- VALUE res;
880
- int error = 0;
881
- struct fuse_context *ctx=fuse_get_context();
882
- init_context_path_args(args,ctx,path);
883
-
884
- args[3]=rb_str_new(buf, size);
885
- args[4]=OFFT2NUM(offset);
886
- args[5]=get_file_info(ffi);
887
-
888
- res = rb_protect((VALUE (*)())unsafe_write,(VALUE) args, &error);
889
-
890
- if (error)
891
- {
892
- return -(return_error(ENOENT));
893
- }
894
- else
895
- {
896
- return NUM2INT(res);
897
- }
898
- }
899
-
900
- /*
901
- Get file system statistics
902
-
903
- @overload statfs(context,path)
904
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#4e765e29122e7b6b533dc99849a52655 statfs}
905
- @param [Context] context
906
- @param [String] path
907
-
908
- @return [StatVfs] or something that quacks like a statVfs
909
- @raise [Errno]
910
-
911
- The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
912
-
913
- */
914
- static VALUE unsafe_statfs(VALUE *args)
915
- {
916
- return rb_funcall3(args[0],rb_intern("statfs"),2,&args[1]);
917
- }
918
-
919
- static int rf_statfs(const char * path, struct statvfs * vfsinfo)
920
- {
921
- VALUE args[3];
922
- VALUE res;
923
- int error = 0;
924
-
925
- struct fuse_context *ctx=fuse_get_context();
926
- init_context_path_args(args,ctx,path);
927
-
928
- res = rb_protect((VALUE (*)())unsafe_statfs,(VALUE) args,&error);
929
-
930
- if (error || (res == Qnil))
931
- {
932
- return -(return_error(ENOENT));
933
- }
934
- else
935
- {
936
- rstatvfs2statvfs(res,vfsinfo);
937
- return 0;
938
- }
939
- }
940
-
941
-
942
- /*
943
- Set extended attributes
944
-
945
- @overload setxattr(context,path,name,data,flags)
946
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#988ced7091c2821daa208e6c96d8b598 setxattr}
947
- @param [Context] context
948
- @param [String] path
949
- @param [String] name
950
- @param [String] data
951
- @param [Integer] flags
952
-
953
- @return [void]
954
- @raise [Errno]
955
-
956
- */
957
- static VALUE unsafe_setxattr(VALUE *args)
958
- {
959
- return rb_funcall3(args[0],rb_intern("setxattr"),5,&args[1]);
960
- }
961
-
962
- static int rf_setxattr(const char *path,const char *name,
963
- const char *value, size_t size, int flags)
964
- {
965
- VALUE args[6];
966
- int error = 0;
967
-
968
- struct fuse_context *ctx=fuse_get_context();
969
- init_context_path_args(args,ctx,path);
970
-
971
- args[3]=rb_str_new2(name);
972
- args[4]=rb_str_new(value,size);
973
- args[5]=INT2NUM(flags);
974
-
975
- rb_protect((VALUE (*)())unsafe_setxattr,(VALUE) args,&error);
976
-
977
- return error ? -(return_error(ENOENT)) : 0;
978
- }
979
-
980
-
981
- /*
982
- Get extended attribute
983
-
984
- @overload getxattr(context,path,name)
985
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#e21503c64fe2990c8a599f5ba339a8f2 getxattr}
986
- @param [Context] context
987
- @param [String] path
988
- @param [String] name
989
-
990
- @return [String] attribute value
991
- @raise [Errno] Errno::ENOATTR if attribute does not exist
992
-
993
- */
994
- static VALUE unsafe_getxattr(VALUE *args)
995
- {
996
- VALUE res;
997
- res = rb_funcall3(args[0],rb_intern("getxattr"),3,&args[1]);
998
- //TODO - exception won't should that we're calling getxattr
999
- return StringValue(res);
1000
- }
1001
-
1002
- static int rf_getxattr(const char *path,const char *name,char *buf,
1003
- size_t size)
1004
- {
1005
- VALUE args[4];
1006
- VALUE res;
1007
- int error = 0;
1008
- long length;
1009
-
1010
- struct fuse_context *ctx=fuse_get_context();
1011
- init_context_path_args(args,ctx,path);
1012
-
1013
- args[3]=rb_str_new2(name);
1014
- res=rb_protect((VALUE (*)())unsafe_getxattr,(VALUE) args,&error);
1015
-
1016
- if (error)
1017
- {
1018
- return -(return_error(ENOENT));
1019
- }
1020
- else
1021
- {
1022
- length = rb_strcpy(res,buf,size);
1023
- if (buf != NULL && length > ((long) size))
1024
- {
1025
- return -ERANGE;
1026
- }
1027
- return length;
1028
- }
1029
- }
1030
-
1031
- /*
1032
- List extended attributes
1033
-
1034
- @overload listxattr(context,path)
1035
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#b4a9c361ce48406f07d5a08ab03f5de8 listxattr}
1036
- @param [Context] context
1037
- @param [String] path
1038
-
1039
- @return [Array<String>] list of attribute names
1040
- @raise [Errno]
1041
- */
1042
- static VALUE unsafe_listxattr(VALUE *args)
1043
- {
1044
- VALUE res;
1045
- res = rb_funcall3(args[0],rb_intern("listxattr"),2,&args[1]);
1046
-
1047
- //We'll let Ruby do the hard work of creating a String
1048
- //separated by NULLs
1049
- return rb_funcall(mRFuse,rb_intern("packxattr"),1,res);
1050
- }
1051
-
1052
- static int rf_listxattr(const char *path,char *buf, size_t size)
1053
- {
1054
- VALUE args[3];
1055
- VALUE res;
1056
- int error = 0;
1057
- long length;
1058
-
1059
- struct fuse_context *ctx=fuse_get_context();
1060
- init_context_path_args(args,ctx,path);
1061
-
1062
- res=rb_protect((VALUE (*)())unsafe_listxattr,(VALUE) args,&error);
1063
-
1064
- if (error)
1065
- {
1066
- return -(return_error(ENOENT));
1067
- }
1068
- else
1069
- {
1070
- length = rb_strcpy(res,buf,size);
1071
- if (buf != NULL && length > (long) size)
1072
- {
1073
- return -ERANGE;
1074
- }
1075
- return length;
1076
- }
1077
- }
1078
-
1079
-
1080
- /*
1081
- Remove extended attribute
1082
-
1083
- @overload removexattr(context,path,name)
1084
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#5e54de801a0e0d7019e4579112ecc477 removexattr}
1085
- @param [Context] context
1086
- @param [String] path
1087
- @param [String] name attribute to remove
1088
-
1089
- @return [void]
1090
- @raise [Errno]
1091
- */
1092
- static VALUE unsafe_removexattr(VALUE *args)
1093
- {
1094
- return rb_funcall3(args[0],rb_intern("removexattr"),3,&args[1]);
1095
- }
1096
-
1097
- static int rf_removexattr(const char *path,const char *name)
1098
- {
1099
- VALUE args[4];
1100
- int error = 0;
1101
- struct fuse_context *ctx=fuse_get_context();
1102
- init_context_path_args(args,ctx,path);
1103
- args[3]=rb_str_new2(name);
1104
- rb_protect((VALUE (*)())unsafe_removexattr,(VALUE) args,&error);
1105
-
1106
- return error ? -(return_error(ENOENT)) : 0 ;
1107
- }
1108
-
1109
-
1110
- /*
1111
- Open directory
1112
-
1113
- @overload opendir(context,path,name)
1114
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#1813889bc5e6e0087a936b7abe8b923f opendir}
1115
- @param [Context] context
1116
- @param [String] path
1117
- @param [FileInfo] ffi
1118
-
1119
- @return [void]
1120
- @raise [Errno]
1121
-
1122
-
1123
- Unless the 'default_permissions' mount option is given, this method should check if opendir is permitted for this directory. Optionally opendir may also return an arbitrary filehandle in the fuse_file_info structure, which will be available to {#readdir}, {#fsyncdir}, {#releasedir}.
1124
-
1125
- */
1126
- static VALUE unsafe_opendir(VALUE *args)
1127
- {
1128
- return rb_funcall3(args[0],rb_intern("opendir"),3,&args[1]);
1129
- }
1130
-
1131
- static int rf_opendir(const char *path,struct fuse_file_info *ffi)
1132
- {
1133
- VALUE args[4];
1134
- int error = 0;
1135
- struct fuse_context *ctx=fuse_get_context();
1136
- init_context_path_args(args,ctx,path);
1137
-
1138
- args[3]=wrap_file_info(ctx,ffi);
1139
-
1140
- rb_protect((VALUE (*)())unsafe_opendir,(VALUE) args,&error);
1141
-
1142
- return error ? -(return_error(ENOENT)) : 0 ;
1143
- }
1144
-
1145
- /*
1146
- Release directory
1147
-
1148
- @overload releasedir(context,path,ffi)
1149
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#729e53d36acc05a7a8985a1a3bbfac1e releasedir}
1150
- @param [Context] context
1151
- @param [String] path
1152
- @param [FileInfo] ffi
1153
-
1154
- @return [void]
1155
- @raise [Errno]
1156
- */
1157
- static VALUE unsafe_releasedir(VALUE *args)
1158
- {
1159
- return rb_funcall3(args[0],rb_intern("releasedir"),3,&args[1]);
1160
- }
1161
-
1162
- static int rf_releasedir(const char *path,struct fuse_file_info *ffi)
1163
- {
1164
- VALUE args[4];
1165
- int error = 0;
1166
-
1167
- struct fuse_context *ctx=fuse_get_context();
1168
- init_context_path_args(args,ctx,path);
1169
- args[3]=release_file_info(ctx,ffi);
1170
-
1171
- rb_protect((VALUE (*)())unsafe_releasedir,(VALUE) args,&error);
1172
-
1173
- return error ? -(return_error(ENOENT)) : 0 ;
1174
- }
1175
-
1176
-
1177
- /*
1178
- Sync directory
1179
-
1180
- @overload fsyncdir(context,path,datasync,ffi)
1181
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#ba5cc1fe9a63ec152ceb19656f243256 fsyncdir}
1182
- @param [Context] context
1183
- @param [String] path
1184
- @param [Integer] datasync if nonzero sync only data, not metadata
1185
- @param [FileInfo] ffi
1186
-
1187
- @return [void]
1188
- @raise [Errno]
1189
-
1190
- */
1191
- static VALUE unsafe_fsyncdir(VALUE *args)
1192
- {
1193
- return rb_funcall2(args[0],rb_intern("fsyncdir"),4,&args[1]);
1194
- }
1195
-
1196
- static int rf_fsyncdir(const char *path,int meta,struct fuse_file_info *ffi)
1197
- {
1198
- VALUE args[5];
1199
- int error = 0;
1200
- struct fuse_context *ctx=fuse_get_context();
1201
- init_context_path_args(args,ctx,path);
1202
- args[3]=INT2NUM(meta);
1203
- args[4]=get_file_info(ffi);
1204
- rb_protect((VALUE (*)())unsafe_fsyncdir,(VALUE) args,&error);
1205
-
1206
- return error ? -(return_error(ENOENT)) : 0 ;
1207
- }
1208
-
1209
- /*
1210
- Called when filesystem is initialised
1211
-
1212
- @overload init(info)
1213
- @abstract Fuse Operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#dc6dc71274f185de72217e38d62142c4 init}
1214
-
1215
- @param [Context] context
1216
- @param [Struct] info connection information
1217
-
1218
- @return [void]
1219
- */
1220
- static VALUE unsafe_init(VALUE* args)
1221
- {
1222
- return rb_funcall3(args[0],rb_intern("init"),2,&args[1]);
1223
- }
1224
-
1225
- static void *rf_init(struct fuse_conn_info *conn)
1226
- {
1227
- VALUE args[3];
1228
- int error = 0;
1229
- struct fuse_context *ctx;
1230
-
1231
- VALUE self, s, fci, fcio;
1232
-
1233
- ctx = fuse_get_context();
1234
-
1235
- self = (VALUE) ctx->private_data;
1236
-
1237
- args[0] = self;
1238
- args[1] = wrap_context(ctx);
1239
-
1240
- //Create a struct for the conn_info
1241
- //TODO - some of these are writable!
1242
- s = rb_const_get(rb_cObject,rb_intern("Struct"));
1243
- fci = rb_funcall(s,rb_intern("new"),7,
1244
- ID2SYM(rb_intern("proto_major")),
1245
- ID2SYM(rb_intern("proto_minor")),
1246
- ID2SYM(rb_intern("async_read")),
1247
- ID2SYM(rb_intern("max_write")),
1248
- ID2SYM(rb_intern("max_readahead")),
1249
- ID2SYM(rb_intern("capable")),
1250
- ID2SYM(rb_intern("want"))
1251
- );
1252
-
1253
- fcio = rb_funcall(fci,rb_intern("new"),7,
1254
- UINT2NUM(conn->proto_major),
1255
- UINT2NUM(conn->proto_minor),
1256
- UINT2NUM(conn->async_read),
1257
- UINT2NUM(conn->max_write),
1258
- UINT2NUM(conn->max_readahead),
1259
- UINT2NUM(conn->capable),
1260
- UINT2NUM(conn->want)
1261
- );
1262
-
1263
- args[2] = fcio;
1264
-
1265
- rb_protect((VALUE (*)())unsafe_init,(VALUE) args,&error);
1266
-
1267
- //This previously was the result of the init call (res)
1268
- //but it was never made available to any of the file operations
1269
- //and nothing was done to prevent it from being GC'd so
1270
- //filesystems would need to have stored it separately anyway
1271
- return error ? NULL : (void *) self;
1272
- }
1273
-
1274
- /*
1275
- Check access permissions
1276
-
1277
- @overload access(context,path,mode)
1278
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#2248db35e200265f7fb9a18348229858 access}
1279
- @param [Context] context
1280
- @param [String] path
1281
- @param [Integer] mode the permissions to check
1282
-
1283
- @return [void]
1284
- @raise [Errno::EACCESS] if the requested permission isn't available
1285
-
1286
- */
1287
- static VALUE unsafe_access(VALUE* args)
1288
- {
1289
- return rb_funcall3(args[0],rb_intern("access"),3,&args[1]);
1290
- }
1291
-
1292
- static int rf_access(const char *path, int mask)
1293
- {
1294
- VALUE args[4];
1295
- int error = 0;
1296
- struct fuse_context *ctx=fuse_get_context();
1297
- init_context_path_args(args,ctx,path);
1298
- args[3] = INT2NUM(mask);
1299
- rb_protect((VALUE (*)())unsafe_access,(VALUE) args,&error);
1300
-
1301
- return error ? -(return_error(ENOENT)) : 0 ;
1302
- }
1303
-
1304
-
1305
- /*
1306
- Create and open a file
1307
-
1308
- @overload create(context,path,mode,ffi)
1309
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#97243e0f9268a96236bc3b6f2bacee17 create}
1310
- @param [Context] context
1311
- @param [String] path
1312
- @param [Integer] mode the file permissions to create
1313
- @param [Fileinfo] ffi - use the {FileInfo#fh} attribute to store a filehandle
1314
-
1315
- @return [void]
1316
- @raise [Errno]
1317
-
1318
- If the file does not exist, first create it with the specified mode, and then open it.
1319
-
1320
- */
1321
- static VALUE unsafe_create(VALUE* args)
1322
- {
1323
- return rb_funcall3(args[0],rb_intern("create"),4,&args[1]);
1324
- }
1325
-
1326
- static int rf_create(const char *path, mode_t mode, struct fuse_file_info *ffi)
1327
- {
1328
- VALUE args[5];
1329
- int error = 0;
1330
-
1331
- struct fuse_context *ctx = fuse_get_context();
1332
- init_context_path_args(args,ctx,path);
1333
- args[3] = INT2NUM(mode);
1334
- args[4] = wrap_file_info(ctx,ffi);
1335
-
1336
- rb_protect((VALUE (*)())unsafe_create,(VALUE) args,&error);
1337
-
1338
- return error ? -(return_error(ENOENT)) : 0 ;
1339
-
1340
- }
1341
-
1342
-
1343
- /*
1344
- Change the size of an open file
1345
-
1346
- @overload ftruncate(context,path,size,ffi)
1347
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#1e492882859740f13cbf3344cf963c70 ftruncate}
1348
- @param [Context] context
1349
- @param [String] path
1350
- @param [Integer] size
1351
- @param [Fileinfo] ffi
1352
-
1353
- @return [void]
1354
- @raise [Errno]
1355
-
1356
- */
1357
- static VALUE unsafe_ftruncate(VALUE* args)
1358
- {
1359
- return rb_funcall3(args[0],rb_intern("ftruncate"),4,&args[1]);
1360
- }
1361
-
1362
- static int rf_ftruncate(const char *path, off_t size,
1363
- struct fuse_file_info *ffi)
1364
- {
1365
- VALUE args[5];
1366
- int error = 0;
1367
-
1368
- struct fuse_context *ctx = fuse_get_context();
1369
- init_context_path_args(args,ctx,path);
1370
- args[3] = OFFT2NUM(size);
1371
- args[4] = get_file_info(ffi);
1372
-
1373
- rb_protect((VALUE (*)())unsafe_ftruncate,(VALUE) args,&error);
1374
-
1375
- return error ? -(return_error(ENOENT)) : 0 ;
1376
- }
1377
-
1378
-
1379
- /*
1380
- Get attributes of an open file
1381
-
1382
- @overload fgetattr(context,path,ffi)
1383
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#573d79862df591c98e1685225a4cd3a5 fgetattr}
1384
- @param [Context] context
1385
- @param [String] path
1386
- @param [Fileinfo] ffi
1387
-
1388
- @return [Stat] file attributes
1389
- @raise [Errno]
1390
-
1391
- */
1392
- static VALUE unsafe_fgetattr(VALUE *args)
1393
- {
1394
- return rb_funcall3(args[0],rb_intern("fgetattr"),3,&args[1]);
1395
- }
1396
-
1397
- static int rf_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *ffi)
1398
- {
1399
- VALUE args[4];
1400
- VALUE res;
1401
- int error = 0;
1402
-
1403
- struct fuse_context *ctx = fuse_get_context();
1404
- init_context_path_args(args,ctx,path);
1405
- args[3] = get_file_info(ffi);
1406
-
1407
- res=rb_protect((VALUE (*)())unsafe_fgetattr,(VALUE) args,&error);
1408
-
1409
- if (error || (res == Qnil))
1410
- {
1411
- return -(return_error(ENOENT));
1412
- }
1413
- else
1414
- {
1415
- rstat2stat(res,stbuf);
1416
- return 0;
1417
- }
1418
- }
1419
-
1420
- /*
1421
- Perform POSIX file locking operation
1422
-
1423
- @overload lock(context,path,ffi,cmd,flock)
1424
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#1c3fff5cf0c1c2003d117e764b9a76fd lock}
1425
- @param [Context] context
1426
- @param [String] path
1427
- @param [Fileinfo] ffi
1428
- @param [Integer] cmd
1429
- @param [Struct] flock
1430
-
1431
- @return [void]
1432
- @raise [Errno]
1433
- @todo Some of the attributes of the flock struct should be writable
1434
-
1435
- The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
1436
-
1437
- For the meaning of fields in 'struct flock' see the man page for fcntl(2). The l_whence field will always be set to SEEK_SET.
1438
-
1439
- For checking lock ownership, the FileInfo#owner argument must be used. (NOT YET IMPLEMENTED)
1440
-
1441
- For F_GETLK operation, the library will first check currently held locks, and if a conflicting lock is found it will return information without calling this method. This ensures, that for local locks the l_pid field is correctly filled in. The results may not be accurate in case of race conditions and in the presence of hard links, but it's unlikly that an application would rely on accurate GETLK results in these cases. If a conflicting lock is not found, this method will be called, and the filesystem may fill out l_pid by a meaningful value, or it may leave this field zero.
1442
-
1443
- For F_SETLK and F_SETLKW the l_pid field will be set to the pid of the process performing the locking operation.
1444
-
1445
- Note: if this method is not implemented, the kernel will still allow file locking to work locally. Hence it is only interesting for network filesystems and similar.
1446
- */
1447
- static VALUE unsafe_lock(VALUE *args)
1448
- {
1449
- return rb_funcall3(args[0],rb_intern("lock"),5,&args[1]);
1450
- }
1451
-
1452
- static int rf_lock(const char *path, struct fuse_file_info *ffi,
1453
- int cmd, struct flock *lock)
1454
- {
1455
- VALUE args[6];
1456
- int error = 0;
1457
-
1458
- VALUE cStruct;
1459
- VALUE lockc;
1460
- VALUE locko;
1461
-
1462
- struct fuse_context *ctx = fuse_get_context();
1463
- init_context_path_args(args,ctx,path);
1464
-
1465
-
1466
- //Create a struct for the lock structure
1467
- cStruct = rb_const_get(rb_cObject,rb_intern("Struct"));
1468
- lockc = rb_funcall(cStruct,rb_intern("new"),5,
1469
- ID2SYM(rb_intern("l_type")),
1470
- ID2SYM(rb_intern("l_whence")),
1471
- ID2SYM(rb_intern("l_start")),
1472
- ID2SYM(rb_intern("l_len")),
1473
- ID2SYM(rb_intern("l_pid"))
1474
- );
1475
-
1476
- locko = rb_funcall(lockc,rb_intern("new"),5,
1477
- UINT2NUM(lock->l_type),
1478
- UINT2NUM(lock->l_whence),
1479
- UINT2NUM(lock->l_start),
1480
- UINT2NUM(lock->l_len),
1481
- UINT2NUM(lock->l_pid)
1482
- );
1483
-
1484
- args[3] = get_file_info(ffi);
1485
- args[4] = INT2NUM(cmd);
1486
- args[5] = locko;
1487
-
1488
- rb_protect((VALUE (*)())unsafe_lock,(VALUE) args,&error);
1489
-
1490
- return error ? -(return_error(ENOENT)) : 0 ;
1491
- }
1492
-
1493
-
1494
- /*
1495
- Change access/modification times of a file
1496
-
1497
- @overload utimens(context,path,actime,modtime)
1498
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#79955861cc5eb006954476607ef28944 utimens}
1499
-
1500
- @param [Context] context
1501
- @param [String] path
1502
- @param [Integer] actime access time in nanoseconds
1503
- @param [Integer] modtime modification time in nanoseconds
1504
-
1505
- @return [void]
1506
- @raise [Errno]
1507
- */
1508
- static VALUE unsafe_utimens(VALUE *args)
1509
- {
1510
- return rb_funcall3(args[0],rb_intern("utimens"),4,&args[1]);
1511
- }
1512
-
1513
- static int rf_utimens(const char * path, const struct timespec tv[2])
1514
- {
1515
- VALUE args[5];
1516
- int error = 0;
1517
-
1518
- struct fuse_context *ctx = fuse_get_context();
1519
- init_context_path_args(args,ctx,path);
1520
-
1521
- // tv_sec * 1000000000 + tv_nsec
1522
- args[3] = rb_funcall(
1523
- rb_funcall(
1524
- INT2NUM(tv[0].tv_sec), rb_intern("*"), 1, INT2NUM(1000000000)
1525
- ),
1526
- rb_intern("+"), 1, INT2NUM(tv[0].tv_nsec)
1527
- );
1528
-
1529
- args[4] = rb_funcall(
1530
- rb_funcall(
1531
- INT2NUM(tv[1].tv_sec), rb_intern("*"), 1, INT2NUM(1000000000)
1532
- ),
1533
- rb_intern("+"), 1, INT2NUM(tv[1].tv_nsec)
1534
- );
1535
-
1536
- rb_protect((VALUE (*)())unsafe_utimens,(VALUE) args, &error);
1537
- return error ? -(return_error(ENOENT)) : 0 ;
1538
- }
1539
-
1540
- /*
1541
- Map block index within file to block index within device
1542
-
1543
- @overload bmap(context,path,blocksize,index)
1544
- @abstract Fuse operation {http://fuse.sourceforge.net/doxygen/structfuse__operations.html#e3f3482e33a0eada0292350d76b82901 bmap}
1545
-
1546
- @param [Context] context
1547
- @param [String] path
1548
- @param [Integer] blocksize
1549
- @param [Integer] index
1550
-
1551
- @return [Integer] device relative block index
1552
- @raise [Errno]
1553
-
1554
-
1555
- Note: This makes sense only for block device backed filesystems mounted with the 'blkdev' option
1556
- */
1557
- static VALUE unsafe_bmap(VALUE *args)
1558
- {
1559
- return rb_funcall3(args[0],rb_intern("bmap"),4,&args[1]);
1560
- }
1561
-
1562
- static int rf_bmap(const char *path, size_t blocksize, uint64_t *idx)
1563
- {
1564
- VALUE args[5];
1565
- VALUE res;
1566
- int error = 0;
1567
-
1568
- struct fuse_context *ctx = fuse_get_context();
1569
- init_context_path_args(args,ctx,path);
1570
- args[3] = SIZET2NUM(blocksize);
1571
- args[4] = LL2NUM(*idx);
1572
-
1573
- res = rb_protect((VALUE (*)())unsafe_bmap,(VALUE) args, &error);
1574
-
1575
- if (error)
1576
- {
1577
- return -(return_error(ENOENT));
1578
- }
1579
- else
1580
- {
1581
- *idx = NUM2LL(res);
1582
- return 0;
1583
- }
1584
- }
1585
-
1586
- //----------------------IOCTL
1587
- #ifdef RFUSE_BROKEN
1588
- static VALUE unsafe_ioctl(VALUE *args)
1589
- {
1590
- VALUE path = args[0];
1591
- VALUE cmd = args[1];
1592
- VALUE arg = args[2];
1593
- VALUE ffi = args[3];
1594
- VALUE flags = args[4];
1595
- VALUE data = args[5];
1596
-
1597
- struct fuse_context *ctx = fuse_get_context();
1598
-
1599
- return rb_funcall((VALUE) ctx->private_data, rb_intern("ioctl"), 7, wrap_context(ctx),
1600
- path, cmd, arg, ffi, flags, data);
1601
- }
1602
-
1603
- static int rf_ioctl(const char *path, int cmd, void *arg,
1604
- struct fuse_file_info *ffi, unsigned int flags, void *data)
1605
- {
1606
- VALUE args[6];
1607
- VALUE res;
1608
- int error = 0;
1609
-
1610
- args[0] = rb_str_new2(path);
1611
- rb_filesystem_encode(args[0]);
1612
- args[1] = INT2NUM(cmd);
1613
- args[2] = wrap_buffer(arg);
1614
- args[3] = get_file_info(ffi);
1615
- args[4] = INT2NUM(flags);
1616
- args[5] = wrap_buffer(data);
1617
-
1618
- res = rb_protect((VALUE (*)())unsafe_ioctl,(VALUE) args, &error);
1619
-
1620
- if (error)
1621
- {
1622
- return -(return_error(ENOENT));
1623
- }
1624
-
1625
- return 0;
1626
- }
1627
- #endif
1628
-
1629
- //----------------------POLL
1630
- #ifdef RFUSE_BROKEN
1631
- static VALUE unsafe_poll(VALUE *args)
1632
- {
1633
- VALUE path = args[0];
1634
- VALUE ffi = args[1];
1635
- VALUE ph = args[2];
1636
- VALUE reventsp = args[3];
1637
-
1638
- struct fuse_context *ctx = fuse_get_context();
1639
-
1640
- return rb_funcall( ctx->private_data, rb_intern("poll"), 5, wrap_context(ctx),
1641
- path, ffi, ph, reventsp);
1642
- }
1643
-
1644
- static int rf_poll(const char *path, struct fuse_file_info *ffi,
1645
- struct fuse_pollhandle *ph, unsigned *reventsp)
1646
- {
1647
- VALUE args[4];
1648
- VALUE res;
1649
- int error = 0;
1650
-
1651
- args[0] = rb_str_new2(path);
1652
- rb_filesystem_encode(args[0]);
1653
- args[1] = get_file_info(ffi);
1654
- args[2] = wrap_pollhandle(ph);
1655
- args[3] = INT2NUM(*reventsp);
1656
-
1657
- res = rb_protect((VALUE (*)())unsafe_poll,(VALUE) args, &error);
1658
-
1659
- if (error)
1660
- {
1661
- return -(return_error(ENOENT));
1662
- }
1663
- else
1664
- {
1665
- *reventsp = NUM2INT(args[3]);
1666
- }
1667
- return 0;
1668
- }
1669
- #endif
1670
-
1671
- /*
1672
- Is the filesystem successfully mounted
1673
-
1674
- @return [Boolean] true if mounted, false otherwise
1675
-
1676
- */
1677
- static VALUE rf_mounted(VALUE self)
1678
- {
1679
- struct intern_fuse *inf;
1680
- Data_Get_Struct(self,struct intern_fuse,inf);
1681
-
1682
- // Never mounted, unmounted via fusermount, or via rf_unmount
1683
- return (inf->fuse == NULL || fuse_exited(inf->fuse) ) ? Qfalse : Qtrue;
1684
- }
1685
-
1686
- /*
1687
- Unmount filesystem
1688
- */
1689
- VALUE rf_unmount(VALUE self)
1690
- {
1691
- struct intern_fuse *inf;
1692
- Data_Get_Struct(self,struct intern_fuse,inf);
1693
-
1694
- rb_funcall(self,rb_intern("ruby_unmount"),0);
1695
-
1696
- if (inf->fuse != NULL) {
1697
- fuse_exit(inf->fuse);
1698
- }
1699
-
1700
- if (inf->fc != NULL) {
1701
- fuse_unmount(inf->mountpoint, inf->fc);
1702
- inf->fc = NULL;
1703
- }
1704
- return Qnil;
1705
- }
1706
-
1707
- /*
1708
- @return [String] directory where this filesystem is mounted
1709
- */
1710
- VALUE rf_mountname(VALUE self)
1711
- {
1712
- struct intern_fuse *inf;
1713
- VALUE result;
1714
-
1715
- Data_Get_Struct(self,struct intern_fuse,inf);
1716
-
1717
- result = rb_str_new2(inf->mountpoint);
1718
- rb_filesystem_encode(result);
1719
-
1720
- return result;
1721
- }
1722
-
1723
- /*
1724
- @deprecated obsolete in FUSE itself
1725
- */
1726
- VALUE rf_invalidate(VALUE self,VALUE path)
1727
- {
1728
- struct intern_fuse *inf;
1729
- Data_Get_Struct(self,struct intern_fuse,inf);
1730
- return fuse_invalidate(inf->fuse,StringValueCStr(path));
1731
- }
1732
-
1733
- /*
1734
- @return [Integer] /dev/fuse file descriptor for use with IO.select and {#process}
1735
- @raise [RFuse::Error] if fuse not mounted
1736
- */
1737
- VALUE rf_fd(VALUE self)
1738
- {
1739
- struct intern_fuse *inf;
1740
- Data_Get_Struct(self,struct intern_fuse,inf);
1741
- if (inf->fuse == NULL) {
1742
- rb_raise(eRFuse_Error,"FUSE not mounted");
1743
- return Qnil;
1744
- } else {
1745
- return INT2NUM(intern_fuse_fd(inf));
1746
- }
1747
- }
1748
-
1749
- /*
1750
- Process one fuse command from the kernel
1751
-
1752
- @return [Integer] 0 if successful
1753
- @raise [RFuse::Error] if fuse not mounted
1754
- */
1755
- VALUE rf_process(VALUE self)
1756
- {
1757
- struct intern_fuse *inf;
1758
- Data_Get_Struct(self,struct intern_fuse,inf);
1759
- if (inf->fuse == NULL) {
1760
- rb_raise(eRFuse_Error,"FUSE not mounted");
1761
- return Qnil;
1762
- } else {
1763
- return INT2NUM(intern_fuse_process(inf));
1764
- }
1765
- }
1766
-
1767
- #define RESPOND_TO(obj,methodname) \
1768
- rb_funcall( \
1769
- obj,rb_intern("respond_to?"), \
1770
- 1, rb_str_new2(methodname) \
1771
- ) == Qtrue
1772
-
1773
- /*
1774
- * initialize and mount the filesystem
1775
- * @overload initialize(mountpoint,*options)
1776
- * @param [String] mountpoint The mountpoint
1777
- * @param [Array<String>] options fuse arguments (-h to see a list)
1778
- */
1779
- static VALUE rf_initialize(
1780
- int argc,
1781
- VALUE* argv,
1782
- VALUE self)
1783
- {
1784
-
1785
- VALUE opts;
1786
- VALUE first_opt;
1787
- VALUE mountpoint_arg;
1788
- VALUE mountpoint;
1789
- struct intern_fuse *inf;
1790
- int init_result;
1791
- struct fuse_args *args;
1792
-
1793
- rb_scan_args(argc, argv, "1*",&mountpoint_arg, &opts);
1794
-
1795
- // Allow pre 1.0.6 style Fuse which forced options to be passed as an array
1796
- if (RARRAY_LEN(opts) == 1) {
1797
- first_opt = rb_ary_entry(opts,0);
1798
- if (TYPE(first_opt) == T_ARRAY) {
1799
- opts = first_opt;
1800
- }
1801
- }
1802
- //Allow things like Pathname to be sent as a mountpoint
1803
- mountpoint = rb_obj_as_string(mountpoint_arg);
1804
-
1805
- //Is this redundant if scan_args has populted opts?
1806
- Check_Type(opts, T_ARRAY);
1807
-
1808
- Data_Get_Struct(self,struct intern_fuse,inf);
1809
-
1810
- inf->mountpoint = strdup(StringValueCStr(mountpoint));
1811
-
1812
- args = rarray2fuseargs(opts);
1813
-
1814
- if (RESPOND_TO(self,"getattr"))
1815
- inf->fuse_op.getattr = rf_getattr;
1816
- if (RESPOND_TO(self,"readlink"))
1817
- inf->fuse_op.readlink = rf_readlink;
1818
- if (RESPOND_TO(self,"getdir"))
1819
- inf->fuse_op.getdir = rf_getdir; // Deprecated
1820
- if (RESPOND_TO(self,"mknod"))
1821
- inf->fuse_op.mknod = rf_mknod;
1822
- if (RESPOND_TO(self,"mkdir"))
1823
- inf->fuse_op.mkdir = rf_mkdir;
1824
- if (RESPOND_TO(self,"unlink"))
1825
- inf->fuse_op.unlink = rf_unlink;
1826
- if (RESPOND_TO(self,"rmdir"))
1827
- inf->fuse_op.rmdir = rf_rmdir;
1828
- if (RESPOND_TO(self,"symlink"))
1829
- inf->fuse_op.symlink = rf_symlink;
1830
- if (RESPOND_TO(self,"rename"))
1831
- inf->fuse_op.rename = rf_rename;
1832
- if (RESPOND_TO(self,"link"))
1833
- inf->fuse_op.link = rf_link;
1834
- if (RESPOND_TO(self,"chmod"))
1835
- inf->fuse_op.chmod = rf_chmod;
1836
- if (RESPOND_TO(self,"chown"))
1837
- inf->fuse_op.chown = rf_chown;
1838
- if (RESPOND_TO(self,"truncate"))
1839
- inf->fuse_op.truncate = rf_truncate;
1840
- if (RESPOND_TO(self,"utime"))
1841
- inf->fuse_op.utime = rf_utime; // Deprecated
1842
- if (RESPOND_TO(self,"open")) {
1843
- inf->fuse_op.open = rf_open;
1844
- inf->fuse_op.release = rf_release_ffi; // remove open file reference
1845
- }
1846
- if (RESPOND_TO(self,"create")) {
1847
- inf->fuse_op.create = rf_create;
1848
- inf->fuse_op.release = rf_release_ffi; // remove open file reference
1849
- }
1850
- if (RESPOND_TO(self,"read"))
1851
- inf->fuse_op.read = rf_read;
1852
- if (RESPOND_TO(self,"write"))
1853
- inf->fuse_op.write = rf_write;
1854
- if (RESPOND_TO(self,"statfs"))
1855
- inf->fuse_op.statfs = rf_statfs;
1856
- if (RESPOND_TO(self,"flush"))
1857
- inf->fuse_op.flush = rf_flush;
1858
- if (RESPOND_TO(self,"release"))
1859
- inf->fuse_op.release = rf_release;
1860
- if (RESPOND_TO(self,"fsync"))
1861
- inf->fuse_op.fsync = rf_fsync;
1862
- if (RESPOND_TO(self,"setxattr"))
1863
- inf->fuse_op.setxattr = rf_setxattr;
1864
- if (RESPOND_TO(self,"getxattr"))
1865
- inf->fuse_op.getxattr = rf_getxattr;
1866
- if (RESPOND_TO(self,"listxattr"))
1867
- inf->fuse_op.listxattr = rf_listxattr;
1868
- if (RESPOND_TO(self,"removexattr"))
1869
- inf->fuse_op.removexattr = rf_removexattr;
1870
- if (RESPOND_TO(self,"opendir")) {
1871
- inf->fuse_op.opendir = rf_opendir;
1872
- inf->fuse_op.release = rf_release_ffi; // remove open file reference
1873
- }
1874
- if (RESPOND_TO(self,"readdir"))
1875
- inf->fuse_op.readdir = rf_readdir;
1876
- if (RESPOND_TO(self,"releasedir"))
1877
- inf->fuse_op.releasedir = rf_releasedir;
1878
- if (RESPOND_TO(self,"fsyncdir"))
1879
- inf->fuse_op.fsyncdir = rf_fsyncdir;
1880
- if (RESPOND_TO(self,"init"))
1881
- inf->fuse_op.init = rf_init;
1882
- if (RESPOND_TO(self,"access"))
1883
- inf->fuse_op.access = rf_access;
1884
- if (RESPOND_TO(self,"ftruncate"))
1885
- inf->fuse_op.ftruncate = rf_ftruncate;
1886
- if (RESPOND_TO(self,"fgetattr"))
1887
- inf->fuse_op.fgetattr = rf_fgetattr;
1888
- if (RESPOND_TO(self,"lock"))
1889
- inf->fuse_op.lock = rf_lock;
1890
- if (RESPOND_TO(self,"utimens"))
1891
- inf->fuse_op.utimens = rf_utimens;
1892
- if (RESPOND_TO(self,"bmap"))
1893
- inf->fuse_op.bmap = rf_bmap;
1894
- #ifdef RFUSE_BROKEN
1895
- if (RESPOND_TO(self,"ioctl"))
1896
- inf->fuse_op.ioctl = rf_ioctl;
1897
- if (RESPOND_TO(self,"poll"))
1898
- inf->fuse_op.poll = rf_poll;
1899
- #endif
1900
-
1901
-
1902
- // init_result indicates not mounted, but so does inf->fuse == NULL
1903
- // raise exceptions only if we try to use the mount
1904
- // can test with mounted?
1905
- // Note we are storing this Ruby object as the FUSE user_data
1906
- init_result = intern_fuse_init(inf, args, (void *) self);
1907
-
1908
- //Create the open files hash where we cache FileInfo objects
1909
- if (init_result == 0) {
1910
- VALUE open_files_hash;
1911
- open_files_hash=rb_hash_new();
1912
- rb_iv_set(self,"@open_files",open_files_hash);
1913
- rb_funcall(self,rb_intern("ruby_initialize"),0);
1914
- }
1915
- return self;
1916
- }
1917
-
1918
- static VALUE rf_new(VALUE class)
1919
- {
1920
- struct intern_fuse *inf;
1921
- VALUE self;
1922
- inf = intern_fuse_new();
1923
- self=Data_Wrap_Struct(class, 0, intern_fuse_destroy, inf);
1924
- return self;
1925
- }
1926
-
1927
- /*
1928
- * Document-class: RFuse::Fuse
1929
- *
1930
- * A FUSE filesystem - extend this class implementing
1931
- * the various abstract methods to provide your filesystem.
1932
- *
1933
- * All file operations take a {Context} and a path as well as any other necessary parameters
1934
- *
1935
- * Mount your filesystem by creating an instance of your subclass and call #loop to begin processing
1936
- */
1937
- void rfuse_init(VALUE module)
1938
- {
1939
- #if 0
1940
- //Trick Yardoc
1941
- mRFuse = rb_define_mRFuse("RFuse");
1942
- #endif
1943
- VALUE cFuse;
1944
-
1945
- mRFuse = module;
1946
-
1947
- // The underlying FUSE library major version
1948
- rb_define_const(mRFuse,"FUSE_MAJOR_VERSION",INT2FIX(FUSE_MAJOR_VERSION));
1949
- // The underlyfing FUSE library minor versoin
1950
- rb_define_const(mRFuse,"FUSE_MINOR_VERSION",INT2FIX(FUSE_MINOR_VERSION));
1951
-
1952
- cFuse = rb_define_class_under(mRFuse,"Fuse",rb_cObject);
1953
-
1954
- rb_define_alloc_func(cFuse,rf_new);
1955
-
1956
- rb_define_method(cFuse,"initialize",rf_initialize,-1);
1957
- rb_define_method(cFuse,"mounted?",rf_mounted,0);
1958
- rb_define_method(cFuse,"invalidate",rf_invalidate,1);
1959
- rb_define_method(cFuse,"unmount",rf_unmount,0);
1960
- rb_define_method(cFuse,"mountname",rf_mountname,0);
1961
- rb_define_alias(cFuse,"mountpoint","mountname");
1962
- rb_define_method(cFuse,"fd",rf_fd,0);
1963
- rb_define_method(cFuse,"process",rf_process,0);
1964
- rb_attr(cFuse,rb_intern("open_files"),1,0,Qfalse);
1965
-
1966
- eRFuse_Error = rb_define_class_under(mRFuse,"Error",rb_eStandardError);
1967
-
1968
- #if 0
1969
- //Trick Yarddoc into documenting abstract fuseoperations
1970
- rb_define_method(cFuse,"readdir",unsafe_readdir,0);
1971
- rb_define_method(cFuse,"readlink",unsafe_readlink,0);
1972
- rb_define_method(cFuse,"getdir",unsafe_getdir,0);
1973
- rb_define_method(cFuse,"mknod",unsafe_mknod,0);
1974
- rb_define_method(cFuse,"getattr",unsafe_getattr,0);
1975
- rb_define_method(cFuse,"mkdir",unsafe_mkdir,0);
1976
- rb_define_method(cFuse,"open",unsafe_open,0);
1977
- rb_define_method(cFuse,"release",unsafe_release,0);
1978
- rb_define_method(cFuse,"fsync",unsafe_fsync,0);
1979
- rb_define_method(cFuse,"flush",unsafe_flush,0);
1980
- rb_define_method(cFuse,"truncate",unsafe_truncate,0);
1981
- rb_define_method(cFuse,"utime",unsafe_utime,0);
1982
- rb_define_method(cFuse,"chown",unsafe_chown,0);
1983
- rb_define_method(cFuse,"chmod",unsafe_chmod,0);
1984
- rb_define_method(cFuse,"unlink",unsafe_unlink,0);
1985
- rb_define_method(cFuse,"symlink",unsafe_symlink,0);
1986
- rb_define_method(cFuse,"rename",unsafe_rename,0);
1987
- rb_define_method(cFuse,"link",unsafe_link,0);
1988
- rb_define_method(cFuse,"read",unsafe_read,0);
1989
- rb_define_method(cFuse,"write",unsafe_write,0);
1990
- rb_define_method(cFuse,"statfs",unsafe_statfs,0);
1991
- rb_define_method(cFuse,"setxattr",unsafe_setxattr,0);
1992
- rb_define_method(cFuse,"getxattr",unsafe_getxattr,0);
1993
- rb_define_method(cFuse,"listxattr",unsafe_listxattr,0);
1994
- rb_define_method(cFuse,"removexattr",unsafe_removexattr,0);
1995
- rb_define_method(cFuse,"opendir",unsafe_opendir,0);
1996
- rb_define_method(cFuse,"releasedir",unsafe_releasedir,0);
1997
- rb_define_method(cFuse,"fsyncdir",unsafe_fsyncdir,0);
1998
- rb_define_method(cFuse,"init",unsafe_init,0);
1999
- rb_define_method(cFuse,"access",unsafe_access,0);
2000
- rb_define_method(cFuse,"create",unsafe_create,0);
2001
- rb_define_method(cFuse,"ftruncate",unsafe_ftruncate,0);
2002
- rb_define_method(cFuse,"fgetattr",unsafe_fgetattr,0);
2003
- rb_define_method(cFuse,"lock",unsafe_lock,0);
2004
- rb_define_method(cFuse,"utimens",unsafe_utimens,0);
2005
- rb_define_method(cFuse,"bmap",unsafe_bmap,0);
2006
- #endif
2007
- }