/[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 19 - (show annotations)
Tue Dec 27 12:47:00 2005 UTC (15 years, 11 months ago) by dpavlin
File size: 17154 byte(s)
Changes from Mark Glines in preparation for 0.07
- Remove the FUSE_DEBUG constant; we never actually implemented
  it to begin with.
- "make test" now uses the version of Fuse you've just built,
  not the one installed in /usr/lib/perl5.
- getattr test now allows blksize to vary between host and fuse
  fs, as this is not a bug.
- Add experimental support for threading.  The following minor
  API changes accommodate this:
- The nonexistent (yet documented) "unthreaded=>1" attribute
  has been replaced with the "threaded=>1" attribute, and this
  time it actually exists.
- Symbolic refs like "main::e_getattr" are now allowed for
  callbacks, because threaded mode needs to share() the
  callbacks, yet perl 5.8.7 does not allow share()ing code
  refs yet.  Direct code-refs are still supported as much
  as possible (currently, non-threaded mode).
- testsuite uses a multithreaded loopback.pl, when available.
- Update docs accordingly.  Update examples accordingly.

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

  ViewVC Help
Powered by ViewVC 1.1.26