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

  ViewVC Help
Powered by ViewVC 1.1.26