/[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 68 - (show annotations)
Tue Jan 3 16:21:13 2006 UTC (18 years, 2 months ago) by dpavlin
File size: 17532 byte(s)
added __FreeBSD__ compilation fixes
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 1
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 #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 int rv;
553 char *rvstr;
554 FUSE_CONTEXT_PRE;
555 dSP;
556 DEBUGf("statfs begin\n");
557 ENTER;
558 SAVETMPS;
559 PUSHMARK(SP);
560 PUTBACK;
561 rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
562 SPAGAIN;
563 DEBUGf("statfs got %i params\n",rv);
564 if(rv == 6 || rv == 7) {
565 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 st->f_frsize = 4096;
575 st->f_flag = 0;
576 st->f_bavail = st->f_bfree;
577 st->f_favail = st->f_ffree;
578 #endif
579
580 if(rv == 7)
581 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 DEBUGf("statfs end: %i\n",rv);
596 FUSE_CONTEXT_POST;
597 return rv;
598 }
599
600 int _PLfuse_flush (const char *file) {
601 int rv;
602 char *rvstr;
603 FUSE_CONTEXT_PRE;
604 dSP;
605 DEBUGf("flush begin\n");
606 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 DEBUGf("flush end: %i\n",rv);
621 FUSE_CONTEXT_POST;
622 return rv;
623 }
624
625 int _PLfuse_release (const char *file, int flags) {
626 int rv;
627 char *rvstr;
628 FUSE_CONTEXT_PRE;
629 dSP;
630 DEBUGf("release begin\n");
631 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 DEBUGf("release end: %i\n",rv);
647 FUSE_CONTEXT_POST;
648 return rv;
649 }
650
651 int _PLfuse_fsync (const char *file, int flags) {
652 int rv;
653 char *rvstr;
654 FUSE_CONTEXT_PRE;
655 dSP;
656 DEBUGf("fsync begin\n");
657 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 DEBUGf("fsync end: %i\n",rv);
673 FUSE_CONTEXT_POST;
674 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 FUSE_CONTEXT_PRE;
681 dSP;
682 DEBUGf("setxattr begin\n");
683 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 DEBUGf("setxattr end: %i\n",rv);
701 FUSE_CONTEXT_POST;
702 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 FUSE_CONTEXT_PRE;
709 dSP;
710 DEBUGf("getxattr begin\n");
711 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 DEBUGf("getxattr end: %i\n",rv);
746 FUSE_CONTEXT_POST;
747 return rv;
748 }
749
750 int _PLfuse_listxattr (const char *file, char *list, size_t size) {
751 int prv, rv;
752 char *rvstr;
753 FUSE_CONTEXT_PRE;
754 dSP;
755 DEBUGf("listxattr begin\n");
756 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 DEBUGf("listxattr end: %i\n",rv);
813 FUSE_CONTEXT_POST;
814 return rv;
815 }
816
817 int _PLfuse_removexattr (const char *file, const char *name) {
818 int rv;
819 char *rvstr;
820 FUSE_CONTEXT_PRE;
821 dSP;
822 DEBUGf("removexattr begin\n");
823 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 DEBUGf("removexattr end: %i\n",rv);
839 FUSE_CONTEXT_POST;
840 return rv;
841 }
842
843 struct fuse_operations _available_ops = {
844 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 };
870
871 MODULE = Fuse PACKAGE = Fuse
872 PROTOTYPES: DISABLE
873
874 void
875 perl_fuse_main(...)
876 PREINIT:
877 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 int i, fd, varnum = 0, debug, threaded, have_mnt;
881 char *mountpoint;
882 char *mountopts;
883 STRLEN n_a;
884 STRLEN l;
885 INIT:
886 if(items != 29) {
887 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
888 XSRETURN_UNDEF;
889 }
890 CODE:
891 debug = SvIV(ST(0));
892 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 for(i=0;i<N_CALLBACKS;i++) {
906 SV *var = ST(i+4);
907 /* allow symbolic references, or real code references. */
908 if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
909 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
910 tmp2[i] = tmp1[i];
911 #ifdef FUSE_USE_ITHREADS
912 if(threaded)
913 /* note: under 5.8.7, this croaks for code references. */
914 SvSHARE(var);
915 #endif
916 _PLfuse_callbacks[i] = var;
917 } 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 }
923 }
924 /* FIXME: need to pass fusermount arguments */
925 fd = fuse_mount(mountpoint,mountopts);
926 if(fd < 0)
927 croak("could not mount fuse filesystem!");
928 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