/[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 89 - (show annotations)
Tue May 23 14:45:53 2006 UTC (17 years, 10 months ago) by dpavlin
File size: 18157 byte(s)
Vladimir V. Kolpakov contributed cleanup patch
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.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;
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 FUSE_CONTEXT_PRE;
89 dSP;
90 if(buflen < 1)
91 return EINVAL;
92 DEBUGf("readlink begin\n");
93 ENTER;
94 SAVETMPS;
95 PUSHMARK(SP);
96 XPUSHs(sv_2mortal(newSVpv(file,0)));
97 PUTBACK;
98 rv = call_sv(_PLfuse_callbacks[1],G_SCALAR);
99 SPAGAIN;
100 if(!rv)
101 rv = -ENOENT;
102 else {
103 SV *mysv = POPs;
104 if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV)
105 rv = SvIV(mysv);
106 else {
107 strncpy(buf,SvPV_nolen(mysv),buflen);
108 rv = 0;
109 }
110 }
111 FREETMPS;
112 LEAVE;
113 buf[buflen-1] = 0;
114 PUTBACK;
115 DEBUGf("readlink end: %i\n",rv);
116 FUSE_CONTEXT_POST;
117 return rv;
118 }
119
120 #if 0
121 /*
122 * This doesn't yet work... we alwas get ENOSYS when trying to use readdir().
123 * Well, of course, getdir() is fine as well.
124 */
125 int _PLfuse_readdir(const char *file, void *dirh, fuse_fill_dir_t dirfil, off_t off, struct fuse_file_info *fi) {
126 #endif
127 int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
128 int prv, rv;
129 FUSE_CONTEXT_PRE;
130 dSP;
131 DEBUGf("getdir begin\n");
132 ENTER;
133 SAVETMPS;
134 PUSHMARK(SP);
135 XPUSHs(sv_2mortal(newSVpv(file,0)));
136 PUTBACK;
137 prv = call_sv(_PLfuse_callbacks[2],G_ARRAY);
138 SPAGAIN;
139 if(prv) {
140 rv = POPi;
141 while(--prv)
142 dirfil(dirh,POPp,0,0);
143 } else {
144 fprintf(stderr,"getdir() handler returned nothing!\n");
145 rv = -ENOSYS;
146 }
147 FREETMPS;
148 LEAVE;
149 PUTBACK;
150 DEBUGf("getdir end: %i\n",rv);
151 FUSE_CONTEXT_POST;
152 return rv;
153 }
154
155 int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
156 int rv;
157 FUSE_CONTEXT_PRE;
158 dSP;
159 DEBUGf("mknod begin\n");
160 ENTER;
161 SAVETMPS;
162 PUSHMARK(SP);
163 XPUSHs(sv_2mortal(newSVpv(file,0)));
164 XPUSHs(sv_2mortal(newSViv(mode)));
165 XPUSHs(sv_2mortal(newSViv(dev)));
166 PUTBACK;
167 rv = call_sv(_PLfuse_callbacks[3],G_SCALAR);
168 SPAGAIN;
169 if(rv)
170 rv = POPi;
171 else
172 rv = 0;
173 FREETMPS;
174 LEAVE;
175 PUTBACK;
176 DEBUGf("mknod end: %i\n",rv);
177 FUSE_CONTEXT_POST;
178 return rv;
179 }
180
181 int _PLfuse_mkdir (const char *file, mode_t mode) {
182 int rv;
183 FUSE_CONTEXT_PRE;
184 dSP;
185 DEBUGf("mkdir begin\n");
186 ENTER;
187 SAVETMPS;
188 PUSHMARK(SP);
189 XPUSHs(sv_2mortal(newSVpv(file,0)));
190 XPUSHs(sv_2mortal(newSViv(mode)));
191 PUTBACK;
192 rv = call_sv(_PLfuse_callbacks[4],G_SCALAR);
193 SPAGAIN;
194 if(rv)
195 rv = POPi;
196 else
197 rv = 0;
198 FREETMPS;
199 LEAVE;
200 PUTBACK;
201 DEBUGf("mkdir end: %i\n",rv);
202 FUSE_CONTEXT_POST;
203 return rv;
204 }
205
206
207 int _PLfuse_unlink (const char *file) {
208 int rv;
209 FUSE_CONTEXT_PRE;
210 dSP;
211 DEBUGf("unlink begin\n");
212 ENTER;
213 SAVETMPS;
214 PUSHMARK(SP);
215 XPUSHs(sv_2mortal(newSVpv(file,0)));
216 PUTBACK;
217 rv = call_sv(_PLfuse_callbacks[5],G_SCALAR);
218 SPAGAIN;
219 if(rv)
220 rv = POPi;
221 else
222 rv = 0;
223 FREETMPS;
224 LEAVE;
225 PUTBACK;
226 DEBUGf("unlink end: %i\n",rv);
227 FUSE_CONTEXT_POST;
228 return rv;
229 }
230
231 int _PLfuse_rmdir (const char *file) {
232 int rv;
233 FUSE_CONTEXT_PRE;
234 dSP;
235 DEBUGf("rmdir begin\n");
236 ENTER;
237 SAVETMPS;
238 PUSHMARK(SP);
239 XPUSHs(sv_2mortal(newSVpv(file,0)));
240 PUTBACK;
241 rv = call_sv(_PLfuse_callbacks[6],G_SCALAR);
242 SPAGAIN;
243 if(rv)
244 rv = POPi;
245 else
246 rv = 0;
247 FREETMPS;
248 LEAVE;
249 PUTBACK;
250 DEBUGf("rmdir end: %i\n",rv);
251 FUSE_CONTEXT_POST;
252 return rv;
253 }
254
255 int _PLfuse_symlink (const char *file, const char *new) {
256 int rv;
257 FUSE_CONTEXT_PRE;
258 dSP;
259 DEBUGf("symlink begin\n");
260 ENTER;
261 SAVETMPS;
262 PUSHMARK(SP);
263 XPUSHs(sv_2mortal(newSVpv(file,0)));
264 XPUSHs(sv_2mortal(newSVpv(new,0)));
265 PUTBACK;
266 rv = call_sv(_PLfuse_callbacks[7],G_SCALAR);
267 SPAGAIN;
268 if(rv)
269 rv = POPi;
270 else
271 rv = 0;
272 FREETMPS;
273 LEAVE;
274 PUTBACK;
275 DEBUGf("symlink end: %i\n",rv);
276 FUSE_CONTEXT_POST;
277 return rv;
278 }
279
280 int _PLfuse_rename (const char *file, const char *new) {
281 int rv;
282 FUSE_CONTEXT_PRE;
283 dSP;
284 DEBUGf("rename begin\n");
285 ENTER;
286 SAVETMPS;
287 PUSHMARK(SP);
288 XPUSHs(sv_2mortal(newSVpv(file,0)));
289 XPUSHs(sv_2mortal(newSVpv(new,0)));
290 PUTBACK;
291 rv = call_sv(_PLfuse_callbacks[8],G_SCALAR);
292 SPAGAIN;
293 if(rv)
294 rv = POPi;
295 else
296 rv = 0;
297 FREETMPS;
298 LEAVE;
299 PUTBACK;
300 DEBUGf("rename end: %i\n",rv);
301 FUSE_CONTEXT_POST;
302 return rv;
303 }
304
305 int _PLfuse_link (const char *file, const char *new) {
306 int rv;
307 FUSE_CONTEXT_PRE;
308 dSP;
309 DEBUGf("link begin\n");
310 ENTER;
311 SAVETMPS;
312 PUSHMARK(SP);
313 XPUSHs(sv_2mortal(newSVpv(file,0)));
314 XPUSHs(sv_2mortal(newSVpv(new,0)));
315 PUTBACK;
316 rv = call_sv(_PLfuse_callbacks[9],G_SCALAR);
317 SPAGAIN;
318 if(rv)
319 rv = POPi;
320 else
321 rv = 0;
322 FREETMPS;
323 LEAVE;
324 PUTBACK;
325 DEBUGf("link end: %i\n",rv);
326 FUSE_CONTEXT_POST;
327 return rv;
328 }
329
330 int _PLfuse_chmod (const char *file, mode_t mode) {
331 int rv;
332 FUSE_CONTEXT_PRE;
333 dSP;
334 DEBUGf("chmod begin\n");
335 ENTER;
336 SAVETMPS;
337 PUSHMARK(SP);
338 XPUSHs(sv_2mortal(newSVpv(file,0)));
339 XPUSHs(sv_2mortal(newSViv(mode)));
340 PUTBACK;
341 rv = call_sv(_PLfuse_callbacks[10],G_SCALAR);
342 SPAGAIN;
343 if(rv)
344 rv = POPi;
345 else
346 rv = 0;
347 FREETMPS;
348 LEAVE;
349 PUTBACK;
350 DEBUGf("chmod end: %i\n",rv);
351 FUSE_CONTEXT_POST;
352 return rv;
353 }
354
355 int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
356 int rv;
357 FUSE_CONTEXT_PRE;
358 dSP;
359 DEBUGf("chown begin\n");
360 ENTER;
361 SAVETMPS;
362 PUSHMARK(SP);
363 XPUSHs(sv_2mortal(newSVpv(file,0)));
364 XPUSHs(sv_2mortal(newSViv(uid)));
365 XPUSHs(sv_2mortal(newSViv(gid)));
366 PUTBACK;
367 rv = call_sv(_PLfuse_callbacks[11],G_SCALAR);
368 SPAGAIN;
369 if(rv)
370 rv = POPi;
371 else
372 rv = 0;
373 FREETMPS;
374 LEAVE;
375 PUTBACK;
376 DEBUGf("chown end: %i\n",rv);
377 FUSE_CONTEXT_POST;
378 return rv;
379 }
380
381 int _PLfuse_truncate (const char *file, off_t off) {
382 int rv;
383 FUSE_CONTEXT_PRE;
384 dSP;
385 DEBUGf("truncate begin\n");
386 ENTER;
387 SAVETMPS;
388 PUSHMARK(SP);
389 XPUSHs(sv_2mortal(newSVpv(file,0)));
390 XPUSHs(sv_2mortal(newSViv(off)));
391 PUTBACK;
392 rv = call_sv(_PLfuse_callbacks[12],G_SCALAR);
393 SPAGAIN;
394 if(rv)
395 rv = POPi;
396 else
397 rv = 0;
398 FREETMPS;
399 LEAVE;
400 PUTBACK;
401 DEBUGf("truncate end: %i\n",rv);
402 FUSE_CONTEXT_POST;
403 return rv;
404 }
405
406 int _PLfuse_utime (const char *file, struct utimbuf *uti) {
407 int rv;
408 FUSE_CONTEXT_PRE;
409 dSP;
410 DEBUGf("utime begin\n");
411 ENTER;
412 SAVETMPS;
413 PUSHMARK(SP);
414 XPUSHs(sv_2mortal(newSVpv(file,0)));
415 XPUSHs(sv_2mortal(newSViv(uti->actime)));
416 XPUSHs(sv_2mortal(newSViv(uti->modtime)));
417 PUTBACK;
418 rv = call_sv(_PLfuse_callbacks[13],G_SCALAR);
419 SPAGAIN;
420 if(rv)
421 rv = POPi;
422 else
423 rv = 0;
424 FREETMPS;
425 LEAVE;
426 PUTBACK;
427 DEBUGf("utime end: %i\n",rv);
428 FUSE_CONTEXT_POST;
429 return rv;
430 }
431
432 int _PLfuse_open (const char *file, struct fuse_file_info *fi) {
433 int rv;
434 int flags = fi->flags;
435 FUSE_CONTEXT_PRE;
436 dSP;
437 DEBUGf("open begin\n");
438 ENTER;
439 SAVETMPS;
440 PUSHMARK(SP);
441 XPUSHs(sv_2mortal(newSVpv(file,0)));
442 XPUSHs(sv_2mortal(newSViv(flags)));
443 PUTBACK;
444 rv = call_sv(_PLfuse_callbacks[14],G_SCALAR);
445 SPAGAIN;
446 if(rv)
447 rv = POPi;
448 else
449 rv = 0;
450 FREETMPS;
451 LEAVE;
452 PUTBACK;
453 DEBUGf("open end: %i\n",rv);
454 FUSE_CONTEXT_POST;
455 return rv;
456 }
457
458 int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
459 int rv;
460 FUSE_CONTEXT_PRE;
461 dSP;
462 DEBUGf("read begin\n");
463 ENTER;
464 SAVETMPS;
465 PUSHMARK(SP);
466 XPUSHs(sv_2mortal(newSVpv(file,0)));
467 XPUSHs(sv_2mortal(newSViv(buflen)));
468 XPUSHs(sv_2mortal(newSViv(off)));
469 PUTBACK;
470 rv = call_sv(_PLfuse_callbacks[15],G_SCALAR);
471 SPAGAIN;
472 if(!rv)
473 rv = -ENOENT;
474 else {
475 SV *mysv = POPs;
476 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
477 rv = SvIV(mysv);
478 else {
479 if(SvPOK(mysv)) {
480 rv = SvCUR(mysv);
481 } else {
482 rv = 0;
483 }
484 if(rv > buflen)
485 croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
486 if(rv)
487 memcpy(buf,SvPV_nolen(mysv),rv);
488 }
489 }
490 FREETMPS;
491 LEAVE;
492 PUTBACK;
493 DEBUGf("read end: %i\n",rv);
494 FUSE_CONTEXT_POST;
495 return rv;
496 }
497
498 int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
499 int rv;
500 FUSE_CONTEXT_PRE;
501 dSP;
502 DEBUGf("write begin\n");
503 ENTER;
504 SAVETMPS;
505 PUSHMARK(SP);
506 XPUSHs(sv_2mortal(newSVpv(file,0)));
507 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
508 XPUSHs(sv_2mortal(newSViv(off)));
509 PUTBACK;
510 rv = call_sv(_PLfuse_callbacks[16],G_SCALAR);
511 SPAGAIN;
512 if(rv)
513 rv = POPi;
514 else
515 rv = 0;
516 FREETMPS;
517 LEAVE;
518 PUTBACK;
519 DEBUGf("write end: %i\n",rv);
520 FUSE_CONTEXT_POST;
521 return rv;
522 }
523
524 int _PLfuse_statfs (const char *file, struct statvfs *st) {
525 int rv;
526 FUSE_CONTEXT_PRE;
527 dSP;
528 DEBUGf("statfs begin\n");
529 ENTER;
530 SAVETMPS;
531 PUSHMARK(SP);
532 PUTBACK;
533 rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
534 SPAGAIN;
535 DEBUGf("statfs got %i params\n",rv);
536 if(rv == 6 || rv == 7) {
537 st->f_bsize = POPi;
538 st->f_bfree = POPi;
539 st->f_blocks = POPi;
540 st->f_ffree = POPi;
541 st->f_files = POPi;
542 st->f_namemax = POPi;
543 /* zero and fill-in other */
544 st->f_fsid = 0;
545 st->f_frsize = 4096;
546 st->f_flag = 0;
547 st->f_bavail = st->f_bfree;
548 st->f_favail = st->f_ffree;
549
550 if(rv == 7)
551 rv = POPi;
552 else
553 rv = 0;
554 } else
555 if(rv > 1)
556 croak("inappropriate number of returned values from statfs");
557 else
558 if(rv)
559 rv = POPi;
560 else
561 rv = -ENOSYS;
562 FREETMPS;
563 LEAVE;
564 PUTBACK;
565 DEBUGf("statfs end: %i\n",rv);
566 FUSE_CONTEXT_POST;
567 return rv;
568 }
569
570 int _PLfuse_flush (const char *file, struct fuse_file_info *fi) {
571 int rv;
572 FUSE_CONTEXT_PRE;
573 dSP;
574 DEBUGf("flush begin\n");
575 ENTER;
576 SAVETMPS;
577 PUSHMARK(SP);
578 XPUSHs(sv_2mortal(newSVpv(file,0)));
579 PUTBACK;
580 rv = call_sv(_PLfuse_callbacks[18],G_SCALAR);
581 SPAGAIN;
582 if(rv)
583 rv = POPi;
584 else
585 rv = 0;
586 FREETMPS;
587 LEAVE;
588 PUTBACK;
589 DEBUGf("flush end: %i\n",rv);
590 FUSE_CONTEXT_POST;
591 return rv;
592 }
593
594 int _PLfuse_release (const char *file, struct fuse_file_info *fi) {
595 int rv;
596 int flags = fi->flags;
597 FUSE_CONTEXT_PRE;
598 dSP;
599 DEBUGf("release begin\n");
600 ENTER;
601 SAVETMPS;
602 PUSHMARK(SP);
603 XPUSHs(sv_2mortal(newSVpv(file,0)));
604 XPUSHs(sv_2mortal(newSViv(flags)));
605 PUTBACK;
606 rv = call_sv(_PLfuse_callbacks[19],G_SCALAR);
607 SPAGAIN;
608 if(rv)
609 rv = POPi;
610 else
611 rv = 0;
612 FREETMPS;
613 LEAVE;
614 PUTBACK;
615 DEBUGf("release end: %i\n",rv);
616 FUSE_CONTEXT_POST;
617 return rv;
618 }
619
620 int _PLfuse_fsync (const char *file, int datasync, struct fuse_file_info *fi) {
621 int rv;
622 int flags = fi->flags;
623 FUSE_CONTEXT_PRE;
624 dSP;
625 DEBUGf("fsync begin\n");
626 ENTER;
627 SAVETMPS;
628 PUSHMARK(SP);
629 XPUSHs(sv_2mortal(newSVpv(file,0)));
630 XPUSHs(sv_2mortal(newSViv(flags)));
631 PUTBACK;
632 rv = call_sv(_PLfuse_callbacks[20],G_SCALAR);
633 SPAGAIN;
634 if(rv)
635 rv = POPi;
636 else
637 rv = 0;
638 FREETMPS;
639 LEAVE;
640 PUTBACK;
641 DEBUGf("fsync end: %i\n",rv);
642 FUSE_CONTEXT_POST;
643 return rv;
644 }
645
646 int _PLfuse_setxattr (const char *file, const char *name, const char *buf, size_t buflen, int flags) {
647 int rv;
648 FUSE_CONTEXT_PRE;
649 dSP;
650 DEBUGf("setxattr begin\n");
651 ENTER;
652 SAVETMPS;
653 PUSHMARK(SP);
654 XPUSHs(sv_2mortal(newSVpv(file,0)));
655 XPUSHs(sv_2mortal(newSVpv(name,0)));
656 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
657 XPUSHs(sv_2mortal(newSViv(flags)));
658 PUTBACK;
659 rv = call_sv(_PLfuse_callbacks[21],G_SCALAR);
660 SPAGAIN;
661 if(rv)
662 rv = POPi;
663 else
664 rv = 0;
665 FREETMPS;
666 LEAVE;
667 PUTBACK;
668 DEBUGf("setxattr end: %i\n",rv);
669 FUSE_CONTEXT_POST;
670 return rv;
671 }
672
673 int _PLfuse_getxattr (const char *file, const char *name, char *buf, size_t buflen) {
674 int rv;
675 FUSE_CONTEXT_PRE;
676 dSP;
677 DEBUGf("getxattr begin\n");
678 ENTER;
679 SAVETMPS;
680 PUSHMARK(SP);
681 XPUSHs(sv_2mortal(newSVpv(file,0)));
682 XPUSHs(sv_2mortal(newSVpv(name,0)));
683 PUTBACK;
684 rv = call_sv(_PLfuse_callbacks[22],G_SCALAR);
685 SPAGAIN;
686 if(!rv)
687 rv = -ENOENT;
688 else {
689 SV *mysv = POPs;
690
691 rv = 0;
692 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
693 rv = SvIV(mysv);
694 else {
695 if(SvPOK(mysv)) {
696 rv = SvCUR(mysv);
697 } else {
698 rv = 0;
699 }
700 if ((rv > 0) && (buflen > 0))
701 {
702 if(rv > buflen)
703 rv = -ERANGE;
704 else
705 memcpy(buf,SvPV_nolen(mysv),rv);
706 }
707 }
708 }
709 FREETMPS;
710 LEAVE;
711 PUTBACK;
712 DEBUGf("getxattr end: %i\n",rv);
713 FUSE_CONTEXT_POST;
714 return rv;
715 }
716
717 int _PLfuse_listxattr (const char *file, char *list, size_t size) {
718 int prv, rv;
719 FUSE_CONTEXT_PRE;
720 dSP;
721 DEBUGf("listxattr begin\n");
722 ENTER;
723 SAVETMPS;
724 PUSHMARK(SP);
725 XPUSHs(sv_2mortal(newSVpv(file,0)));
726 PUTBACK;
727 prv = call_sv(_PLfuse_callbacks[23],G_ARRAY);
728 SPAGAIN;
729 if(!prv)
730 rv = -ENOENT;
731 else {
732
733 char *p = list;
734 int spc = size;
735 int total_len = 0;
736
737 rv = POPi;
738 prv--;
739
740 /* Always nul terminate */
741 if (list && (size > 0))
742 list[0] = '\0';
743
744 while (prv > 0)
745 {
746 SV *mysv = POPs;
747 prv--;
748
749 if (SvPOK(mysv)) {
750 /* Copy nul too */
751 int s = SvCUR(mysv) + 1;
752 total_len += s;
753
754 if (p && (size > 0) && (spc >= s))
755 {
756 memcpy(p,SvPV_nolen(mysv),s);
757 p += s;
758 spc -= s;
759 }
760 }
761 }
762
763 /*
764 * If the Perl returned an error, return that.
765 * Otherwise check that the buffer was big enough.
766 */
767 if (rv == 0)
768 {
769 rv = total_len;
770 if ((size > 0) && (size < total_len))
771 rv = -ERANGE;
772 }
773 }
774 FREETMPS;
775 LEAVE;
776 PUTBACK;
777 DEBUGf("listxattr end: %i\n",rv);
778 FUSE_CONTEXT_POST;
779 return rv;
780 }
781
782 int _PLfuse_removexattr (const char *file, const char *name) {
783 int rv;
784 FUSE_CONTEXT_PRE;
785 dSP;
786 DEBUGf("removexattr begin\n");
787 ENTER;
788 SAVETMPS;
789 PUSHMARK(SP);
790 XPUSHs(sv_2mortal(newSVpv(file,0)));
791 XPUSHs(sv_2mortal(newSVpv(name,0)));
792 PUTBACK;
793 rv = call_sv(_PLfuse_callbacks[24],G_SCALAR);
794 SPAGAIN;
795 if(rv)
796 rv = POPi;
797 else
798 rv = 0;
799 FREETMPS;
800 LEAVE;
801 PUTBACK;
802 DEBUGf("removexattr end: %i\n",rv);
803 FUSE_CONTEXT_POST;
804 return rv;
805 }
806
807 struct fuse_operations _available_ops = {
808 getattr: _PLfuse_getattr,
809 readlink: _PLfuse_readlink,
810 getdir: _PLfuse_getdir,
811 #if 0
812 readdir: _PLfuse_readdir,
813 #endif
814 mknod: _PLfuse_mknod,
815 mkdir: _PLfuse_mkdir,
816 unlink: _PLfuse_unlink,
817 rmdir: _PLfuse_rmdir,
818 symlink: _PLfuse_symlink,
819 rename: _PLfuse_rename,
820 link: _PLfuse_link,
821 chmod: _PLfuse_chmod,
822 chown: _PLfuse_chown,
823 truncate: _PLfuse_truncate,
824 utime: _PLfuse_utime,
825 open: _PLfuse_open,
826 read: _PLfuse_read,
827 write: _PLfuse_write,
828 statfs: _PLfuse_statfs,
829 flush: _PLfuse_flush,
830 release: _PLfuse_release,
831 fsync: _PLfuse_fsync,
832 setxattr: _PLfuse_setxattr,
833 getxattr: _PLfuse_getxattr,
834 listxattr: _PLfuse_listxattr,
835 removexattr: _PLfuse_removexattr,
836 };
837
838 MODULE = Fuse PACKAGE = Fuse
839 PROTOTYPES: DISABLE
840
841 void
842 perl_fuse_main(...)
843 PREINIT:
844 struct fuse_operations fops =
845 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
846 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
847 int i, fd, debug, threaded;
848 char *mountpoint;
849 char *mountopts;
850 struct fuse_args margs = FUSE_ARGS_INIT(0, NULL);
851 struct fuse_args fargs = FUSE_ARGS_INIT(0, NULL);
852 INIT:
853 if(items != 29) {
854 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
855 XSRETURN_UNDEF;
856 }
857 CODE:
858 debug = SvIV(ST(0));
859 threaded = SvIV(ST(1));
860 if(threaded) {
861 #ifdef FUSE_USE_ITHREADS
862 master_interp = PERL_GET_INTERP;
863 #else
864 fprintf(stderr,"FUSE warning: Your script has requested multithreaded "
865 "mode, but your perl was not built with -Dusethreads. "
866 "Threads are disabled.\n");
867 threaded = 0;
868 #endif
869 }
870 mountpoint = SvPV_nolen(ST(2));
871 mountopts = SvPV_nolen(ST(3));
872 for(i=0;i<N_CALLBACKS;i++) {
873 SV *var = ST(i+4);
874 /* allow symbolic references, or real code references. */
875 if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
876 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
877 tmp2[i] = tmp1[i];
878 #ifdef FUSE_USE_ITHREADS
879 if(threaded)
880 /* note: under 5.8.7, this croaks for code references. */
881 SvSHARE(var);
882 #endif
883 _PLfuse_callbacks[i] = var;
884 } else
885 if(SvOK(var)) {
886 croak("invalid callback passed to perl_fuse_main "
887 "(%s is not a string, code ref, or undef).\n",
888 i+4,SvPVbyte_nolen(var));
889 }
890 }
891 /*
892 * XXX: What comes here is just a ridiculous use of the option parsing API
893 * to hack on compatibility with other parts of the new API. First and
894 * foremost, real C argc/argv would be good to get at...
895 */
896 if (mountopts &&
897 (fuse_opt_add_arg(&margs, "") == -1 ||
898 fuse_opt_add_arg(&margs, "-o") == -1 ||
899 fuse_opt_add_arg(&margs, mountopts) == -1)) {
900 fuse_opt_free_args(&margs);
901 croak("out of memory\n");
902 }
903 fd = fuse_mount(mountpoint,&margs);
904 fuse_opt_free_args(&margs);
905 if(fd < 0)
906 croak("could not mount fuse filesystem!\n");
907 if (debug) {
908 if ( fuse_opt_add_arg(&fargs, "") == -1 ||
909 fuse_opt_add_arg(&fargs, "-d") == -1) {
910 fuse_opt_free_args(&fargs);
911 croak("out of memory\n");
912 }
913 } else {
914 if (fuse_opt_add_arg(&fargs, "") == -1)
915 croak("out of memory\n");
916 }
917
918 if(threaded) {
919 fuse_loop_mt(fuse_new(fd,&fargs,&fops,sizeof(fops)/sizeof(void*)));
920 } else
921 fuse_loop(fuse_new(fd,&fargs,&fops,sizeof(fops)/sizeof(void*)));
922 fuse_opt_free_args(&fargs);

  ViewVC Help
Powered by ViewVC 1.1.26