/[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

Contents of /perl-llin/Fuse.xs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations)
Mon Jan 2 22:24:03 2006 UTC (16 years, 6 months ago) by dpavlin
File size: 17326 byte(s)
partial fix for statfs (namelen is still broken) [0.07_2]
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #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 #include <fuse/fuse.h>
31
32 #undef DEBUGf
33 #if 0
34 #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,sp-PL_stack_base ,##a )
35 #else
36 #define DEBUGf(a...)
37 #endif
38
39 #define N_CALLBACKS 25
40 SV *_PLfuse_callbacks[N_CALLBACKS];
41
42 int _PLfuse_getattr(const char *file, struct stat *result) {
43 int rv, statcount;
44 FUSE_CONTEXT_PRE;
45 dSP;
46 DEBUGf("getattr begin: %s\n",file);
47 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 result->st_blocks = POPi;
64 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 DEBUGf("getattr end: %i\n",rv);
82 FUSE_CONTEXT_POST;
83 return rv;
84 }
85
86 int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
87 int rv;
88 char *rvstr;
89 I32 ax;
90 FUSE_CONTEXT_PRE;
91 dSP;
92 if(buflen < 1)
93 return EINVAL;
94 DEBUGf("readlink begin\n");
95 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 DEBUGf("readlink end: %i\n",rv);
118 FUSE_CONTEXT_POST;
119 return rv;
120 }
121
122 int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
123 int prv, rv;
124 FUSE_CONTEXT_PRE;
125 dSP;
126 DEBUGf("getdir begin\n");
127 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 dirfil(dirh,POPp,0);
138 } else {
139 fprintf(stderr,"getdir() handler returned nothing!\n");
140 rv = -ENOSYS;
141 }
142 FREETMPS;
143 LEAVE;
144 PUTBACK;
145 DEBUGf("getdir end: %i\n",rv);
146 FUSE_CONTEXT_POST;
147 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 FUSE_CONTEXT_PRE;
155 dSP;
156 DEBUGf("mknod begin\n");
157 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 DEBUGf("mknod end: %i\n",rv);
174 FUSE_CONTEXT_POST;
175 return rv;
176 }
177
178 int _PLfuse_mkdir (const char *file, mode_t mode) {
179 int rv;
180 SV *rvsv;
181 char *rvstr;
182 FUSE_CONTEXT_PRE;
183 dSP;
184 DEBUGf("mkdir begin\n");
185 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 DEBUGf("mkdir end: %i\n",rv);
201 FUSE_CONTEXT_POST;
202 return rv;
203 }
204
205
206 int _PLfuse_unlink (const char *file) {
207 int rv;
208 SV *rvsv;
209 char *rvstr;
210 FUSE_CONTEXT_PRE;
211 dSP;
212 DEBUGf("unlink begin\n");
213 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 DEBUGf("unlink end: %i\n",rv);
228 FUSE_CONTEXT_POST;
229 return rv;
230 }
231
232 int _PLfuse_rmdir (const char *file) {
233 int rv;
234 SV *rvsv;
235 char *rvstr;
236 FUSE_CONTEXT_PRE;
237 dSP;
238 DEBUGf("rmdir begin\n");
239 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 DEBUGf("rmdir end: %i\n",rv);
254 FUSE_CONTEXT_POST;
255 return rv;
256 }
257
258 int _PLfuse_symlink (const char *file, const char *new) {
259 int rv;
260 SV *rvsv;
261 char *rvstr;
262 FUSE_CONTEXT_PRE;
263 dSP;
264 DEBUGf("symlink begin\n");
265 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 DEBUGf("symlink end: %i\n",rv);
281 FUSE_CONTEXT_POST;
282 return rv;
283 }
284
285 int _PLfuse_rename (const char *file, const char *new) {
286 int rv;
287 SV *rvsv;
288 char *rvstr;
289 FUSE_CONTEXT_PRE;
290 dSP;
291 DEBUGf("rename begin\n");
292 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 DEBUGf("rename end: %i\n",rv);
308 FUSE_CONTEXT_POST;
309 return rv;
310 }
311
312 int _PLfuse_link (const char *file, const char *new) {
313 int rv;
314 SV *rvsv;
315 char *rvstr;
316 FUSE_CONTEXT_PRE;
317 dSP;
318 DEBUGf("link begin\n");
319 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 DEBUGf("link end: %i\n",rv);
335 FUSE_CONTEXT_POST;
336 return rv;
337 }
338
339 int _PLfuse_chmod (const char *file, mode_t mode) {
340 int rv;
341 SV *rvsv;
342 char *rvstr;
343 FUSE_CONTEXT_PRE;
344 dSP;
345 DEBUGf("chmod begin\n");
346 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 DEBUGf("chmod end: %i\n",rv);
362 FUSE_CONTEXT_POST;
363 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 FUSE_CONTEXT_PRE;
371 dSP;
372 DEBUGf("chown begin\n");
373 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 DEBUGf("chown end: %i\n",rv);
390 FUSE_CONTEXT_POST;
391 return rv;
392 }
393
394 int _PLfuse_truncate (const char *file, off_t off) {
395 int rv;
396 SV *rvsv;
397 char *rvstr;
398 FUSE_CONTEXT_PRE;
399 dSP;
400 DEBUGf("truncate begin\n");
401 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 DEBUGf("truncate end: %i\n",rv);
417 FUSE_CONTEXT_POST;
418 return rv;
419 }
420
421 int _PLfuse_utime (const char *file, struct utimbuf *uti) {
422 int rv;
423 SV *rvsv;
424 char *rvstr;
425 FUSE_CONTEXT_PRE;
426 dSP;
427 DEBUGf("utime begin\n");
428 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 DEBUGf("utime end: %i\n",rv);
445 FUSE_CONTEXT_POST;
446 return rv;
447 }
448
449 int _PLfuse_open (const char *file, int flags) {
450 int rv;
451 SV *rvsv;
452 char *rvstr;
453 FUSE_CONTEXT_PRE;
454 dSP;
455 DEBUGf("open begin\n");
456 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 DEBUGf("open end: %i\n",rv);
472 FUSE_CONTEXT_POST;
473 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 FUSE_CONTEXT_PRE;
480 dSP;
481 DEBUGf("read begin\n");
482 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 croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
505 if(rv)
506 memcpy(buf,SvPV_nolen(mysv),rv);
507 }
508 }
509 FREETMPS;
510 LEAVE;
511 PUTBACK;
512 DEBUGf("read end: %i\n",rv);
513 FUSE_CONTEXT_POST;
514 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 FUSE_CONTEXT_PRE;
521 dSP;
522 DEBUGf("write begin\n");
523 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 DEBUGf("write end: %i\n",rv);
540 FUSE_CONTEXT_POST;
541 return rv;
542 }
543
544 /* FIXME check for old fuse API (< 21?) and use statfs here */
545 int _PLfuse_statfs (const char *file, struct statvfs *st) {
546 int rv;
547 char *rvstr;
548 FUSE_CONTEXT_PRE;
549 dSP;
550 DEBUGf("statfs begin\n");
551 ENTER;
552 SAVETMPS;
553 PUSHMARK(SP);
554 PUTBACK;
555 rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
556 SPAGAIN;
557 if(rv > 5) {
558 st->f_bsize = POPi;
559 st->f_bfree = st->f_bavail = POPi;
560 st->f_blocks = POPi;
561 st->f_ffree = st->f_favail = POPi;
562 st->f_files = POPi;
563 st->f_namemax = POPi;
564 /* zero all other */
565 st->f_frsize = 4096;
566 st->f_fsid = 0;
567 st->f_flag = 0;
568
569 if(rv > 6)
570 rv = POPi;
571 else
572 rv = 0;
573 } else
574 if(rv > 1)
575 croak("inappropriate number of returned values from statfs");
576 else
577 if(rv)
578 rv = POPi;
579 else
580 rv = -ENOSYS;
581 FREETMPS;
582 LEAVE;
583 PUTBACK;
584 DEBUGf("statfs end: %i\n",rv);
585 FUSE_CONTEXT_POST;
586 return rv;
587 }
588
589 int _PLfuse_flush (const char *file) {
590 int rv;
591 char *rvstr;
592 FUSE_CONTEXT_PRE;
593 dSP;
594 DEBUGf("flush begin\n");
595 ENTER;
596 SAVETMPS;
597 PUSHMARK(SP);
598 XPUSHs(sv_2mortal(newSVpv(file,0)));
599 PUTBACK;
600 rv = call_sv(_PLfuse_callbacks[18],G_SCALAR);
601 SPAGAIN;
602 if(rv)
603 rv = POPi;
604 else
605 rv = 0;
606 FREETMPS;
607 LEAVE;
608 PUTBACK;
609 DEBUGf("flush end: %i\n",rv);
610 FUSE_CONTEXT_POST;
611 return rv;
612 }
613
614 int _PLfuse_release (const char *file, int flags) {
615 int rv;
616 char *rvstr;
617 FUSE_CONTEXT_PRE;
618 dSP;
619 DEBUGf("release begin\n");
620 ENTER;
621 SAVETMPS;
622 PUSHMARK(SP);
623 XPUSHs(sv_2mortal(newSVpv(file,0)));
624 XPUSHs(sv_2mortal(newSViv(flags)));
625 PUTBACK;
626 rv = call_sv(_PLfuse_callbacks[19],G_SCALAR);
627 SPAGAIN;
628 if(rv)
629 rv = POPi;
630 else
631 rv = 0;
632 FREETMPS;
633 LEAVE;
634 PUTBACK;
635 DEBUGf("release end: %i\n",rv);
636 FUSE_CONTEXT_POST;
637 return rv;
638 }
639
640 int _PLfuse_fsync (const char *file, int flags) {
641 int rv;
642 char *rvstr;
643 FUSE_CONTEXT_PRE;
644 dSP;
645 DEBUGf("fsync begin\n");
646 ENTER;
647 SAVETMPS;
648 PUSHMARK(SP);
649 XPUSHs(sv_2mortal(newSVpv(file,0)));
650 XPUSHs(sv_2mortal(newSViv(flags)));
651 PUTBACK;
652 rv = call_sv(_PLfuse_callbacks[20],G_SCALAR);
653 SPAGAIN;
654 if(rv)
655 rv = POPi;
656 else
657 rv = 0;
658 FREETMPS;
659 LEAVE;
660 PUTBACK;
661 DEBUGf("fsync end: %i\n",rv);
662 FUSE_CONTEXT_POST;
663 return rv;
664 }
665
666 int _PLfuse_setxattr (const char *file, const char *name, const char *buf, size_t buflen, int flags) {
667 int rv;
668 char *rvstr;
669 FUSE_CONTEXT_PRE;
670 dSP;
671 DEBUGf("setxattr begin\n");
672 ENTER;
673 SAVETMPS;
674 PUSHMARK(SP);
675 XPUSHs(sv_2mortal(newSVpv(file,0)));
676 XPUSHs(sv_2mortal(newSVpv(name,0)));
677 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
678 XPUSHs(sv_2mortal(newSViv(flags)));
679 PUTBACK;
680 rv = call_sv(_PLfuse_callbacks[21],G_SCALAR);
681 SPAGAIN;
682 if(rv)
683 rv = POPi;
684 else
685 rv = 0;
686 FREETMPS;
687 LEAVE;
688 PUTBACK;
689 DEBUGf("setxattr end: %i\n",rv);
690 FUSE_CONTEXT_POST;
691 return rv;
692 }
693
694 int _PLfuse_getxattr (const char *file, const char *name, char *buf, size_t buflen) {
695 int rv;
696 char *rvstr;
697 FUSE_CONTEXT_PRE;
698 dSP;
699 DEBUGf("getxattr begin\n");
700 ENTER;
701 SAVETMPS;
702 PUSHMARK(SP);
703 XPUSHs(sv_2mortal(newSVpv(file,0)));
704 XPUSHs(sv_2mortal(newSVpv(name,0)));
705 PUTBACK;
706 rv = call_sv(_PLfuse_callbacks[22],G_SCALAR);
707 SPAGAIN;
708 if(!rv)
709 rv = -ENOENT;
710 else {
711 SV *mysv = POPs;
712
713 rv = 0;
714 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
715 rv = SvIV(mysv);
716 else {
717 if(SvPOK(mysv)) {
718 rv = SvCUR(mysv);
719 } else {
720 rv = 0;
721 }
722 if ((rv > 0) && (buflen > 0))
723 {
724 if(rv > buflen)
725 rv = -ERANGE;
726 else
727 memcpy(buf,SvPV_nolen(mysv),rv);
728 }
729 }
730 }
731 FREETMPS;
732 LEAVE;
733 PUTBACK;
734 DEBUGf("getxattr end: %i\n",rv);
735 FUSE_CONTEXT_POST;
736 return rv;
737 }
738
739 int _PLfuse_listxattr (const char *file, char *list, size_t size) {
740 int prv, rv;
741 char *rvstr;
742 FUSE_CONTEXT_PRE;
743 dSP;
744 DEBUGf("listxattr begin\n");
745 ENTER;
746 SAVETMPS;
747 PUSHMARK(SP);
748 XPUSHs(sv_2mortal(newSVpv(file,0)));
749 PUTBACK;
750 prv = call_sv(_PLfuse_callbacks[23],G_ARRAY);
751 SPAGAIN;
752 if(!prv)
753 rv = -ENOENT;
754 else {
755
756 char *p = list;
757 int spc = size;
758 int total_len = 0;
759 int i;
760
761 rv = POPi;
762 prv--;
763
764 /* Always nul terminate */
765 if (list && (size > 0))
766 list[0] = '\0';
767
768 while (prv > 0)
769 {
770 SV *mysv = POPs;
771 prv--;
772
773 if (SvPOK(mysv)) {
774 /* Copy nul too */
775 int s = SvCUR(mysv) + 1;
776 total_len += s;
777
778 if (p && (size > 0) && (spc >= s))
779 {
780 memcpy(p,SvPV_nolen(mysv),s);
781 p += s;
782 spc -= s;
783 }
784 }
785 }
786
787 /*
788 * If the Perl returned an error, return that.
789 * Otherwise check that the buffer was big enough.
790 */
791 if (rv == 0)
792 {
793 rv = total_len;
794 if ((size > 0) && (size < total_len))
795 rv = -ERANGE;
796 }
797 }
798 FREETMPS;
799 LEAVE;
800 PUTBACK;
801 DEBUGf("listxattr end: %i\n",rv);
802 FUSE_CONTEXT_POST;
803 return rv;
804 }
805
806 int _PLfuse_removexattr (const char *file, const char *name) {
807 int rv;
808 char *rvstr;
809 FUSE_CONTEXT_PRE;
810 dSP;
811 DEBUGf("removexattr begin\n");
812 ENTER;
813 SAVETMPS;
814 PUSHMARK(SP);
815 XPUSHs(sv_2mortal(newSVpv(file,0)));
816 XPUSHs(sv_2mortal(newSVpv(name,0)));
817 PUTBACK;
818 rv = call_sv(_PLfuse_callbacks[24],G_SCALAR);
819 SPAGAIN;
820 if(rv)
821 rv = POPi;
822 else
823 rv = 0;
824 FREETMPS;
825 LEAVE;
826 PUTBACK;
827 DEBUGf("removexattr end: %i\n",rv);
828 FUSE_CONTEXT_POST;
829 return rv;
830 }
831
832 struct fuse_operations _available_ops = {
833 getattr: _PLfuse_getattr,
834 readlink: _PLfuse_readlink,
835 getdir: _PLfuse_getdir,
836 mknod: _PLfuse_mknod,
837 mkdir: _PLfuse_mkdir,
838 unlink: _PLfuse_unlink,
839 rmdir: _PLfuse_rmdir,
840 symlink: _PLfuse_symlink,
841 rename: _PLfuse_rename,
842 link: _PLfuse_link,
843 chmod: _PLfuse_chmod,
844 chown: _PLfuse_chown,
845 truncate: _PLfuse_truncate,
846 utime: _PLfuse_utime,
847 open: _PLfuse_open,
848 read: _PLfuse_read,
849 write: _PLfuse_write,
850 statfs: _PLfuse_statfs,
851 flush: _PLfuse_flush,
852 release: _PLfuse_release,
853 fsync: _PLfuse_fsync,
854 setxattr: _PLfuse_setxattr,
855 getxattr: _PLfuse_getxattr,
856 listxattr: _PLfuse_listxattr,
857 removexattr: _PLfuse_removexattr,
858 };
859
860 MODULE = Fuse PACKAGE = Fuse
861 PROTOTYPES: DISABLE
862
863 void
864 perl_fuse_main(...)
865 PREINIT:
866 struct fuse_operations fops =
867 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
868 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
869 int i, fd, varnum = 0, debug, threaded, have_mnt;
870 char *mountpoint;
871 char *mountopts;
872 STRLEN n_a;
873 STRLEN l;
874 INIT:
875 if(items != 29) {
876 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
877 XSRETURN_UNDEF;
878 }
879 CODE:
880 debug = SvIV(ST(0));
881 threaded = SvIV(ST(1));
882 if(threaded) {
883 #ifdef FUSE_USE_ITHREADS
884 master_interp = PERL_GET_INTERP;
885 #else
886 fprintf(stderr,"FUSE warning: Your script has requested multithreaded "
887 "mode, but your perl was not built with -Dusethreads. "
888 "Threads are disabled.\n");
889 threaded = 0;
890 #endif
891 }
892 mountpoint = SvPV_nolen(ST(2));
893 mountopts = SvPV_nolen(ST(3));
894 for(i=0;i<N_CALLBACKS;i++) {
895 SV *var = ST(i+4);
896 /* allow symbolic references, or real code references. */
897 if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
898 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
899 tmp2[i] = tmp1[i];
900 #ifdef FUSE_USE_ITHREADS
901 if(threaded)
902 /* note: under 5.8.7, this croaks for code references. */
903 SvSHARE(var);
904 #endif
905 _PLfuse_callbacks[i] = var;
906 } else
907 if(SvOK(var)) {
908 croak("invalid callback passed to perl_fuse_main "
909 "(%s is not a string, code ref, or undef).\n",
910 i+4,SvPVbyte_nolen(var));
911 }
912 }
913 /* FIXME: need to pass fusermount arguments */
914 fd = fuse_mount(mountpoint,mountopts);
915 if(fd < 0)
916 croak("could not mount fuse filesystem!");
917 if(threaded) {
918 fuse_loop_mt(fuse_new(fd,debug ? "debug" : NULL,&fops));
919 } else
920 fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));

  ViewVC Help
Powered by ViewVC 1.1.26