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

  ViewVC Help
Powered by ViewVC 1.1.26