/[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 8 - (show annotations)
Fri Nov 26 20:38:56 2004 UTC (17 years, 6 months ago) by dpavlin
File size: 10751 byte(s)
It seems that blockcount isn't last argument any longer. Fixed.

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

  ViewVC Help
Powered by ViewVC 1.1.26