/[fuse.before_github]/perl/trunk/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/trunk/Fuse.xs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 98 - (hide annotations)
Tue Jan 3 16:45:51 2006 UTC (16 years, 4 months ago) by dpavlin
File size: 17532 byte(s)
subversion revision 71 commited to CVS

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

  ViewVC Help
Powered by ViewVC 1.1.26