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

Contents of /perl/trunk/Fuse.xs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (show annotations)
Mon Jan 2 22:52:22 2006 UTC (18 years, 2 months ago) by dpavlin
File size: 17377 byte(s)
fix 6 and 7 parametar handling

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 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 DEBUGf("statfs got %i params\n",rv);
558 if(rv == 6 || rv == 7) {
559 st->f_bsize = POPi;
560 st->f_bfree = st->f_bavail = POPi;
561 st->f_blocks = POPi;
562 st->f_ffree = st->f_favail = POPi;
563 st->f_files = POPi;
564 st->f_namemax = POPi;
565 /* zero all other */
566 st->f_frsize = 4096;
567 st->f_fsid = 0;
568 st->f_flag = 0;
569
570 if(rv == 7)
571 rv = POPi;
572 else
573 rv = 0;
574 } else
575 if(rv > 1)
576 croak("inappropriate number of returned values from statfs");
577 else
578 if(rv)
579 rv = POPi;
580 else
581 rv = -ENOSYS;
582 FREETMPS;
583 LEAVE;
584 PUTBACK;
585 DEBUGf("statfs end: %i\n",rv);
586 FUSE_CONTEXT_POST;
587 return rv;
588 }
589
590 int _PLfuse_flush (const char *file) {
591 int rv;
592 char *rvstr;
593 FUSE_CONTEXT_PRE;
594 dSP;
595 DEBUGf("flush begin\n");
596 ENTER;
597 SAVETMPS;
598 PUSHMARK(SP);
599 XPUSHs(sv_2mortal(newSVpv(file,0)));
600 PUTBACK;
601 rv = call_sv(_PLfuse_callbacks[18],G_SCALAR);
602 SPAGAIN;
603 if(rv)
604 rv = POPi;
605 else
606 rv = 0;
607 FREETMPS;
608 LEAVE;
609 PUTBACK;
610 DEBUGf("flush end: %i\n",rv);
611 FUSE_CONTEXT_POST;
612 return rv;
613 }
614
615 int _PLfuse_release (const char *file, int flags) {
616 int rv;
617 char *rvstr;
618 FUSE_CONTEXT_PRE;
619 dSP;
620 DEBUGf("release begin\n");
621 ENTER;
622 SAVETMPS;
623 PUSHMARK(SP);
624 XPUSHs(sv_2mortal(newSVpv(file,0)));
625 XPUSHs(sv_2mortal(newSViv(flags)));
626 PUTBACK;
627 rv = call_sv(_PLfuse_callbacks[19],G_SCALAR);
628 SPAGAIN;
629 if(rv)
630 rv = POPi;
631 else
632 rv = 0;
633 FREETMPS;
634 LEAVE;
635 PUTBACK;
636 DEBUGf("release end: %i\n",rv);
637 FUSE_CONTEXT_POST;
638 return rv;
639 }
640
641 int _PLfuse_fsync (const char *file, int flags) {
642 int rv;
643 char *rvstr;
644 FUSE_CONTEXT_PRE;
645 dSP;
646 DEBUGf("fsync begin\n");
647 ENTER;
648 SAVETMPS;
649 PUSHMARK(SP);
650 XPUSHs(sv_2mortal(newSVpv(file,0)));
651 XPUSHs(sv_2mortal(newSViv(flags)));
652 PUTBACK;
653 rv = call_sv(_PLfuse_callbacks[20],G_SCALAR);
654 SPAGAIN;
655 if(rv)
656 rv = POPi;
657 else
658 rv = 0;
659 FREETMPS;
660 LEAVE;
661 PUTBACK;
662 DEBUGf("fsync end: %i\n",rv);
663 FUSE_CONTEXT_POST;
664 return rv;
665 }
666
667 int _PLfuse_setxattr (const char *file, const char *name, const char *buf, size_t buflen, int flags) {
668 int rv;
669 char *rvstr;
670 FUSE_CONTEXT_PRE;
671 dSP;
672 DEBUGf("setxattr begin\n");
673 ENTER;
674 SAVETMPS;
675 PUSHMARK(SP);
676 XPUSHs(sv_2mortal(newSVpv(file,0)));
677 XPUSHs(sv_2mortal(newSVpv(name,0)));
678 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
679 XPUSHs(sv_2mortal(newSViv(flags)));
680 PUTBACK;
681 rv = call_sv(_PLfuse_callbacks[21],G_SCALAR);
682 SPAGAIN;
683 if(rv)
684 rv = POPi;
685 else
686 rv = 0;
687 FREETMPS;
688 LEAVE;
689 PUTBACK;
690 DEBUGf("setxattr end: %i\n",rv);
691 FUSE_CONTEXT_POST;
692 return rv;
693 }
694
695 int _PLfuse_getxattr (const char *file, const char *name, char *buf, size_t buflen) {
696 int rv;
697 char *rvstr;
698 FUSE_CONTEXT_PRE;
699 dSP;
700 DEBUGf("getxattr begin\n");
701 ENTER;
702 SAVETMPS;
703 PUSHMARK(SP);
704 XPUSHs(sv_2mortal(newSVpv(file,0)));
705 XPUSHs(sv_2mortal(newSVpv(name,0)));
706 PUTBACK;
707 rv = call_sv(_PLfuse_callbacks[22],G_SCALAR);
708 SPAGAIN;
709 if(!rv)
710 rv = -ENOENT;
711 else {
712 SV *mysv = POPs;
713
714 rv = 0;
715 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
716 rv = SvIV(mysv);
717 else {
718 if(SvPOK(mysv)) {
719 rv = SvCUR(mysv);
720 } else {
721 rv = 0;
722 }
723 if ((rv > 0) && (buflen > 0))
724 {
725 if(rv > buflen)
726 rv = -ERANGE;
727 else
728 memcpy(buf,SvPV_nolen(mysv),rv);
729 }
730 }
731 }
732 FREETMPS;
733 LEAVE;
734 PUTBACK;
735 DEBUGf("getxattr end: %i\n",rv);
736 FUSE_CONTEXT_POST;
737 return rv;
738 }
739
740 int _PLfuse_listxattr (const char *file, char *list, size_t size) {
741 int prv, rv;
742 char *rvstr;
743 FUSE_CONTEXT_PRE;
744 dSP;
745 DEBUGf("listxattr begin\n");
746 ENTER;
747 SAVETMPS;
748 PUSHMARK(SP);
749 XPUSHs(sv_2mortal(newSVpv(file,0)));
750 PUTBACK;
751 prv = call_sv(_PLfuse_callbacks[23],G_ARRAY);
752 SPAGAIN;
753 if(!prv)
754 rv = -ENOENT;
755 else {
756
757 char *p = list;
758 int spc = size;
759 int total_len = 0;
760 int i;
761
762 rv = POPi;
763 prv--;
764
765 /* Always nul terminate */
766 if (list && (size > 0))
767 list[0] = '\0';
768
769 while (prv > 0)
770 {
771 SV *mysv = POPs;
772 prv--;
773
774 if (SvPOK(mysv)) {
775 /* Copy nul too */
776 int s = SvCUR(mysv) + 1;
777 total_len += s;
778
779 if (p && (size > 0) && (spc >= s))
780 {
781 memcpy(p,SvPV_nolen(mysv),s);
782 p += s;
783 spc -= s;
784 }
785 }
786 }
787
788 /*
789 * If the Perl returned an error, return that.
790 * Otherwise check that the buffer was big enough.
791 */
792 if (rv == 0)
793 {
794 rv = total_len;
795 if ((size > 0) && (size < total_len))
796 rv = -ERANGE;
797 }
798 }
799 FREETMPS;
800 LEAVE;
801 PUTBACK;
802 DEBUGf("listxattr end: %i\n",rv);
803 FUSE_CONTEXT_POST;
804 return rv;
805 }
806
807 int _PLfuse_removexattr (const char *file, const char *name) {
808 int rv;
809 char *rvstr;
810 FUSE_CONTEXT_PRE;
811 dSP;
812 DEBUGf("removexattr begin\n");
813 ENTER;
814 SAVETMPS;
815 PUSHMARK(SP);
816 XPUSHs(sv_2mortal(newSVpv(file,0)));
817 XPUSHs(sv_2mortal(newSVpv(name,0)));
818 PUTBACK;
819 rv = call_sv(_PLfuse_callbacks[24],G_SCALAR);
820 SPAGAIN;
821 if(rv)
822 rv = POPi;
823 else
824 rv = 0;
825 FREETMPS;
826 LEAVE;
827 PUTBACK;
828 DEBUGf("removexattr end: %i\n",rv);
829 FUSE_CONTEXT_POST;
830 return rv;
831 }
832
833 struct fuse_operations _available_ops = {
834 getattr: _PLfuse_getattr,
835 readlink: _PLfuse_readlink,
836 getdir: _PLfuse_getdir,
837 mknod: _PLfuse_mknod,
838 mkdir: _PLfuse_mkdir,
839 unlink: _PLfuse_unlink,
840 rmdir: _PLfuse_rmdir,
841 symlink: _PLfuse_symlink,
842 rename: _PLfuse_rename,
843 link: _PLfuse_link,
844 chmod: _PLfuse_chmod,
845 chown: _PLfuse_chown,
846 truncate: _PLfuse_truncate,
847 utime: _PLfuse_utime,
848 open: _PLfuse_open,
849 read: _PLfuse_read,
850 write: _PLfuse_write,
851 statfs: _PLfuse_statfs,
852 flush: _PLfuse_flush,
853 release: _PLfuse_release,
854 fsync: _PLfuse_fsync,
855 setxattr: _PLfuse_setxattr,
856 getxattr: _PLfuse_getxattr,
857 listxattr: _PLfuse_listxattr,
858 removexattr: _PLfuse_removexattr,
859 };
860
861 MODULE = Fuse PACKAGE = Fuse
862 PROTOTYPES: DISABLE
863
864 void
865 perl_fuse_main(...)
866 PREINIT:
867 struct fuse_operations fops =
868 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
869 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
870 int i, fd, varnum = 0, debug, threaded, have_mnt;
871 char *mountpoint;
872 char *mountopts;
873 STRLEN n_a;
874 STRLEN l;
875 INIT:
876 if(items != 29) {
877 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
878 XSRETURN_UNDEF;
879 }
880 CODE:
881 debug = SvIV(ST(0));
882 threaded = SvIV(ST(1));
883 if(threaded) {
884 #ifdef FUSE_USE_ITHREADS
885 master_interp = PERL_GET_INTERP;
886 #else
887 fprintf(stderr,"FUSE warning: Your script has requested multithreaded "
888 "mode, but your perl was not built with -Dusethreads. "
889 "Threads are disabled.\n");
890 threaded = 0;
891 #endif
892 }
893 mountpoint = SvPV_nolen(ST(2));
894 mountopts = SvPV_nolen(ST(3));
895 for(i=0;i<N_CALLBACKS;i++) {
896 SV *var = ST(i+4);
897 /* allow symbolic references, or real code references. */
898 if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
899 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
900 tmp2[i] = tmp1[i];
901 #ifdef FUSE_USE_ITHREADS
902 if(threaded)
903 /* note: under 5.8.7, this croaks for code references. */
904 SvSHARE(var);
905 #endif
906 _PLfuse_callbacks[i] = var;
907 } else
908 if(SvOK(var)) {
909 croak("invalid callback passed to perl_fuse_main "
910 "(%s is not a string, code ref, or undef).\n",
911 i+4,SvPVbyte_nolen(var));
912 }
913 }
914 /* FIXME: need to pass fusermount arguments */
915 fd = fuse_mount(mountpoint,mountopts);
916 if(fd < 0)
917 croak("could not mount fuse filesystem!");
918 if(threaded) {
919 fuse_loop_mt(fuse_new(fd,debug ? "debug" : NULL,&fops));
920 } else
921 fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));

  ViewVC Help
Powered by ViewVC 1.1.26