/[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 8 - (hide annotations)
Fri Nov 26 20:38:56 2004 UTC (19 years, 4 months ago) by dpavlin
File size: 10751 byte(s)
It seems that blockcount isn't last argument any longer. Fixed.

1 mszeredi 4 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 dpavlin 7 #include <fuse/fuse.h>
6 mszeredi 4
7     #undef DEBUGf
8     #if 0
9     #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,PL_stack_sp-PL_stack_base ,##a )
10     #else
11     #define DEBUGf(a...)
12     #endif
13    
14     SV *_PLfuse_callbacks[18];
15    
16     int _PLfuse_getattr(const char *file, struct stat *result) {
17     dSP;
18     int rv, statcount;
19     ENTER;
20     SAVETMPS;
21     PUSHMARK(SP);
22     XPUSHs(sv_2mortal(newSVpv(file,strlen(file))));
23     PUTBACK;
24     rv = call_sv(_PLfuse_callbacks[0],G_ARRAY);
25     SPAGAIN;
26     if(rv != 13) {
27     if(rv > 1) {
28     fprintf(stderr,"inappropriate number of returned values from getattr\n");
29     rv = -ENOSYS;
30     } else if(rv)
31     rv = POPi;
32     else
33     rv = -ENOENT;
34     } else {
35 dpavlin 8 result->st_blocks = POPi;
36 mszeredi 4 result->st_blksize = POPi;
37     result->st_ctime = POPi;
38     result->st_mtime = POPi;
39     result->st_atime = POPi;
40     result->st_size = POPi;
41     result->st_rdev = POPi;
42     result->st_gid = POPi;
43     result->st_uid = POPi;
44     result->st_nlink = POPi;
45     result->st_mode = POPi;
46     /*result->st_ino =*/ POPi;
47     result->st_dev = POPi;
48     rv = 0;
49     }
50     FREETMPS;
51     LEAVE;
52     PUTBACK;
53     return rv;
54     }
55    
56     int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
57     int rv;
58     char *rvstr;
59     dSP;
60     I32 ax;
61     if(buflen < 1)
62     return EINVAL;
63     ENTER;
64     SAVETMPS;
65     PUSHMARK(SP);
66     XPUSHs(sv_2mortal(newSVpv(file,0)));
67     PUTBACK;
68     rv = call_sv(_PLfuse_callbacks[1],G_SCALAR);
69     SPAGAIN;
70     if(!rv)
71     rv = -ENOENT;
72     else {
73     SV *mysv = POPs;
74     if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV)
75     rv = SvIV(mysv);
76     else {
77     strncpy(buf,SvPV_nolen(mysv),buflen);
78     rv = 0;
79     }
80     }
81     FREETMPS;
82     LEAVE;
83     buf[buflen-1] = 0;
84     PUTBACK;
85     return rv;
86     }
87    
88     int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
89     int prv, rv;
90     dSP;
91     ENTER;
92     SAVETMPS;
93     PUSHMARK(SP);
94     XPUSHs(sv_2mortal(newSVpv(file,0)));
95     PUTBACK;
96     prv = call_sv(_PLfuse_callbacks[2],G_ARRAY);
97     SPAGAIN;
98     if(prv) {
99     rv = POPi;
100     while(--prv)
101 dpavlin 7 dirfil(dirh,POPp,0,0);
102 mszeredi 4 } else {
103     fprintf(stderr,"getdir() handler returned nothing!\n");
104     rv = -ENOSYS;
105     }
106     FREETMPS;
107     LEAVE;
108     PUTBACK;
109     return rv;
110     }
111    
112     int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
113     int rv;
114     SV *rvsv;
115     char *rvstr;
116     dSP;
117     ENTER;
118     SAVETMPS;
119     PUSHMARK(SP);
120     XPUSHs(sv_2mortal(newSVpv(file,0)));
121     XPUSHs(sv_2mortal(newSViv(mode)));
122     XPUSHs(sv_2mortal(newSViv(dev)));
123     PUTBACK;
124     rv = call_sv(_PLfuse_callbacks[3],G_SCALAR);
125     SPAGAIN;
126     if(rv)
127     rv = POPi;
128     else
129     rv = 0;
130     FREETMPS;
131     LEAVE;
132     PUTBACK;
133     return rv;
134     }
135    
136     int _PLfuse_mkdir (const char *file, mode_t mode) {
137     int rv;
138     SV *rvsv;
139     char *rvstr;
140     dSP;
141     DEBUGf("mkdir begin: %i\n",sp-PL_stack_base);
142     ENTER;
143     SAVETMPS;
144     PUSHMARK(SP);
145     XPUSHs(sv_2mortal(newSVpv(file,0)));
146     XPUSHs(sv_2mortal(newSViv(mode)));
147     PUTBACK;
148     rv = call_sv(_PLfuse_callbacks[4],G_SCALAR);
149     SPAGAIN;
150     if(rv)
151     rv = POPi;
152     else
153     rv = 0;
154     FREETMPS;
155     LEAVE;
156     PUTBACK;
157     DEBUGf("mkdir end: %i %i\n",sp-PL_stack_base,rv);
158     return rv;
159     }
160    
161    
162     int _PLfuse_unlink (const char *file) {
163     int rv;
164     SV *rvsv;
165     char *rvstr;
166     dSP;
167     DEBUGf("unlink begin: %i\n",sp-PL_stack_base);
168     ENTER;
169     SAVETMPS;
170     PUSHMARK(SP);
171     XPUSHs(sv_2mortal(newSVpv(file,0)));
172     PUTBACK;
173     rv = call_sv(_PLfuse_callbacks[5],G_SCALAR);
174     SPAGAIN;
175     if(rv)
176     rv = POPi;
177     else
178     rv = 0;
179     FREETMPS;
180     LEAVE;
181     PUTBACK;
182     DEBUGf("unlink end: %i\n",sp-PL_stack_base);
183     return rv;
184     }
185    
186     int _PLfuse_rmdir (const char *file) {
187     int rv;
188     SV *rvsv;
189     char *rvstr;
190     dSP;
191     DEBUGf("rmdir begin: %i\n",sp-PL_stack_base);
192     ENTER;
193     SAVETMPS;
194     PUSHMARK(SP);
195     XPUSHs(sv_2mortal(newSVpv(file,0)));
196     PUTBACK;
197     rv = call_sv(_PLfuse_callbacks[6],G_SCALAR);
198     SPAGAIN;
199     if(rv)
200     rv = POPi;
201     else
202     rv = 0;
203     FREETMPS;
204     LEAVE;
205     PUTBACK;
206     DEBUGf("rmdir end: %i %i\n",sp-PL_stack_base,rv);
207     return rv;
208     }
209    
210     int _PLfuse_symlink (const char *file, const char *new) {
211     int rv;
212     SV *rvsv;
213     char *rvstr;
214     dSP;
215     DEBUGf("symlink begin: %i\n",sp-PL_stack_base);
216     ENTER;
217     SAVETMPS;
218     PUSHMARK(SP);
219     XPUSHs(sv_2mortal(newSVpv(file,0)));
220     XPUSHs(sv_2mortal(newSVpv(new,0)));
221     PUTBACK;
222     rv = call_sv(_PLfuse_callbacks[7],G_SCALAR);
223     SPAGAIN;
224     if(rv)
225     rv = POPi;
226     else
227     rv = 0;
228     FREETMPS;
229     LEAVE;
230     PUTBACK;
231     DEBUGf("symlink end: %i\n",sp-PL_stack_base);
232     return rv;
233     }
234    
235     int _PLfuse_rename (const char *file, const char *new) {
236     int rv;
237     SV *rvsv;
238     char *rvstr;
239     dSP;
240     DEBUGf("rename begin: %i\n",sp-PL_stack_base);
241     ENTER;
242     SAVETMPS;
243     PUSHMARK(SP);
244     XPUSHs(sv_2mortal(newSVpv(file,0)));
245     XPUSHs(sv_2mortal(newSVpv(new,0)));
246     PUTBACK;
247     rv = call_sv(_PLfuse_callbacks[8],G_SCALAR);
248     SPAGAIN;
249     if(rv)
250     rv = POPi;
251     else
252     rv = 0;
253     FREETMPS;
254     LEAVE;
255     PUTBACK;
256     DEBUGf("rename end: %i\n",sp-PL_stack_base);
257     return rv;
258     }
259    
260     int _PLfuse_link (const char *file, const char *new) {
261     int rv;
262     SV *rvsv;
263     char *rvstr;
264     dSP;
265     DEBUGf("link begin: %i\n",sp-PL_stack_base);
266     ENTER;
267     SAVETMPS;
268     PUSHMARK(SP);
269     XPUSHs(sv_2mortal(newSVpv(file,0)));
270     XPUSHs(sv_2mortal(newSVpv(new,0)));
271     PUTBACK;
272     rv = call_sv(_PLfuse_callbacks[9],G_SCALAR);
273     SPAGAIN;
274     if(rv)
275     rv = POPi;
276     else
277     rv = 0;
278     FREETMPS;
279     LEAVE;
280     PUTBACK;
281     DEBUGf("link end: %i\n",sp-PL_stack_base);
282     return rv;
283     }
284    
285     int _PLfuse_chmod (const char *file, mode_t mode) {
286     int rv;
287     SV *rvsv;
288     char *rvstr;
289     dSP;
290     DEBUGf("chmod begin: %i\n",sp-PL_stack_base);
291     ENTER;
292     SAVETMPS;
293     PUSHMARK(SP);
294     XPUSHs(sv_2mortal(newSVpv(file,0)));
295     XPUSHs(sv_2mortal(newSViv(mode)));
296     PUTBACK;
297     rv = call_sv(_PLfuse_callbacks[10],G_SCALAR);
298     SPAGAIN;
299     if(rv)
300     rv = POPi;
301     else
302     rv = 0;
303     FREETMPS;
304     LEAVE;
305     PUTBACK;
306     DEBUGf("chmod end: %i\n",sp-PL_stack_base);
307     return rv;
308     }
309    
310     int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
311     int rv;
312     SV *rvsv;
313     char *rvstr;
314     dSP;
315     DEBUGf("chown begin: %i\n",sp-PL_stack_base);
316     ENTER;
317     SAVETMPS;
318     PUSHMARK(SP);
319     XPUSHs(sv_2mortal(newSVpv(file,0)));
320     XPUSHs(sv_2mortal(newSViv(uid)));
321     XPUSHs(sv_2mortal(newSViv(gid)));
322     PUTBACK;
323     rv = call_sv(_PLfuse_callbacks[11],G_SCALAR);
324     SPAGAIN;
325     if(rv)
326     rv = POPi;
327     else
328     rv = 0;
329     FREETMPS;
330     LEAVE;
331     PUTBACK;
332     DEBUGf("chown end: %i\n",sp-PL_stack_base);
333     return rv;
334     }
335    
336     int _PLfuse_truncate (const char *file, off_t off) {
337     int rv;
338     SV *rvsv;
339     char *rvstr;
340     dSP;
341     DEBUGf("truncate begin: %i\n",sp-PL_stack_base);
342     ENTER;
343     SAVETMPS;
344     PUSHMARK(SP);
345     XPUSHs(sv_2mortal(newSVpv(file,0)));
346     XPUSHs(sv_2mortal(newSViv(off)));
347     PUTBACK;
348     rv = call_sv(_PLfuse_callbacks[12],G_SCALAR);
349     SPAGAIN;
350     if(rv)
351     rv = POPi;
352     else
353     rv = 0;
354     FREETMPS;
355     LEAVE;
356     PUTBACK;
357     DEBUGf("truncate end: %i\n",sp-PL_stack_base);
358     return rv;
359     }
360    
361     int _PLfuse_utime (const char *file, struct utimbuf *uti) {
362     int rv;
363     SV *rvsv;
364     char *rvstr;
365     dSP;
366     DEBUGf("utime begin: %i\n",sp-PL_stack_base);
367     ENTER;
368     SAVETMPS;
369     PUSHMARK(SP);
370     XPUSHs(sv_2mortal(newSVpv(file,0)));
371     XPUSHs(sv_2mortal(newSViv(uti->actime)));
372     XPUSHs(sv_2mortal(newSViv(uti->modtime)));
373     PUTBACK;
374     rv = call_sv(_PLfuse_callbacks[13],G_SCALAR);
375     SPAGAIN;
376     if(rv)
377     rv = POPi;
378     else
379     rv = 0;
380     FREETMPS;
381     LEAVE;
382     PUTBACK;
383     DEBUGf("utime end: %i\n",sp-PL_stack_base);
384     return rv;
385     }
386    
387     int _PLfuse_open (const char *file, int flags) {
388     int rv;
389     SV *rvsv;
390     char *rvstr;
391     dSP;
392     DEBUGf("open begin: %i\n",sp-PL_stack_base);
393     ENTER;
394     SAVETMPS;
395     PUSHMARK(SP);
396     XPUSHs(sv_2mortal(newSVpv(file,0)));
397     XPUSHs(sv_2mortal(newSViv(flags)));
398     PUTBACK;
399     rv = call_sv(_PLfuse_callbacks[14],G_SCALAR);
400     SPAGAIN;
401     if(rv)
402     rv = POPi;
403     else
404     rv = 0;
405     FREETMPS;
406     LEAVE;
407     PUTBACK;
408     DEBUGf("open end: %i %i\n",sp-PL_stack_base,rv);
409     return rv;
410     }
411    
412     int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off) {
413     int rv;
414     char *rvstr;
415     dSP;
416     DEBUGf("read begin: %i\n",sp-PL_stack_base);
417     ENTER;
418     SAVETMPS;
419     PUSHMARK(SP);
420     XPUSHs(sv_2mortal(newSVpv(file,0)));
421     XPUSHs(sv_2mortal(newSViv(buflen)));
422     XPUSHs(sv_2mortal(newSViv(off)));
423     PUTBACK;
424     rv = call_sv(_PLfuse_callbacks[15],G_SCALAR);
425     SPAGAIN;
426     if(!rv)
427     rv = -ENOENT;
428     else {
429     SV *mysv = POPs;
430     if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
431     rv = SvIV(mysv);
432     else {
433     if(SvPOK(mysv)) {
434     rv = SvCUR(mysv);
435     } else {
436     rv = 0;
437     }
438     if(rv > buflen)
439     croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
440     if(rv)
441     memcpy(buf,SvPV_nolen(mysv),rv);
442     }
443     }
444     FREETMPS;
445     LEAVE;
446     PUTBACK;
447     DEBUGf("read end: %i %i\n",sp-PL_stack_base,rv);
448     return rv;
449     }
450    
451     int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) {
452     int rv;
453     char *rvstr;
454     dSP;
455     DEBUGf("write begin: %i\n",sp-PL_stack_base);
456     ENTER;
457     SAVETMPS;
458     PUSHMARK(SP);
459     XPUSHs(sv_2mortal(newSVpv(file,0)));
460     XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
461     XPUSHs(sv_2mortal(newSViv(off)));
462     PUTBACK;
463     rv = call_sv(_PLfuse_callbacks[16],G_SCALAR);
464     SPAGAIN;
465     if(rv)
466     rv = POPi;
467     else
468     rv = 0;
469     FREETMPS;
470     LEAVE;
471     PUTBACK;
472     DEBUGf("write end: %i\n",sp-PL_stack_base);
473     return rv;
474     }
475    
476     int _PLfuse_statfs (const char *file, struct statfs *st) {
477     int rv;
478     char *rvstr;
479     dSP;
480     DEBUGf("statfs begin: %i\n",sp-PL_stack_base);
481     ENTER;
482     SAVETMPS;
483     PUSHMARK(SP);
484     PUTBACK;
485     rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
486     SPAGAIN;
487     if(rv > 5) {
488     st->f_bsize = POPi;
489     st->f_bfree = POPi;
490     st->f_blocks = POPi;
491     st->f_ffree = POPi;
492     st->f_files = POPi;
493     st->f_namelen = POPi;
494     if(rv > 6)
495     rv = POPi;
496     else
497     rv = 0;
498     } else
499     if(rv > 1)
500     croak("inappropriate number of returned values from statfs");
501     else
502     if(rv)
503     rv = POPi;
504     else
505     rv = -ENOSYS;
506     FREETMPS;
507     LEAVE;
508     PUTBACK;
509     DEBUGf("statfs end: %i\n",sp-PL_stack_base);
510     return rv;
511     }
512    
513     struct fuse_operations _available_ops = {
514     getattr: _PLfuse_getattr,
515     _PLfuse_readlink,
516     _PLfuse_getdir,
517     _PLfuse_mknod,
518     _PLfuse_mkdir,
519     _PLfuse_unlink,
520     _PLfuse_rmdir,
521     _PLfuse_symlink,
522     _PLfuse_rename,
523     _PLfuse_link,
524     _PLfuse_chmod,
525     _PLfuse_chown,
526     _PLfuse_truncate,
527     _PLfuse_utime,
528     _PLfuse_open,
529     _PLfuse_read,
530     _PLfuse_write,
531     _PLfuse_statfs
532     };
533    
534     MODULE = Fuse PACKAGE = Fuse
535     PROTOTYPES: DISABLE
536    
537     void
538     perl_fuse_main(...)
539     PREINIT:
540     struct fuse_operations fops = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
541     int i, fd, varnum = 0, debug, have_mnt;
542     char *mountpoint;
543     STRLEN n_a;
544     STRLEN l;
545     INIT:
546     if(items != 20) {
547     fprintf(stderr,"Perl<->C inconsistency or internal error\n");
548     XSRETURN_UNDEF;
549     }
550     CODE:
551     debug = SvIV(ST(0));
552     mountpoint = SvPV_nolen(ST(1));
553     /* FIXME: reevaluate multithreading support when perl6 arrives */
554     for(i=0;i<18;i++) {
555     SV *var = ST(i+2);
556     if((var != &PL_sv_undef) && SvROK(var)) {
557     if(SvTYPE(SvRV(var)) == SVt_PVCV) {
558     void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
559     tmp2[i] = tmp1[i];
560     _PLfuse_callbacks[i] = var;
561     } else
562     croak("arg is not a code reference!");
563     }
564     }
565     /* FIXME: need to pass fusermount arguments */
566     fd = fuse_mount(mountpoint,NULL);
567     if(fd < 0)
568     croak("could not mount fuse filesystem!");
569     fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));

  ViewVC Help
Powered by ViewVC 1.1.26