/[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 4 - (hide annotations)
Thu Nov 11 14:44:15 2004 UTC (19 years, 4 months ago) by mszeredi
File size: 10934 byte(s)
Initial revision

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

  ViewVC Help
Powered by ViewVC 1.1.26