/[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 4 - (show annotations)
Thu Nov 11 14:44:15 2004 UTC (19 years, 4 months ago) by mszeredi
File size: 10934 byte(s)
Initial revision

1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <fuse.h>
6
7 #undef DEBUGf
8 #if 0
9 #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,PL_stack_sp-PL_stack_base ,##a )
10 #else
11 #define DEBUGf(a...)
12 #endif
13
14 SV *_PLfuse_callbacks[18];
15
16 int _PLfuse_getattr(const char *file, struct stat *result) {
17 dSP;
18 int rv, statcount;
19 ENTER;
20 SAVETMPS;
21 PUSHMARK(SP);
22 XPUSHs(sv_2mortal(newSVpv(file,strlen(file))));
23 PUTBACK;
24 rv = call_sv(_PLfuse_callbacks[0],G_ARRAY);
25 SPAGAIN;
26 if(rv != 13) {
27 if(rv > 1) {
28 fprintf(stderr,"inappropriate number of returned values from getattr\n");
29 rv = -ENOSYS;
30 } else if(rv)
31 rv = POPi;
32 else
33 rv = -ENOENT;
34 } else {
35 result->st_blksize = POPi;
36 result->st_ctime = POPi;
37 result->st_mtime = POPi;
38 result->st_atime = POPi;
39 /* What the HELL? Perl says the blockcount is the last argument.
40 * Everything else says the blockcount is the last argument. So why
41 * was it folded into the middle of the list? */
42 result->st_blocks = POPi;
43 result->st_size = POPi;
44 result->st_rdev = POPi;
45 result->st_gid = POPi;
46 result->st_uid = POPi;
47 result->st_nlink = POPi;
48 result->st_mode = POPi;
49 /*result->st_ino =*/ POPi;
50 result->st_dev = POPi;
51 rv = 0;
52 }
53 FREETMPS;
54 LEAVE;
55 PUTBACK;
56 return rv;
57 }
58
59 int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
60 int rv;
61 char *rvstr;
62 dSP;
63 I32 ax;
64 if(buflen < 1)
65 return EINVAL;
66 ENTER;
67 SAVETMPS;
68 PUSHMARK(SP);
69 XPUSHs(sv_2mortal(newSVpv(file,0)));
70 PUTBACK;
71 rv = call_sv(_PLfuse_callbacks[1],G_SCALAR);
72 SPAGAIN;
73 if(!rv)
74 rv = -ENOENT;
75 else {
76 SV *mysv = POPs;
77 if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV)
78 rv = SvIV(mysv);
79 else {
80 strncpy(buf,SvPV_nolen(mysv),buflen);
81 rv = 0;
82 }
83 }
84 FREETMPS;
85 LEAVE;
86 buf[buflen-1] = 0;
87 PUTBACK;
88 return rv;
89 }
90
91 int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
92 int prv, rv;
93 dSP;
94 ENTER;
95 SAVETMPS;
96 PUSHMARK(SP);
97 XPUSHs(sv_2mortal(newSVpv(file,0)));
98 PUTBACK;
99 prv = call_sv(_PLfuse_callbacks[2],G_ARRAY);
100 SPAGAIN;
101 if(prv) {
102 rv = POPi;
103 while(--prv)
104 dirfil(dirh,POPp,0);
105 } else {
106 fprintf(stderr,"getdir() handler returned nothing!\n");
107 rv = -ENOSYS;
108 }
109 FREETMPS;
110 LEAVE;
111 PUTBACK;
112 return rv;
113 }
114
115 int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
116 int rv;
117 SV *rvsv;
118 char *rvstr;
119 dSP;
120 ENTER;
121 SAVETMPS;
122 PUSHMARK(SP);
123 XPUSHs(sv_2mortal(newSVpv(file,0)));
124 XPUSHs(sv_2mortal(newSViv(mode)));
125 XPUSHs(sv_2mortal(newSViv(dev)));
126 PUTBACK;
127 rv = call_sv(_PLfuse_callbacks[3],G_SCALAR);
128 SPAGAIN;
129 if(rv)
130 rv = POPi;
131 else
132 rv = 0;
133 FREETMPS;
134 LEAVE;
135 PUTBACK;
136 return rv;
137 }
138
139 int _PLfuse_mkdir (const char *file, mode_t mode) {
140 int rv;
141 SV *rvsv;
142 char *rvstr;
143 dSP;
144 DEBUGf("mkdir begin: %i\n",sp-PL_stack_base);
145 ENTER;
146 SAVETMPS;
147 PUSHMARK(SP);
148 XPUSHs(sv_2mortal(newSVpv(file,0)));
149 XPUSHs(sv_2mortal(newSViv(mode)));
150 PUTBACK;
151 rv = call_sv(_PLfuse_callbacks[4],G_SCALAR);
152 SPAGAIN;
153 if(rv)
154 rv = POPi;
155 else
156 rv = 0;
157 FREETMPS;
158 LEAVE;
159 PUTBACK;
160 DEBUGf("mkdir end: %i %i\n",sp-PL_stack_base,rv);
161 return rv;
162 }
163
164
165 int _PLfuse_unlink (const char *file) {
166 int rv;
167 SV *rvsv;
168 char *rvstr;
169 dSP;
170 DEBUGf("unlink begin: %i\n",sp-PL_stack_base);
171 ENTER;
172 SAVETMPS;
173 PUSHMARK(SP);
174 XPUSHs(sv_2mortal(newSVpv(file,0)));
175 PUTBACK;
176 rv = call_sv(_PLfuse_callbacks[5],G_SCALAR);
177 SPAGAIN;
178 if(rv)
179 rv = POPi;
180 else
181 rv = 0;
182 FREETMPS;
183 LEAVE;
184 PUTBACK;
185 DEBUGf("unlink end: %i\n",sp-PL_stack_base);
186 return rv;
187 }
188
189 int _PLfuse_rmdir (const char *file) {
190 int rv;
191 SV *rvsv;
192 char *rvstr;
193 dSP;
194 DEBUGf("rmdir begin: %i\n",sp-PL_stack_base);
195 ENTER;
196 SAVETMPS;
197 PUSHMARK(SP);
198 XPUSHs(sv_2mortal(newSVpv(file,0)));
199 PUTBACK;
200 rv = call_sv(_PLfuse_callbacks[6],G_SCALAR);
201 SPAGAIN;
202 if(rv)
203 rv = POPi;
204 else
205 rv = 0;
206 FREETMPS;
207 LEAVE;
208 PUTBACK;
209 DEBUGf("rmdir end: %i %i\n",sp-PL_stack_base,rv);
210 return rv;
211 }
212
213 int _PLfuse_symlink (const char *file, const char *new) {
214 int rv;
215 SV *rvsv;
216 char *rvstr;
217 dSP;
218 DEBUGf("symlink begin: %i\n",sp-PL_stack_base);
219 ENTER;
220 SAVETMPS;
221 PUSHMARK(SP);
222 XPUSHs(sv_2mortal(newSVpv(file,0)));
223 XPUSHs(sv_2mortal(newSVpv(new,0)));
224 PUTBACK;
225 rv = call_sv(_PLfuse_callbacks[7],G_SCALAR);
226 SPAGAIN;
227 if(rv)
228 rv = POPi;
229 else
230 rv = 0;
231 FREETMPS;
232 LEAVE;
233 PUTBACK;
234 DEBUGf("symlink end: %i\n",sp-PL_stack_base);
235 return rv;
236 }
237
238 int _PLfuse_rename (const char *file, const char *new) {
239 int rv;
240 SV *rvsv;
241 char *rvstr;
242 dSP;
243 DEBUGf("rename begin: %i\n",sp-PL_stack_base);
244 ENTER;
245 SAVETMPS;
246 PUSHMARK(SP);
247 XPUSHs(sv_2mortal(newSVpv(file,0)));
248 XPUSHs(sv_2mortal(newSVpv(new,0)));
249 PUTBACK;
250 rv = call_sv(_PLfuse_callbacks[8],G_SCALAR);
251 SPAGAIN;
252 if(rv)
253 rv = POPi;
254 else
255 rv = 0;
256 FREETMPS;
257 LEAVE;
258 PUTBACK;
259 DEBUGf("rename end: %i\n",sp-PL_stack_base);
260 return rv;
261 }
262
263 int _PLfuse_link (const char *file, const char *new) {
264 int rv;
265 SV *rvsv;
266 char *rvstr;
267 dSP;
268 DEBUGf("link begin: %i\n",sp-PL_stack_base);
269 ENTER;
270 SAVETMPS;
271 PUSHMARK(SP);
272 XPUSHs(sv_2mortal(newSVpv(file,0)));
273 XPUSHs(sv_2mortal(newSVpv(new,0)));
274 PUTBACK;
275 rv = call_sv(_PLfuse_callbacks[9],G_SCALAR);
276 SPAGAIN;
277 if(rv)
278 rv = POPi;
279 else
280 rv = 0;
281 FREETMPS;
282 LEAVE;
283 PUTBACK;
284 DEBUGf("link end: %i\n",sp-PL_stack_base);
285 return rv;
286 }
287
288 int _PLfuse_chmod (const char *file, mode_t mode) {
289 int rv;
290 SV *rvsv;
291 char *rvstr;
292 dSP;
293 DEBUGf("chmod begin: %i\n",sp-PL_stack_base);
294 ENTER;
295 SAVETMPS;
296 PUSHMARK(SP);
297 XPUSHs(sv_2mortal(newSVpv(file,0)));
298 XPUSHs(sv_2mortal(newSViv(mode)));
299 PUTBACK;
300 rv = call_sv(_PLfuse_callbacks[10],G_SCALAR);
301 SPAGAIN;
302 if(rv)
303 rv = POPi;
304 else
305 rv = 0;
306 FREETMPS;
307 LEAVE;
308 PUTBACK;
309 DEBUGf("chmod end: %i\n",sp-PL_stack_base);
310 return rv;
311 }
312
313 int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
314 int rv;
315 SV *rvsv;
316 char *rvstr;
317 dSP;
318 DEBUGf("chown begin: %i\n",sp-PL_stack_base);
319 ENTER;
320 SAVETMPS;
321 PUSHMARK(SP);
322 XPUSHs(sv_2mortal(newSVpv(file,0)));
323 XPUSHs(sv_2mortal(newSViv(uid)));
324 XPUSHs(sv_2mortal(newSViv(gid)));
325 PUTBACK;
326 rv = call_sv(_PLfuse_callbacks[11],G_SCALAR);
327 SPAGAIN;
328 if(rv)
329 rv = POPi;
330 else
331 rv = 0;
332 FREETMPS;
333 LEAVE;
334 PUTBACK;
335 DEBUGf("chown end: %i\n",sp-PL_stack_base);
336 return rv;
337 }
338
339 int _PLfuse_truncate (const char *file, off_t off) {
340 int rv;
341 SV *rvsv;
342 char *rvstr;
343 dSP;
344 DEBUGf("truncate begin: %i\n",sp-PL_stack_base);
345 ENTER;
346 SAVETMPS;
347 PUSHMARK(SP);
348 XPUSHs(sv_2mortal(newSVpv(file,0)));
349 XPUSHs(sv_2mortal(newSViv(off)));
350 PUTBACK;
351 rv = call_sv(_PLfuse_callbacks[12],G_SCALAR);
352 SPAGAIN;
353 if(rv)
354 rv = POPi;
355 else
356 rv = 0;
357 FREETMPS;
358 LEAVE;
359 PUTBACK;
360 DEBUGf("truncate end: %i\n",sp-PL_stack_base);
361 return rv;
362 }
363
364 int _PLfuse_utime (const char *file, struct utimbuf *uti) {
365 int rv;
366 SV *rvsv;
367 char *rvstr;
368 dSP;
369 DEBUGf("utime begin: %i\n",sp-PL_stack_base);
370 ENTER;
371 SAVETMPS;
372 PUSHMARK(SP);
373 XPUSHs(sv_2mortal(newSVpv(file,0)));
374 XPUSHs(sv_2mortal(newSViv(uti->actime)));
375 XPUSHs(sv_2mortal(newSViv(uti->modtime)));
376 PUTBACK;
377 rv = call_sv(_PLfuse_callbacks[13],G_SCALAR);
378 SPAGAIN;
379 if(rv)
380 rv = POPi;
381 else
382 rv = 0;
383 FREETMPS;
384 LEAVE;
385 PUTBACK;
386 DEBUGf("utime end: %i\n",sp-PL_stack_base);
387 return rv;
388 }
389
390 int _PLfuse_open (const char *file, int flags) {
391 int rv;
392 SV *rvsv;
393 char *rvstr;
394 dSP;
395 DEBUGf("open begin: %i\n",sp-PL_stack_base);
396 ENTER;
397 SAVETMPS;
398 PUSHMARK(SP);
399 XPUSHs(sv_2mortal(newSVpv(file,0)));
400 XPUSHs(sv_2mortal(newSViv(flags)));
401 PUTBACK;
402 rv = call_sv(_PLfuse_callbacks[14],G_SCALAR);
403 SPAGAIN;
404 if(rv)
405 rv = POPi;
406 else
407 rv = 0;
408 FREETMPS;
409 LEAVE;
410 PUTBACK;
411 DEBUGf("open end: %i %i\n",sp-PL_stack_base,rv);
412 return rv;
413 }
414
415 int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off) {
416 int rv;
417 char *rvstr;
418 dSP;
419 DEBUGf("read begin: %i\n",sp-PL_stack_base);
420 ENTER;
421 SAVETMPS;
422 PUSHMARK(SP);
423 XPUSHs(sv_2mortal(newSVpv(file,0)));
424 XPUSHs(sv_2mortal(newSViv(buflen)));
425 XPUSHs(sv_2mortal(newSViv(off)));
426 PUTBACK;
427 rv = call_sv(_PLfuse_callbacks[15],G_SCALAR);
428 SPAGAIN;
429 if(!rv)
430 rv = -ENOENT;
431 else {
432 SV *mysv = POPs;
433 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
434 rv = SvIV(mysv);
435 else {
436 if(SvPOK(mysv)) {
437 rv = SvCUR(mysv);
438 } else {
439 rv = 0;
440 }
441 if(rv > buflen)
442 croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
443 if(rv)
444 memcpy(buf,SvPV_nolen(mysv),rv);
445 }
446 }
447 FREETMPS;
448 LEAVE;
449 PUTBACK;
450 DEBUGf("read end: %i %i\n",sp-PL_stack_base,rv);
451 return rv;
452 }
453
454 int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) {
455 int rv;
456 char *rvstr;
457 dSP;
458 DEBUGf("write begin: %i\n",sp-PL_stack_base);
459 ENTER;
460 SAVETMPS;
461 PUSHMARK(SP);
462 XPUSHs(sv_2mortal(newSVpv(file,0)));
463 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
464 XPUSHs(sv_2mortal(newSViv(off)));
465 PUTBACK;
466 rv = call_sv(_PLfuse_callbacks[16],G_SCALAR);
467 SPAGAIN;
468 if(rv)
469 rv = POPi;
470 else
471 rv = 0;
472 FREETMPS;
473 LEAVE;
474 PUTBACK;
475 DEBUGf("write end: %i\n",sp-PL_stack_base);
476 return rv;
477 }
478
479 int _PLfuse_statfs (const char *file, struct statfs *st) {
480 int rv;
481 char *rvstr;
482 dSP;
483 DEBUGf("statfs begin: %i\n",sp-PL_stack_base);
484 ENTER;
485 SAVETMPS;
486 PUSHMARK(SP);
487 PUTBACK;
488 rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
489 SPAGAIN;
490 if(rv > 5) {
491 st->f_bsize = POPi;
492 st->f_bfree = POPi;
493 st->f_blocks = POPi;
494 st->f_ffree = POPi;
495 st->f_files = POPi;
496 st->f_namelen = POPi;
497 if(rv > 6)
498 rv = POPi;
499 else
500 rv = 0;
501 } else
502 if(rv > 1)
503 croak("inappropriate number of returned values from statfs");
504 else
505 if(rv)
506 rv = POPi;
507 else
508 rv = -ENOSYS;
509 FREETMPS;
510 LEAVE;
511 PUTBACK;
512 DEBUGf("statfs end: %i\n",sp-PL_stack_base);
513 return rv;
514 }
515
516 struct fuse_operations _available_ops = {
517 getattr: _PLfuse_getattr,
518 _PLfuse_readlink,
519 _PLfuse_getdir,
520 _PLfuse_mknod,
521 _PLfuse_mkdir,
522 _PLfuse_unlink,
523 _PLfuse_rmdir,
524 _PLfuse_symlink,
525 _PLfuse_rename,
526 _PLfuse_link,
527 _PLfuse_chmod,
528 _PLfuse_chown,
529 _PLfuse_truncate,
530 _PLfuse_utime,
531 _PLfuse_open,
532 _PLfuse_read,
533 _PLfuse_write,
534 _PLfuse_statfs
535 };
536
537 MODULE = Fuse PACKAGE = Fuse
538 PROTOTYPES: DISABLE
539
540 void
541 perl_fuse_main(...)
542 PREINIT:
543 struct fuse_operations fops = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
544 int i, fd, varnum = 0, debug, have_mnt;
545 char *mountpoint;
546 STRLEN n_a;
547 STRLEN l;
548 INIT:
549 if(items != 20) {
550 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
551 XSRETURN_UNDEF;
552 }
553 CODE:
554 debug = SvIV(ST(0));
555 mountpoint = SvPV_nolen(ST(1));
556 /* FIXME: reevaluate multithreading support when perl6 arrives */
557 for(i=0;i<18;i++) {
558 SV *var = ST(i+2);
559 if((var != &PL_sv_undef) && SvROK(var)) {
560 if(SvTYPE(SvRV(var)) == SVt_PVCV) {
561 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
562 tmp2[i] = tmp1[i];
563 _PLfuse_callbacks[i] = var;
564 } else
565 croak("arg is not a code reference!");
566 }
567 }
568 /* FIXME: need to pass fusermount arguments */
569 fd = fuse_mount(mountpoint,NULL);
570 if(fd < 0)
571 croak("could not mount fuse filesystem!");
572 fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));

  ViewVC Help
Powered by ViewVC 1.1.26