/[fuse.before_github]/perl-llin/Fuse.xs
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /perl-llin/Fuse.xs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 92 - (hide annotations)
Mon May 29 08:57:50 2006 UTC (17 years, 10 months ago) by dpavlin
File size: 18129 byte(s)
Mark Glines fixed problem with newer fuse versions
1 mszeredi 4 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 dpavlin 18 #ifdef USE_ITHREADS
6     # ifdef I_PTHREAD
7     /* perl implements threads with pthread. So, we use the pthread API for
8     * handling thread-local storage. */
9     # include <pthread.h>
10     PerlInterpreter *master_interp = NULL;
11     static inline void create_perl_context() {
12     if(master_interp) {
13     PerlInterpreter *me = PERL_GET_CONTEXT;
14     if(!me) {
15     PERL_SET_CONTEXT(master_interp);
16     me = perl_clone(master_interp, CLONEf_CLONE_HOST);
17     }
18     }
19     }
20     # define FUSE_CONTEXT_PRE create_perl_context(); {
21     # define FUSE_CONTEXT_POST }
22     # define FUSE_USE_ITHREADS
23     # else
24     # error "Sorry, I don't know how to handle ithreads on this architecture."
25     # endif
26     #else
27     # define FUSE_CONTEXT_PRE
28     # define FUSE_CONTEXT_POST
29     #endif
30 dpavlin 85 #include <fuse.h>
31 mszeredi 4
32     #undef DEBUGf
33 dpavlin 71 #if 0
34 dpavlin 18 #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,sp-PL_stack_base ,##a )
35 mszeredi 4 #else
36     #define DEBUGf(a...)
37     #endif
38    
39 richdawe 14 #define N_CALLBACKS 25
40     SV *_PLfuse_callbacks[N_CALLBACKS];
41 mszeredi 4
42     int _PLfuse_getattr(const char *file, struct stat *result) {
43 dpavlin 89 int rv;
44 dpavlin 18 FUSE_CONTEXT_PRE;
45 mszeredi 4 dSP;
46 dpavlin 18 DEBUGf("getattr begin: %s\n",file);
47 mszeredi 4 ENTER;
48     SAVETMPS;
49     PUSHMARK(SP);
50     XPUSHs(sv_2mortal(newSVpv(file,strlen(file))));
51     PUTBACK;
52     rv = call_sv(_PLfuse_callbacks[0],G_ARRAY);
53     SPAGAIN;
54     if(rv != 13) {
55     if(rv > 1) {
56     fprintf(stderr,"inappropriate number of returned values from getattr\n");
57     rv = -ENOSYS;
58     } else if(rv)
59     rv = POPi;
60     else
61     rv = -ENOENT;
62     } else {
63 dpavlin 8 result->st_blocks = POPi;
64 mszeredi 4 result->st_blksize = POPi;
65     result->st_ctime = POPi;
66     result->st_mtime = POPi;
67     result->st_atime = POPi;
68     result->st_size = POPi;
69     result->st_rdev = POPi;
70     result->st_gid = POPi;
71     result->st_uid = POPi;
72     result->st_nlink = POPi;
73     result->st_mode = POPi;
74 dpavlin 89 result->st_ino = POPi;
75 mszeredi 4 result->st_dev = POPi;
76     rv = 0;
77     }
78     FREETMPS;
79     LEAVE;
80     PUTBACK;
81 dpavlin 18 DEBUGf("getattr end: %i\n",rv);
82     FUSE_CONTEXT_POST;
83 mszeredi 4 return rv;
84     }
85    
86     int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
87     int rv;
88 dpavlin 18 FUSE_CONTEXT_PRE;
89 mszeredi 4 dSP;
90     if(buflen < 1)
91     return EINVAL;
92 dpavlin 18 DEBUGf("readlink begin\n");
93 mszeredi 4 ENTER;
94     SAVETMPS;
95     PUSHMARK(SP);
96     XPUSHs(sv_2mortal(newSVpv(file,0)));
97     PUTBACK;
98     rv = call_sv(_PLfuse_callbacks[1],G_SCALAR);
99     SPAGAIN;
100     if(!rv)
101     rv = -ENOENT;
102     else {
103     SV *mysv = POPs;
104     if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV)
105     rv = SvIV(mysv);
106     else {
107     strncpy(buf,SvPV_nolen(mysv),buflen);
108     rv = 0;
109     }
110     }
111     FREETMPS;
112     LEAVE;
113     buf[buflen-1] = 0;
114     PUTBACK;
115 dpavlin 18 DEBUGf("readlink end: %i\n",rv);
116     FUSE_CONTEXT_POST;
117 mszeredi 4 return rv;
118     }
119    
120 dpavlin 85 #if 0
121     /*
122     * This doesn't yet work... we alwas get ENOSYS when trying to use readdir().
123     * Well, of course, getdir() is fine as well.
124     */
125     int _PLfuse_readdir(const char *file, void *dirh, fuse_fill_dir_t dirfil, off_t off, struct fuse_file_info *fi) {
126     #endif
127 mszeredi 4 int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
128     int prv, rv;
129 dpavlin 18 FUSE_CONTEXT_PRE;
130 mszeredi 4 dSP;
131 dpavlin 18 DEBUGf("getdir begin\n");
132 mszeredi 4 ENTER;
133     SAVETMPS;
134     PUSHMARK(SP);
135     XPUSHs(sv_2mortal(newSVpv(file,0)));
136     PUTBACK;
137     prv = call_sv(_PLfuse_callbacks[2],G_ARRAY);
138     SPAGAIN;
139     if(prv) {
140     rv = POPi;
141     while(--prv)
142 dpavlin 85 dirfil(dirh,POPp,0,0);
143 mszeredi 4 } else {
144     fprintf(stderr,"getdir() handler returned nothing!\n");
145     rv = -ENOSYS;
146     }
147     FREETMPS;
148     LEAVE;
149     PUTBACK;
150 dpavlin 18 DEBUGf("getdir end: %i\n",rv);
151     FUSE_CONTEXT_POST;
152 mszeredi 4 return rv;
153     }
154    
155     int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
156     int rv;
157 dpavlin 18 FUSE_CONTEXT_PRE;
158 mszeredi 4 dSP;
159 dpavlin 18 DEBUGf("mknod begin\n");
160 mszeredi 4 ENTER;
161     SAVETMPS;
162     PUSHMARK(SP);
163     XPUSHs(sv_2mortal(newSVpv(file,0)));
164     XPUSHs(sv_2mortal(newSViv(mode)));
165     XPUSHs(sv_2mortal(newSViv(dev)));
166     PUTBACK;
167     rv = call_sv(_PLfuse_callbacks[3],G_SCALAR);
168     SPAGAIN;
169     if(rv)
170     rv = POPi;
171     else
172     rv = 0;
173     FREETMPS;
174     LEAVE;
175     PUTBACK;
176 dpavlin 18 DEBUGf("mknod end: %i\n",rv);
177     FUSE_CONTEXT_POST;
178 mszeredi 4 return rv;
179     }
180    
181     int _PLfuse_mkdir (const char *file, mode_t mode) {
182     int rv;
183 dpavlin 18 FUSE_CONTEXT_PRE;
184 mszeredi 4 dSP;
185 dpavlin 18 DEBUGf("mkdir begin\n");
186 mszeredi 4 ENTER;
187     SAVETMPS;
188     PUSHMARK(SP);
189     XPUSHs(sv_2mortal(newSVpv(file,0)));
190     XPUSHs(sv_2mortal(newSViv(mode)));
191     PUTBACK;
192     rv = call_sv(_PLfuse_callbacks[4],G_SCALAR);
193     SPAGAIN;
194     if(rv)
195     rv = POPi;
196     else
197     rv = 0;
198     FREETMPS;
199     LEAVE;
200     PUTBACK;
201 dpavlin 18 DEBUGf("mkdir end: %i\n",rv);
202     FUSE_CONTEXT_POST;
203 mszeredi 4 return rv;
204     }
205    
206    
207     int _PLfuse_unlink (const char *file) {
208     int rv;
209 dpavlin 18 FUSE_CONTEXT_PRE;
210 mszeredi 4 dSP;
211 dpavlin 18 DEBUGf("unlink begin\n");
212 mszeredi 4 ENTER;
213     SAVETMPS;
214     PUSHMARK(SP);
215     XPUSHs(sv_2mortal(newSVpv(file,0)));
216     PUTBACK;
217     rv = call_sv(_PLfuse_callbacks[5],G_SCALAR);
218     SPAGAIN;
219     if(rv)
220     rv = POPi;
221     else
222     rv = 0;
223     FREETMPS;
224     LEAVE;
225     PUTBACK;
226 dpavlin 18 DEBUGf("unlink end: %i\n",rv);
227     FUSE_CONTEXT_POST;
228 mszeredi 4 return rv;
229     }
230    
231     int _PLfuse_rmdir (const char *file) {
232     int rv;
233 dpavlin 18 FUSE_CONTEXT_PRE;
234 mszeredi 4 dSP;
235 dpavlin 18 DEBUGf("rmdir begin\n");
236 mszeredi 4 ENTER;
237     SAVETMPS;
238     PUSHMARK(SP);
239     XPUSHs(sv_2mortal(newSVpv(file,0)));
240     PUTBACK;
241     rv = call_sv(_PLfuse_callbacks[6],G_SCALAR);
242     SPAGAIN;
243     if(rv)
244     rv = POPi;
245     else
246     rv = 0;
247     FREETMPS;
248     LEAVE;
249     PUTBACK;
250 dpavlin 18 DEBUGf("rmdir end: %i\n",rv);
251     FUSE_CONTEXT_POST;
252 mszeredi 4 return rv;
253     }
254    
255     int _PLfuse_symlink (const char *file, const char *new) {
256     int rv;
257 dpavlin 18 FUSE_CONTEXT_PRE;
258 mszeredi 4 dSP;
259 dpavlin 18 DEBUGf("symlink begin\n");
260 mszeredi 4 ENTER;
261     SAVETMPS;
262     PUSHMARK(SP);
263     XPUSHs(sv_2mortal(newSVpv(file,0)));
264     XPUSHs(sv_2mortal(newSVpv(new,0)));
265     PUTBACK;
266     rv = call_sv(_PLfuse_callbacks[7],G_SCALAR);
267     SPAGAIN;
268     if(rv)
269     rv = POPi;
270     else
271     rv = 0;
272     FREETMPS;
273     LEAVE;
274     PUTBACK;
275 dpavlin 18 DEBUGf("symlink end: %i\n",rv);
276     FUSE_CONTEXT_POST;
277 mszeredi 4 return rv;
278     }
279    
280     int _PLfuse_rename (const char *file, const char *new) {
281     int rv;
282 dpavlin 18 FUSE_CONTEXT_PRE;
283 mszeredi 4 dSP;
284 dpavlin 18 DEBUGf("rename begin\n");
285 mszeredi 4 ENTER;
286     SAVETMPS;
287     PUSHMARK(SP);
288     XPUSHs(sv_2mortal(newSVpv(file,0)));
289     XPUSHs(sv_2mortal(newSVpv(new,0)));
290     PUTBACK;
291     rv = call_sv(_PLfuse_callbacks[8],G_SCALAR);
292     SPAGAIN;
293     if(rv)
294     rv = POPi;
295     else
296     rv = 0;
297     FREETMPS;
298     LEAVE;
299     PUTBACK;
300 dpavlin 18 DEBUGf("rename end: %i\n",rv);
301     FUSE_CONTEXT_POST;
302 mszeredi 4 return rv;
303     }
304    
305     int _PLfuse_link (const char *file, const char *new) {
306     int rv;
307 dpavlin 18 FUSE_CONTEXT_PRE;
308 mszeredi 4 dSP;
309 dpavlin 18 DEBUGf("link begin\n");
310 mszeredi 4 ENTER;
311     SAVETMPS;
312     PUSHMARK(SP);
313     XPUSHs(sv_2mortal(newSVpv(file,0)));
314     XPUSHs(sv_2mortal(newSVpv(new,0)));
315     PUTBACK;
316     rv = call_sv(_PLfuse_callbacks[9],G_SCALAR);
317     SPAGAIN;
318     if(rv)
319     rv = POPi;
320     else
321     rv = 0;
322     FREETMPS;
323     LEAVE;
324     PUTBACK;
325 dpavlin 18 DEBUGf("link end: %i\n",rv);
326     FUSE_CONTEXT_POST;
327 mszeredi 4 return rv;
328     }
329    
330     int _PLfuse_chmod (const char *file, mode_t mode) {
331     int rv;
332 dpavlin 18 FUSE_CONTEXT_PRE;
333 mszeredi 4 dSP;
334 dpavlin 18 DEBUGf("chmod begin\n");
335 mszeredi 4 ENTER;
336     SAVETMPS;
337     PUSHMARK(SP);
338     XPUSHs(sv_2mortal(newSVpv(file,0)));
339     XPUSHs(sv_2mortal(newSViv(mode)));
340     PUTBACK;
341     rv = call_sv(_PLfuse_callbacks[10],G_SCALAR);
342     SPAGAIN;
343     if(rv)
344     rv = POPi;
345     else
346     rv = 0;
347     FREETMPS;
348     LEAVE;
349     PUTBACK;
350 dpavlin 18 DEBUGf("chmod end: %i\n",rv);
351     FUSE_CONTEXT_POST;
352 mszeredi 4 return rv;
353     }
354    
355     int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
356     int rv;
357 dpavlin 18 FUSE_CONTEXT_PRE;
358 mszeredi 4 dSP;
359 dpavlin 18 DEBUGf("chown begin\n");
360 mszeredi 4 ENTER;
361     SAVETMPS;
362     PUSHMARK(SP);
363     XPUSHs(sv_2mortal(newSVpv(file,0)));
364     XPUSHs(sv_2mortal(newSViv(uid)));
365     XPUSHs(sv_2mortal(newSViv(gid)));
366     PUTBACK;
367     rv = call_sv(_PLfuse_callbacks[11],G_SCALAR);
368     SPAGAIN;
369     if(rv)
370     rv = POPi;
371     else
372     rv = 0;
373     FREETMPS;
374     LEAVE;
375     PUTBACK;
376 dpavlin 18 DEBUGf("chown end: %i\n",rv);
377     FUSE_CONTEXT_POST;
378 mszeredi 4 return rv;
379     }
380    
381     int _PLfuse_truncate (const char *file, off_t off) {
382     int rv;
383 dpavlin 18 FUSE_CONTEXT_PRE;
384 mszeredi 4 dSP;
385 dpavlin 18 DEBUGf("truncate begin\n");
386 mszeredi 4 ENTER;
387     SAVETMPS;
388     PUSHMARK(SP);
389     XPUSHs(sv_2mortal(newSVpv(file,0)));
390     XPUSHs(sv_2mortal(newSViv(off)));
391     PUTBACK;
392     rv = call_sv(_PLfuse_callbacks[12],G_SCALAR);
393     SPAGAIN;
394     if(rv)
395     rv = POPi;
396     else
397     rv = 0;
398     FREETMPS;
399     LEAVE;
400     PUTBACK;
401 dpavlin 18 DEBUGf("truncate end: %i\n",rv);
402     FUSE_CONTEXT_POST;
403 mszeredi 4 return rv;
404     }
405    
406     int _PLfuse_utime (const char *file, struct utimbuf *uti) {
407     int rv;
408 dpavlin 18 FUSE_CONTEXT_PRE;
409 mszeredi 4 dSP;
410 dpavlin 18 DEBUGf("utime begin\n");
411 mszeredi 4 ENTER;
412     SAVETMPS;
413     PUSHMARK(SP);
414     XPUSHs(sv_2mortal(newSVpv(file,0)));
415     XPUSHs(sv_2mortal(newSViv(uti->actime)));
416     XPUSHs(sv_2mortal(newSViv(uti->modtime)));
417     PUTBACK;
418     rv = call_sv(_PLfuse_callbacks[13],G_SCALAR);
419     SPAGAIN;
420     if(rv)
421     rv = POPi;
422     else
423     rv = 0;
424     FREETMPS;
425     LEAVE;
426     PUTBACK;
427 dpavlin 18 DEBUGf("utime end: %i\n",rv);
428     FUSE_CONTEXT_POST;
429 mszeredi 4 return rv;
430     }
431    
432 dpavlin 85 int _PLfuse_open (const char *file, struct fuse_file_info *fi) {
433 mszeredi 4 int rv;
434 dpavlin 85 int flags = fi->flags;
435 dpavlin 18 FUSE_CONTEXT_PRE;
436 mszeredi 4 dSP;
437 dpavlin 18 DEBUGf("open begin\n");
438 mszeredi 4 ENTER;
439     SAVETMPS;
440     PUSHMARK(SP);
441     XPUSHs(sv_2mortal(newSVpv(file,0)));
442     XPUSHs(sv_2mortal(newSViv(flags)));
443     PUTBACK;
444     rv = call_sv(_PLfuse_callbacks[14],G_SCALAR);
445     SPAGAIN;
446     if(rv)
447     rv = POPi;
448     else
449     rv = 0;
450     FREETMPS;
451     LEAVE;
452     PUTBACK;
453 dpavlin 18 DEBUGf("open end: %i\n",rv);
454     FUSE_CONTEXT_POST;
455 mszeredi 4 return rv;
456     }
457    
458 dpavlin 85 int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
459 mszeredi 4 int rv;
460 dpavlin 18 FUSE_CONTEXT_PRE;
461 mszeredi 4 dSP;
462 dpavlin 18 DEBUGf("read begin\n");
463 mszeredi 4 ENTER;
464     SAVETMPS;
465     PUSHMARK(SP);
466     XPUSHs(sv_2mortal(newSVpv(file,0)));
467     XPUSHs(sv_2mortal(newSViv(buflen)));
468     XPUSHs(sv_2mortal(newSViv(off)));
469     PUTBACK;
470     rv = call_sv(_PLfuse_callbacks[15],G_SCALAR);
471     SPAGAIN;
472     if(!rv)
473     rv = -ENOENT;
474     else {
475     SV *mysv = POPs;
476     if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
477     rv = SvIV(mysv);
478     else {
479     if(SvPOK(mysv)) {
480     rv = SvCUR(mysv);
481     } else {
482     rv = 0;
483     }
484     if(rv > buflen)
485 dpavlin 19 croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
486 mszeredi 4 if(rv)
487     memcpy(buf,SvPV_nolen(mysv),rv);
488     }
489     }
490     FREETMPS;
491     LEAVE;
492     PUTBACK;
493 dpavlin 18 DEBUGf("read end: %i\n",rv);
494     FUSE_CONTEXT_POST;
495 mszeredi 4 return rv;
496     }
497    
498 dpavlin 85 int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
499 mszeredi 4 int rv;
500 dpavlin 18 FUSE_CONTEXT_PRE;
501 mszeredi 4 dSP;
502 dpavlin 18 DEBUGf("write begin\n");
503 mszeredi 4 ENTER;
504     SAVETMPS;
505     PUSHMARK(SP);
506     XPUSHs(sv_2mortal(newSVpv(file,0)));
507     XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
508     XPUSHs(sv_2mortal(newSViv(off)));
509     PUTBACK;
510     rv = call_sv(_PLfuse_callbacks[16],G_SCALAR);
511     SPAGAIN;
512     if(rv)
513     rv = POPi;
514     else
515     rv = 0;
516     FREETMPS;
517     LEAVE;
518     PUTBACK;
519 dpavlin 18 DEBUGf("write end: %i\n",rv);
520     FUSE_CONTEXT_POST;
521 mszeredi 4 return rv;
522     }
523    
524 dpavlin 85 int _PLfuse_statfs (const char *file, struct statvfs *st) {
525 mszeredi 4 int rv;
526 dpavlin 18 FUSE_CONTEXT_PRE;
527 mszeredi 4 dSP;
528 dpavlin 18 DEBUGf("statfs begin\n");
529 mszeredi 4 ENTER;
530     SAVETMPS;
531     PUSHMARK(SP);
532     PUTBACK;
533     rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
534     SPAGAIN;
535 dpavlin 28 DEBUGf("statfs got %i params\n",rv);
536     if(rv == 6 || rv == 7) {
537 dpavlin 68 st->f_bsize = POPi;
538     st->f_bfree = POPi;
539     st->f_blocks = POPi;
540     st->f_ffree = POPi;
541     st->f_files = POPi;
542     st->f_namemax = POPi;
543     /* zero and fill-in other */
544     st->f_fsid = 0;
545 dpavlin 26 st->f_frsize = 4096;
546     st->f_flag = 0;
547 dpavlin 68 st->f_bavail = st->f_bfree;
548     st->f_favail = st->f_ffree;
549 dpavlin 26
550 dpavlin 28 if(rv == 7)
551 mszeredi 4 rv = POPi;
552     else
553     rv = 0;
554     } else
555     if(rv > 1)
556     croak("inappropriate number of returned values from statfs");
557     else
558     if(rv)
559     rv = POPi;
560     else
561     rv = -ENOSYS;
562     FREETMPS;
563     LEAVE;
564     PUTBACK;
565 dpavlin 18 DEBUGf("statfs end: %i\n",rv);
566     FUSE_CONTEXT_POST;
567 mszeredi 4 return rv;
568     }
569    
570 dpavlin 85 int _PLfuse_flush (const char *file, struct fuse_file_info *fi) {
571 richdawe 14 int rv;
572 dpavlin 18 FUSE_CONTEXT_PRE;
573 richdawe 14 dSP;
574 dpavlin 18 DEBUGf("flush begin\n");
575 richdawe 14 ENTER;
576     SAVETMPS;
577     PUSHMARK(SP);
578     XPUSHs(sv_2mortal(newSVpv(file,0)));
579     PUTBACK;
580     rv = call_sv(_PLfuse_callbacks[18],G_SCALAR);
581     SPAGAIN;
582     if(rv)
583     rv = POPi;
584     else
585     rv = 0;
586     FREETMPS;
587     LEAVE;
588     PUTBACK;
589 dpavlin 18 DEBUGf("flush end: %i\n",rv);
590     FUSE_CONTEXT_POST;
591 richdawe 14 return rv;
592     }
593    
594 dpavlin 85 int _PLfuse_release (const char *file, struct fuse_file_info *fi) {
595 richdawe 14 int rv;
596 dpavlin 85 int flags = fi->flags;
597 dpavlin 18 FUSE_CONTEXT_PRE;
598 richdawe 14 dSP;
599 dpavlin 18 DEBUGf("release begin\n");
600 richdawe 14 ENTER;
601     SAVETMPS;
602     PUSHMARK(SP);
603     XPUSHs(sv_2mortal(newSVpv(file,0)));
604     XPUSHs(sv_2mortal(newSViv(flags)));
605     PUTBACK;
606     rv = call_sv(_PLfuse_callbacks[19],G_SCALAR);
607     SPAGAIN;
608     if(rv)
609     rv = POPi;
610     else
611     rv = 0;
612     FREETMPS;
613     LEAVE;
614     PUTBACK;
615 dpavlin 18 DEBUGf("release end: %i\n",rv);
616     FUSE_CONTEXT_POST;
617 richdawe 14 return rv;
618     }
619    
620 dpavlin 85 int _PLfuse_fsync (const char *file, int datasync, struct fuse_file_info *fi) {
621 richdawe 14 int rv;
622 dpavlin 85 int flags = fi->flags;
623 dpavlin 18 FUSE_CONTEXT_PRE;
624 richdawe 14 dSP;
625 dpavlin 18 DEBUGf("fsync begin\n");
626 richdawe 14 ENTER;
627     SAVETMPS;
628     PUSHMARK(SP);
629     XPUSHs(sv_2mortal(newSVpv(file,0)));
630     XPUSHs(sv_2mortal(newSViv(flags)));
631     PUTBACK;
632     rv = call_sv(_PLfuse_callbacks[20],G_SCALAR);
633     SPAGAIN;
634     if(rv)
635     rv = POPi;
636     else
637     rv = 0;
638     FREETMPS;
639     LEAVE;
640     PUTBACK;
641 dpavlin 18 DEBUGf("fsync end: %i\n",rv);
642     FUSE_CONTEXT_POST;
643 richdawe 14 return rv;
644     }
645    
646     int _PLfuse_setxattr (const char *file, const char *name, const char *buf, size_t buflen, int flags) {
647     int rv;
648 dpavlin 18 FUSE_CONTEXT_PRE;
649 richdawe 14 dSP;
650 dpavlin 18 DEBUGf("setxattr begin\n");
651 richdawe 14 ENTER;
652     SAVETMPS;
653     PUSHMARK(SP);
654     XPUSHs(sv_2mortal(newSVpv(file,0)));
655     XPUSHs(sv_2mortal(newSVpv(name,0)));
656     XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
657     XPUSHs(sv_2mortal(newSViv(flags)));
658     PUTBACK;
659     rv = call_sv(_PLfuse_callbacks[21],G_SCALAR);
660     SPAGAIN;
661     if(rv)
662     rv = POPi;
663     else
664     rv = 0;
665     FREETMPS;
666     LEAVE;
667     PUTBACK;
668 dpavlin 18 DEBUGf("setxattr end: %i\n",rv);
669     FUSE_CONTEXT_POST;
670 richdawe 14 return rv;
671     }
672    
673     int _PLfuse_getxattr (const char *file, const char *name, char *buf, size_t buflen) {
674     int rv;
675 dpavlin 18 FUSE_CONTEXT_PRE;
676 richdawe 14 dSP;
677 dpavlin 18 DEBUGf("getxattr begin\n");
678 richdawe 14 ENTER;
679     SAVETMPS;
680     PUSHMARK(SP);
681     XPUSHs(sv_2mortal(newSVpv(file,0)));
682     XPUSHs(sv_2mortal(newSVpv(name,0)));
683     PUTBACK;
684     rv = call_sv(_PLfuse_callbacks[22],G_SCALAR);
685     SPAGAIN;
686     if(!rv)
687     rv = -ENOENT;
688     else {
689     SV *mysv = POPs;
690    
691     rv = 0;
692     if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
693     rv = SvIV(mysv);
694     else {
695     if(SvPOK(mysv)) {
696     rv = SvCUR(mysv);
697     } else {
698     rv = 0;
699     }
700     if ((rv > 0) && (buflen > 0))
701     {
702     if(rv > buflen)
703     rv = -ERANGE;
704     else
705     memcpy(buf,SvPV_nolen(mysv),rv);
706     }
707     }
708     }
709     FREETMPS;
710     LEAVE;
711     PUTBACK;
712 dpavlin 18 DEBUGf("getxattr end: %i\n",rv);
713     FUSE_CONTEXT_POST;
714 richdawe 14 return rv;
715     }
716    
717     int _PLfuse_listxattr (const char *file, char *list, size_t size) {
718     int prv, rv;
719 dpavlin 18 FUSE_CONTEXT_PRE;
720 richdawe 14 dSP;
721 dpavlin 18 DEBUGf("listxattr begin\n");
722 richdawe 14 ENTER;
723     SAVETMPS;
724     PUSHMARK(SP);
725     XPUSHs(sv_2mortal(newSVpv(file,0)));
726     PUTBACK;
727     prv = call_sv(_PLfuse_callbacks[23],G_ARRAY);
728     SPAGAIN;
729     if(!prv)
730     rv = -ENOENT;
731     else {
732    
733     char *p = list;
734     int spc = size;
735     int total_len = 0;
736    
737     rv = POPi;
738     prv--;
739    
740     /* Always nul terminate */
741     if (list && (size > 0))
742     list[0] = '\0';
743    
744     while (prv > 0)
745     {
746     SV *mysv = POPs;
747     prv--;
748    
749     if (SvPOK(mysv)) {
750     /* Copy nul too */
751     int s = SvCUR(mysv) + 1;
752     total_len += s;
753    
754     if (p && (size > 0) && (spc >= s))
755     {
756     memcpy(p,SvPV_nolen(mysv),s);
757     p += s;
758     spc -= s;
759     }
760     }
761     }
762    
763     /*
764     * If the Perl returned an error, return that.
765     * Otherwise check that the buffer was big enough.
766     */
767     if (rv == 0)
768     {
769     rv = total_len;
770     if ((size > 0) && (size < total_len))
771     rv = -ERANGE;
772     }
773     }
774     FREETMPS;
775     LEAVE;
776     PUTBACK;
777 dpavlin 18 DEBUGf("listxattr end: %i\n",rv);
778     FUSE_CONTEXT_POST;
779 richdawe 14 return rv;
780     }
781    
782     int _PLfuse_removexattr (const char *file, const char *name) {
783     int rv;
784 dpavlin 18 FUSE_CONTEXT_PRE;
785 richdawe 14 dSP;
786 dpavlin 18 DEBUGf("removexattr begin\n");
787 richdawe 14 ENTER;
788     SAVETMPS;
789     PUSHMARK(SP);
790     XPUSHs(sv_2mortal(newSVpv(file,0)));
791     XPUSHs(sv_2mortal(newSVpv(name,0)));
792     PUTBACK;
793     rv = call_sv(_PLfuse_callbacks[24],G_SCALAR);
794     SPAGAIN;
795     if(rv)
796     rv = POPi;
797     else
798     rv = 0;
799     FREETMPS;
800     LEAVE;
801     PUTBACK;
802 dpavlin 18 DEBUGf("removexattr end: %i\n",rv);
803     FUSE_CONTEXT_POST;
804 richdawe 14 return rv;
805     }
806    
807 mszeredi 4 struct fuse_operations _available_ops = {
808 richdawe 14 getattr: _PLfuse_getattr,
809     readlink: _PLfuse_readlink,
810     getdir: _PLfuse_getdir,
811 dpavlin 85 #if 0
812     readdir: _PLfuse_readdir,
813     #endif
814 richdawe 14 mknod: _PLfuse_mknod,
815     mkdir: _PLfuse_mkdir,
816     unlink: _PLfuse_unlink,
817     rmdir: _PLfuse_rmdir,
818     symlink: _PLfuse_symlink,
819     rename: _PLfuse_rename,
820     link: _PLfuse_link,
821     chmod: _PLfuse_chmod,
822     chown: _PLfuse_chown,
823     truncate: _PLfuse_truncate,
824     utime: _PLfuse_utime,
825     open: _PLfuse_open,
826     read: _PLfuse_read,
827     write: _PLfuse_write,
828     statfs: _PLfuse_statfs,
829     flush: _PLfuse_flush,
830     release: _PLfuse_release,
831     fsync: _PLfuse_fsync,
832     setxattr: _PLfuse_setxattr,
833     getxattr: _PLfuse_getxattr,
834     listxattr: _PLfuse_listxattr,
835     removexattr: _PLfuse_removexattr,
836 mszeredi 4 };
837    
838     MODULE = Fuse PACKAGE = Fuse
839     PROTOTYPES: DISABLE
840    
841     void
842     perl_fuse_main(...)
843     PREINIT:
844 dpavlin 19 struct fuse_operations fops =
845     {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
846     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
847 dpavlin 89 int i, fd, debug, threaded;
848 mszeredi 4 char *mountpoint;
849 dpavlin 16 char *mountopts;
850 dpavlin 85 struct fuse_args margs = FUSE_ARGS_INIT(0, NULL);
851     struct fuse_args fargs = FUSE_ARGS_INIT(0, NULL);
852 mszeredi 4 INIT:
853 dpavlin 18 if(items != 29) {
854 mszeredi 4 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
855     XSRETURN_UNDEF;
856     }
857     CODE:
858     debug = SvIV(ST(0));
859 dpavlin 18 threaded = SvIV(ST(1));
860     if(threaded) {
861     #ifdef FUSE_USE_ITHREADS
862     master_interp = PERL_GET_INTERP;
863     #else
864     fprintf(stderr,"FUSE warning: Your script has requested multithreaded "
865     "mode, but your perl was not built with -Dusethreads. "
866     "Threads are disabled.\n");
867     threaded = 0;
868     #endif
869     }
870     mountpoint = SvPV_nolen(ST(2));
871     mountopts = SvPV_nolen(ST(3));
872 richdawe 14 for(i=0;i<N_CALLBACKS;i++) {
873 dpavlin 18 SV *var = ST(i+4);
874 dpavlin 19 /* allow symbolic references, or real code references. */
875     if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
876 dpavlin 18 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
877     tmp2[i] = tmp1[i];
878 dpavlin 19 #ifdef FUSE_USE_ITHREADS
879 dpavlin 18 if(threaded)
880     /* note: under 5.8.7, this croaks for code references. */
881     SvSHARE(var);
882 dpavlin 19 #endif
883 dpavlin 18 _PLfuse_callbacks[i] = var;
884 dpavlin 19 } else
885     if(SvOK(var)) {
886     croak("invalid callback passed to perl_fuse_main "
887     "(%s is not a string, code ref, or undef).\n",
888     i+4,SvPVbyte_nolen(var));
889 mszeredi 4 }
890     }
891 dpavlin 85 /*
892     * XXX: What comes here is just a ridiculous use of the option parsing API
893     * to hack on compatibility with other parts of the new API. First and
894     * foremost, real C argc/argv would be good to get at...
895     */
896     if (mountopts &&
897     (fuse_opt_add_arg(&margs, "") == -1 ||
898     fuse_opt_add_arg(&margs, "-o") == -1 ||
899     fuse_opt_add_arg(&margs, mountopts) == -1)) {
900     fuse_opt_free_args(&margs);
901     croak("out of memory\n");
902     }
903     fd = fuse_mount(mountpoint,&margs);
904     fuse_opt_free_args(&margs);
905 mszeredi 4 if(fd < 0)
906 dpavlin 87 croak("could not mount fuse filesystem!\n");
907     if (debug) {
908     if ( fuse_opt_add_arg(&fargs, "") == -1 ||
909     fuse_opt_add_arg(&fargs, "-d") == -1) {
910     fuse_opt_free_args(&fargs);
911     croak("out of memory\n");
912     }
913     } else {
914     if (fuse_opt_add_arg(&fargs, "") == -1)
915     croak("out of memory\n");
916 dpavlin 85 }
917 dpavlin 87
918 dpavlin 18 if(threaded) {
919 dpavlin 92 fuse_loop_mt(fuse_new(fd,&fargs,&fops,sizeof(fops)));
920 dpavlin 18 } else
921 dpavlin 92 fuse_loop(fuse_new(fd,&fargs,&fops,sizeof(fops)));
922 dpavlin 85 fuse_opt_free_args(&fargs);

  ViewVC Help
Powered by ViewVC 1.1.26