9 #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,PL_stack_sp-PL_stack_base ,##a )
14 SV *_PLfuse_callbacks[18];
16 int _PLfuse_getattr(const char *file, struct stat *result) {
22 XPUSHs(sv_2mortal(newSVpv(file,strlen(file))));
24 rv = call_sv(_PLfuse_callbacks[0],G_ARRAY);
28 fprintf(stderr,"inappropriate number of returned values from getattr\n");
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;
59 int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
69 XPUSHs(sv_2mortal(newSVpv(file,0)));
71 rv = call_sv(_PLfuse_callbacks[1],G_SCALAR);
77 if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV)
80 strncpy(buf,SvPV_nolen(mysv),buflen);
91 int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
97 XPUSHs(sv_2mortal(newSVpv(file,0)));
99 prv = call_sv(_PLfuse_callbacks[2],G_ARRAY);
104 dirfil(dirh,POPp,0,0);
106 fprintf(stderr,"getdir() handler returned nothing!\n");
115 int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
123 XPUSHs(sv_2mortal(newSVpv(file,0)));
124 XPUSHs(sv_2mortal(newSViv(mode)));
125 XPUSHs(sv_2mortal(newSViv(dev)));
127 rv = call_sv(_PLfuse_callbacks[3],G_SCALAR);
139 int _PLfuse_mkdir (const char *file, mode_t mode) {
144 DEBUGf("mkdir begin: %i\n",sp-PL_stack_base);
148 XPUSHs(sv_2mortal(newSVpv(file,0)));
149 XPUSHs(sv_2mortal(newSViv(mode)));
151 rv = call_sv(_PLfuse_callbacks[4],G_SCALAR);
160 DEBUGf("mkdir end: %i %i\n",sp-PL_stack_base,rv);
165 int _PLfuse_unlink (const char *file) {
170 DEBUGf("unlink begin: %i\n",sp-PL_stack_base);
174 XPUSHs(sv_2mortal(newSVpv(file,0)));
176 rv = call_sv(_PLfuse_callbacks[5],G_SCALAR);
185 DEBUGf("unlink end: %i\n",sp-PL_stack_base);
189 int _PLfuse_rmdir (const char *file) {
194 DEBUGf("rmdir begin: %i\n",sp-PL_stack_base);
198 XPUSHs(sv_2mortal(newSVpv(file,0)));
200 rv = call_sv(_PLfuse_callbacks[6],G_SCALAR);
209 DEBUGf("rmdir end: %i %i\n",sp-PL_stack_base,rv);
213 int _PLfuse_symlink (const char *file, const char *new) {
218 DEBUGf("symlink begin: %i\n",sp-PL_stack_base);
222 XPUSHs(sv_2mortal(newSVpv(file,0)));
223 XPUSHs(sv_2mortal(newSVpv(new,0)));
225 rv = call_sv(_PLfuse_callbacks[7],G_SCALAR);
234 DEBUGf("symlink end: %i\n",sp-PL_stack_base);
238 int _PLfuse_rename (const char *file, const char *new) {
243 DEBUGf("rename begin: %i\n",sp-PL_stack_base);
247 XPUSHs(sv_2mortal(newSVpv(file,0)));
248 XPUSHs(sv_2mortal(newSVpv(new,0)));
250 rv = call_sv(_PLfuse_callbacks[8],G_SCALAR);
259 DEBUGf("rename end: %i\n",sp-PL_stack_base);
263 int _PLfuse_link (const char *file, const char *new) {
268 DEBUGf("link begin: %i\n",sp-PL_stack_base);
272 XPUSHs(sv_2mortal(newSVpv(file,0)));
273 XPUSHs(sv_2mortal(newSVpv(new,0)));
275 rv = call_sv(_PLfuse_callbacks[9],G_SCALAR);
284 DEBUGf("link end: %i\n",sp-PL_stack_base);
288 int _PLfuse_chmod (const char *file, mode_t mode) {
293 DEBUGf("chmod begin: %i\n",sp-PL_stack_base);
297 XPUSHs(sv_2mortal(newSVpv(file,0)));
298 XPUSHs(sv_2mortal(newSViv(mode)));
300 rv = call_sv(_PLfuse_callbacks[10],G_SCALAR);
309 DEBUGf("chmod end: %i\n",sp-PL_stack_base);
313 int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
318 DEBUGf("chown begin: %i\n",sp-PL_stack_base);
322 XPUSHs(sv_2mortal(newSVpv(file,0)));
323 XPUSHs(sv_2mortal(newSViv(uid)));
324 XPUSHs(sv_2mortal(newSViv(gid)));
326 rv = call_sv(_PLfuse_callbacks[11],G_SCALAR);
335 DEBUGf("chown end: %i\n",sp-PL_stack_base);
339 int _PLfuse_truncate (const char *file, off_t off) {
344 DEBUGf("truncate begin: %i\n",sp-PL_stack_base);
348 XPUSHs(sv_2mortal(newSVpv(file,0)));
349 XPUSHs(sv_2mortal(newSViv(off)));
351 rv = call_sv(_PLfuse_callbacks[12],G_SCALAR);
360 DEBUGf("truncate end: %i\n",sp-PL_stack_base);
364 int _PLfuse_utime (const char *file, struct utimbuf *uti) {
369 DEBUGf("utime begin: %i\n",sp-PL_stack_base);
373 XPUSHs(sv_2mortal(newSVpv(file,0)));
374 XPUSHs(sv_2mortal(newSViv(uti->actime)));
375 XPUSHs(sv_2mortal(newSViv(uti->modtime)));
377 rv = call_sv(_PLfuse_callbacks[13],G_SCALAR);
386 DEBUGf("utime end: %i\n",sp-PL_stack_base);
390 int _PLfuse_open (const char *file, int flags) {
395 DEBUGf("open begin: %i\n",sp-PL_stack_base);
399 XPUSHs(sv_2mortal(newSVpv(file,0)));
400 XPUSHs(sv_2mortal(newSViv(flags)));
402 rv = call_sv(_PLfuse_callbacks[14],G_SCALAR);
411 DEBUGf("open end: %i %i\n",sp-PL_stack_base,rv);
415 int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off) {
419 DEBUGf("read begin: %i\n",sp-PL_stack_base);
423 XPUSHs(sv_2mortal(newSVpv(file,0)));
424 XPUSHs(sv_2mortal(newSViv(buflen)));
425 XPUSHs(sv_2mortal(newSViv(off)));
427 rv = call_sv(_PLfuse_callbacks[15],G_SCALAR);
433 if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
442 croak("read() handler returned more than buflen! (%i > %i)",rv,buflen);
444 memcpy(buf,SvPV_nolen(mysv),rv);
450 DEBUGf("read end: %i %i\n",sp-PL_stack_base,rv);
454 int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) {
458 DEBUGf("write begin: %i\n",sp-PL_stack_base);
462 XPUSHs(sv_2mortal(newSVpv(file,0)));
463 XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
464 XPUSHs(sv_2mortal(newSViv(off)));
466 rv = call_sv(_PLfuse_callbacks[16],G_SCALAR);
475 DEBUGf("write end: %i\n",sp-PL_stack_base);
479 int _PLfuse_statfs (const char *file, struct statfs *st) {
483 DEBUGf("statfs begin: %i\n",sp-PL_stack_base);
488 rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
496 st->f_namelen = POPi;
503 croak("inappropriate number of returned values from statfs");
512 DEBUGf("statfs end: %i\n",sp-PL_stack_base);
516 struct fuse_operations _available_ops = {
517 getattr: _PLfuse_getattr,
537 MODULE = Fuse PACKAGE = Fuse
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;
550 fprintf(stderr,"Perl<->C inconsistency or internal error\n");
555 mountpoint = SvPV_nolen(ST(1));
556 /* FIXME: reevaluate multithreading support when perl6 arrives */
559 if((var != &PL_sv_undef) && SvROK(var)) {
560 if(SvTYPE(SvRV(var)) == SVt_PVCV) {
561 void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
563 _PLfuse_callbacks[i] = var;
565 croak("arg is not a code reference!");
568 /* FIXME: need to pass fusermount arguments */
569 fd = fuse_mount(mountpoint,NULL);
571 croak("could not mount fuse filesystem!");
572 fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));