/[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

Diff of /perl-llin/Fuse.xs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

perl/trunk/Fuse.xs revision 4 by mszeredi, Thu Nov 11 14:44:15 2004 UTC perl-llin/Fuse.xs revision 123 by dpavlin, Wed Mar 19 19:40:20 2008 UTC
# Line 2  Line 2 
2  #include "perl.h"  #include "perl.h"
3  #include "XSUB.h"  #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(); { dSP
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 dSP
28    # define FUSE_CONTEXT_POST
29    #endif
30  #include <fuse.h>  #include <fuse.h>
31    
32  #undef DEBUGf  #undef DEBUGf
33  #if 0  #if 0
34  #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,PL_stack_sp-PL_stack_base ,##a )  #define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,sp-PL_stack_base ,##a )
35  #else  #else
36  #define DEBUGf(a...)  #define DEBUGf(a...)
37  #endif  #endif
38    
39  SV *_PLfuse_callbacks[18];  #define N_CALLBACKS 25
40    SV *_PLfuse_callbacks[N_CALLBACKS];
41    
42  int _PLfuse_getattr(const char *file, struct stat *result) {  int _PLfuse_getattr(const char *file, struct stat *result) {
43          dSP;          int rv;
44          int rv, statcount;          FUSE_CONTEXT_PRE;
45            DEBUGf("getattr begin: %s\n",file);
46          ENTER;          ENTER;
47          SAVETMPS;          SAVETMPS;
48          PUSHMARK(SP);          PUSHMARK(SP);
# Line 32  int _PLfuse_getattr(const char *file, st Line 59  int _PLfuse_getattr(const char *file, st
59                  else                  else
60                          rv = -ENOENT;                          rv = -ENOENT;
61          } else {          } else {
62                    result->st_blocks = POPi;
63                  result->st_blksize = POPi;                  result->st_blksize = POPi;
64                  result->st_ctime = POPi;                  result->st_ctime = POPi;
65                  result->st_mtime = POPi;                  result->st_mtime = POPi;
66                  result->st_atime = POPi;                  result->st_atime = POPi;
67                  /* What the HELL?  Perl says the blockcount is the last argument.                  result->st_size = POPn; // we pop double here to support files larger than 4Gb (long limit)
                  * Everything else says the blockcount is the last argument.  So why  
                  * was it folded into the middle of the list? */  
                 result->st_blocks = POPi;  
                 result->st_size = POPi;  
68                  result->st_rdev = POPi;                  result->st_rdev = POPi;
69                  result->st_gid = POPi;                  result->st_gid = POPi;
70                  result->st_uid = POPi;                  result->st_uid = POPi;
71                  result->st_nlink = POPi;                  result->st_nlink = POPi;
72                  result->st_mode = POPi;                  result->st_mode = POPi;
73                  /*result->st_ino =*/ POPi;                  result->st_ino   = POPi;
74                  result->st_dev = POPi;                  result->st_dev = POPi;
75                  rv = 0;                  rv = 0;
76          }          }
77          FREETMPS;          FREETMPS;
78          LEAVE;          LEAVE;
79          PUTBACK;          PUTBACK;
80            DEBUGf("getattr end: %i\n",rv);
81            FUSE_CONTEXT_POST;
82          return rv;          return rv;
83  }  }
84    
85  int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {  int _PLfuse_readlink(const char *file,char *buf,size_t buflen) {
86          int rv;          int rv;
87          char *rvstr;          FUSE_CONTEXT_PRE;
         dSP;  
         I32 ax;  
88          if(buflen < 1)          if(buflen < 1)
89                  return EINVAL;                  return EINVAL;
90            DEBUGf("readlink begin\n");
91          ENTER;          ENTER;
92          SAVETMPS;          SAVETMPS;
93          PUSHMARK(SP);          PUSHMARK(SP);
# Line 85  int _PLfuse_readlink(const char *file,ch Line 110  int _PLfuse_readlink(const char *file,ch
110          LEAVE;          LEAVE;
111          buf[buflen-1] = 0;          buf[buflen-1] = 0;
112          PUTBACK;          PUTBACK;
113            DEBUGf("readlink end: %i\n",rv);
114            FUSE_CONTEXT_POST;
115          return rv;          return rv;
116  }  }
117    
118    #if 0
119    /*
120     * This doesn't yet work... we alwas get ENOSYS when trying to use readdir().
121     * Well, of course, getdir() is fine as well.
122     */
123     int _PLfuse_readdir(const char *file, void *dirh, fuse_fill_dir_t dirfil, off_t off, struct fuse_file_info *fi) {
124    #endif
125  int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {  int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) {
126          int prv, rv;          int prv, rv;
127          dSP;          FUSE_CONTEXT_PRE;
128            DEBUGf("getdir begin\n");
129          ENTER;          ENTER;
130          SAVETMPS;          SAVETMPS;
131          PUSHMARK(SP);          PUSHMARK(SP);
# Line 101  int _PLfuse_getdir(const char *file, fus Line 136  int _PLfuse_getdir(const char *file, fus
136          if(prv) {          if(prv) {
137                  rv = POPi;                  rv = POPi;
138                  while(--prv)                  while(--prv)
139                          dirfil(dirh,POPp,0);                          dirfil(dirh,POPp,0,0);
140          } else {          } else {
141                  fprintf(stderr,"getdir() handler returned nothing!\n");                  fprintf(stderr,"getdir() handler returned nothing!\n");
142                  rv = -ENOSYS;                  rv = -ENOSYS;
# Line 109  int _PLfuse_getdir(const char *file, fus Line 144  int _PLfuse_getdir(const char *file, fus
144          FREETMPS;          FREETMPS;
145          LEAVE;          LEAVE;
146          PUTBACK;          PUTBACK;
147            DEBUGf("getdir end: %i\n",rv);
148            FUSE_CONTEXT_POST;
149          return rv;          return rv;
150  }  }
151    
152  int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {  int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) {
153          int rv;          int rv;
154          SV *rvsv;          FUSE_CONTEXT_PRE;
155          char *rvstr;          DEBUGf("mknod begin\n");
         dSP;  
156          ENTER;          ENTER;
157          SAVETMPS;          SAVETMPS;
158          PUSHMARK(SP);          PUSHMARK(SP);
# Line 133  int _PLfuse_mknod (const char *file, mod Line 169  int _PLfuse_mknod (const char *file, mod
169          FREETMPS;          FREETMPS;
170          LEAVE;          LEAVE;
171          PUTBACK;          PUTBACK;
172            DEBUGf("mknod end: %i\n",rv);
173            FUSE_CONTEXT_POST;
174          return rv;          return rv;
175  }  }
176    
177  int _PLfuse_mkdir (const char *file, mode_t mode) {  int _PLfuse_mkdir (const char *file, mode_t mode) {
178          int rv;          int rv;
179          SV *rvsv;          FUSE_CONTEXT_PRE;
180          char *rvstr;          DEBUGf("mkdir begin\n");
         dSP;  
         DEBUGf("mkdir begin: %i\n",sp-PL_stack_base);  
181          ENTER;          ENTER;
182          SAVETMPS;          SAVETMPS;
183          PUSHMARK(SP);          PUSHMARK(SP);
# Line 157  int _PLfuse_mkdir (const char *file, mod Line 193  int _PLfuse_mkdir (const char *file, mod
193          FREETMPS;          FREETMPS;
194          LEAVE;          LEAVE;
195          PUTBACK;          PUTBACK;
196          DEBUGf("mkdir end: %i %i\n",sp-PL_stack_base,rv);          DEBUGf("mkdir end: %i\n",rv);
197            FUSE_CONTEXT_POST;
198          return rv;          return rv;
199  }  }
200    
201    
202  int _PLfuse_unlink (const char *file) {  int _PLfuse_unlink (const char *file) {
203          int rv;          int rv;
204          SV *rvsv;          FUSE_CONTEXT_PRE;
205          char *rvstr;          DEBUGf("unlink begin\n");
         dSP;  
         DEBUGf("unlink begin: %i\n",sp-PL_stack_base);  
206          ENTER;          ENTER;
207          SAVETMPS;          SAVETMPS;
208          PUSHMARK(SP);          PUSHMARK(SP);
# Line 182  int _PLfuse_unlink (const char *file) { Line 217  int _PLfuse_unlink (const char *file) {
217          FREETMPS;          FREETMPS;
218          LEAVE;          LEAVE;
219          PUTBACK;          PUTBACK;
220          DEBUGf("unlink end: %i\n",sp-PL_stack_base);          DEBUGf("unlink end: %i\n",rv);
221            FUSE_CONTEXT_POST;
222          return rv;          return rv;
223  }  }
224    
225  int _PLfuse_rmdir (const char *file) {  int _PLfuse_rmdir (const char *file) {
226          int rv;          int rv;
227          SV *rvsv;          FUSE_CONTEXT_PRE;
228          char *rvstr;          DEBUGf("rmdir begin\n");
         dSP;  
         DEBUGf("rmdir begin: %i\n",sp-PL_stack_base);  
229          ENTER;          ENTER;
230          SAVETMPS;          SAVETMPS;
231          PUSHMARK(SP);          PUSHMARK(SP);
# Line 206  int _PLfuse_rmdir (const char *file) { Line 240  int _PLfuse_rmdir (const char *file) {
240          FREETMPS;          FREETMPS;
241          LEAVE;          LEAVE;
242          PUTBACK;          PUTBACK;
243          DEBUGf("rmdir end: %i %i\n",sp-PL_stack_base,rv);          DEBUGf("rmdir end: %i\n",rv);
244            FUSE_CONTEXT_POST;
245          return rv;          return rv;
246  }  }
247    
248  int _PLfuse_symlink (const char *file, const char *new) {  int _PLfuse_symlink (const char *file, const char *new) {
249          int rv;          int rv;
250          SV *rvsv;          FUSE_CONTEXT_PRE;
251          char *rvstr;          DEBUGf("symlink begin\n");
         dSP;  
         DEBUGf("symlink begin: %i\n",sp-PL_stack_base);  
252          ENTER;          ENTER;
253          SAVETMPS;          SAVETMPS;
254          PUSHMARK(SP);          PUSHMARK(SP);
# Line 231  int _PLfuse_symlink (const char *file, c Line 264  int _PLfuse_symlink (const char *file, c
264          FREETMPS;          FREETMPS;
265          LEAVE;          LEAVE;
266          PUTBACK;          PUTBACK;
267          DEBUGf("symlink end: %i\n",sp-PL_stack_base);          DEBUGf("symlink end: %i\n",rv);
268            FUSE_CONTEXT_POST;
269          return rv;          return rv;
270  }  }
271    
272  int _PLfuse_rename (const char *file, const char *new) {  int _PLfuse_rename (const char *file, const char *new) {
273          int rv;          int rv;
274          SV *rvsv;          FUSE_CONTEXT_PRE;
275          char *rvstr;          DEBUGf("rename begin\n");
         dSP;  
         DEBUGf("rename begin: %i\n",sp-PL_stack_base);  
276          ENTER;          ENTER;
277          SAVETMPS;          SAVETMPS;
278          PUSHMARK(SP);          PUSHMARK(SP);
# Line 256  int _PLfuse_rename (const char *file, co Line 288  int _PLfuse_rename (const char *file, co
288          FREETMPS;          FREETMPS;
289          LEAVE;          LEAVE;
290          PUTBACK;          PUTBACK;
291          DEBUGf("rename end: %i\n",sp-PL_stack_base);          DEBUGf("rename end: %i\n",rv);
292            FUSE_CONTEXT_POST;
293          return rv;          return rv;
294  }  }
295    
296  int _PLfuse_link (const char *file, const char *new) {  int _PLfuse_link (const char *file, const char *new) {
297          int rv;          int rv;
298          SV *rvsv;          FUSE_CONTEXT_PRE;
299          char *rvstr;          DEBUGf("link begin\n");
         dSP;  
         DEBUGf("link begin: %i\n",sp-PL_stack_base);  
300          ENTER;          ENTER;
301          SAVETMPS;          SAVETMPS;
302          PUSHMARK(SP);          PUSHMARK(SP);
# Line 281  int _PLfuse_link (const char *file, cons Line 312  int _PLfuse_link (const char *file, cons
312          FREETMPS;          FREETMPS;
313          LEAVE;          LEAVE;
314          PUTBACK;          PUTBACK;
315          DEBUGf("link end: %i\n",sp-PL_stack_base);          DEBUGf("link end: %i\n",rv);
316            FUSE_CONTEXT_POST;
317          return rv;          return rv;
318  }  }
319    
320  int _PLfuse_chmod (const char *file, mode_t mode) {  int _PLfuse_chmod (const char *file, mode_t mode) {
321          int rv;          int rv;
322          SV *rvsv;          FUSE_CONTEXT_PRE;
323          char *rvstr;          DEBUGf("chmod begin\n");
         dSP;  
         DEBUGf("chmod begin: %i\n",sp-PL_stack_base);  
324          ENTER;          ENTER;
325          SAVETMPS;          SAVETMPS;
326          PUSHMARK(SP);          PUSHMARK(SP);
# Line 306  int _PLfuse_chmod (const char *file, mod Line 336  int _PLfuse_chmod (const char *file, mod
336          FREETMPS;          FREETMPS;
337          LEAVE;          LEAVE;
338          PUTBACK;          PUTBACK;
339          DEBUGf("chmod end: %i\n",sp-PL_stack_base);          DEBUGf("chmod end: %i\n",rv);
340            FUSE_CONTEXT_POST;
341          return rv;          return rv;
342  }  }
343    
344  int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {  int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
345          int rv;          int rv;
346          SV *rvsv;          FUSE_CONTEXT_PRE;
347          char *rvstr;          DEBUGf("chown begin\n");
         dSP;  
         DEBUGf("chown begin: %i\n",sp-PL_stack_base);  
348          ENTER;          ENTER;
349          SAVETMPS;          SAVETMPS;
350          PUSHMARK(SP);          PUSHMARK(SP);
# Line 332  int _PLfuse_chown (const char *file, uid Line 361  int _PLfuse_chown (const char *file, uid
361          FREETMPS;          FREETMPS;
362          LEAVE;          LEAVE;
363          PUTBACK;          PUTBACK;
364          DEBUGf("chown end: %i\n",sp-PL_stack_base);          DEBUGf("chown end: %i\n",rv);
365            FUSE_CONTEXT_POST;
366          return rv;          return rv;
367  }  }
368    
369  int _PLfuse_truncate (const char *file, off_t off) {  int _PLfuse_truncate (const char *file, off_t off) {
370          int rv;          int rv;
371          SV *rvsv;          FUSE_CONTEXT_PRE;
372          char *rvstr;          DEBUGf("truncate begin\n");
         dSP;  
         DEBUGf("truncate begin: %i\n",sp-PL_stack_base);  
373          ENTER;          ENTER;
374          SAVETMPS;          SAVETMPS;
375          PUSHMARK(SP);          PUSHMARK(SP);
# Line 357  int _PLfuse_truncate (const char *file, Line 385  int _PLfuse_truncate (const char *file,
385          FREETMPS;          FREETMPS;
386          LEAVE;          LEAVE;
387          PUTBACK;          PUTBACK;
388          DEBUGf("truncate end: %i\n",sp-PL_stack_base);          DEBUGf("truncate end: %i\n",rv);
389            FUSE_CONTEXT_POST;
390          return rv;          return rv;
391  }  }
392    
393  int _PLfuse_utime (const char *file, struct utimbuf *uti) {  int _PLfuse_utime (const char *file, struct utimbuf *uti) {
394          int rv;          int rv;
395          SV *rvsv;          FUSE_CONTEXT_PRE;
396          char *rvstr;          DEBUGf("utime begin\n");
         dSP;  
         DEBUGf("utime begin: %i\n",sp-PL_stack_base);  
397          ENTER;          ENTER;
398          SAVETMPS;          SAVETMPS;
399          PUSHMARK(SP);          PUSHMARK(SP);
# Line 383  int _PLfuse_utime (const char *file, str Line 410  int _PLfuse_utime (const char *file, str
410          FREETMPS;          FREETMPS;
411          LEAVE;          LEAVE;
412          PUTBACK;          PUTBACK;
413          DEBUGf("utime end: %i\n",sp-PL_stack_base);          DEBUGf("utime end: %i\n",rv);
414            FUSE_CONTEXT_POST;
415          return rv;          return rv;
416  }  }
417    
418  int _PLfuse_open (const char *file, int flags) {  int _PLfuse_open (const char *file, struct fuse_file_info *fi) {
419          int rv;          int rv;
420          SV *rvsv;          int flags = fi->flags;
421          char *rvstr;          FUSE_CONTEXT_PRE;
422          dSP;          DEBUGf("open begin\n");
         DEBUGf("open begin: %i\n",sp-PL_stack_base);  
423          ENTER;          ENTER;
424          SAVETMPS;          SAVETMPS;
425          PUSHMARK(SP);          PUSHMARK(SP);
# Line 408  int _PLfuse_open (const char *file, int Line 435  int _PLfuse_open (const char *file, int
435          FREETMPS;          FREETMPS;
436          LEAVE;          LEAVE;
437          PUTBACK;          PUTBACK;
438          DEBUGf("open end: %i %i\n",sp-PL_stack_base,rv);          DEBUGf("open end: %i\n",rv);
439            FUSE_CONTEXT_POST;
440          return rv;          return rv;
441  }  }
442    
443  int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off) {  int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
444          int rv;          int rv;
445          char *rvstr;          FUSE_CONTEXT_PRE;
446          dSP;          DEBUGf("read begin\n");
         DEBUGf("read begin: %i\n",sp-PL_stack_base);  
447          ENTER;          ENTER;
448          SAVETMPS;          SAVETMPS;
449          PUSHMARK(SP);          PUSHMARK(SP);
# Line 447  int _PLfuse_read (const char *file, char Line 474  int _PLfuse_read (const char *file, char
474          FREETMPS;          FREETMPS;
475          LEAVE;          LEAVE;
476          PUTBACK;          PUTBACK;
477          DEBUGf("read end: %i %i\n",sp-PL_stack_base,rv);          DEBUGf("read end: %i\n",rv);
478            FUSE_CONTEXT_POST;
479          return rv;          return rv;
480  }  }
481    
482  int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) {  int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off, struct fuse_file_info *fi) {
483          int rv;          int rv;
484          char *rvstr;          FUSE_CONTEXT_PRE;
485          dSP;          DEBUGf("write begin\n");
         DEBUGf("write begin: %i\n",sp-PL_stack_base);  
486          ENTER;          ENTER;
487          SAVETMPS;          SAVETMPS;
488          PUSHMARK(SP);          PUSHMARK(SP);
# Line 472  int _PLfuse_write (const char *file, con Line 499  int _PLfuse_write (const char *file, con
499          FREETMPS;          FREETMPS;
500          LEAVE;          LEAVE;
501          PUTBACK;          PUTBACK;
502          DEBUGf("write end: %i\n",sp-PL_stack_base);          DEBUGf("write end: %i\n",rv);
503            FUSE_CONTEXT_POST;
504          return rv;          return rv;
505  }  }
506    
507  int _PLfuse_statfs (const char *file, struct statfs *st) {  int _PLfuse_statfs (const char *file, struct statvfs *st) {
508          int rv;          int rv;
509          char *rvstr;          FUSE_CONTEXT_PRE;
510          dSP;          DEBUGf("statfs begin\n");
         DEBUGf("statfs begin: %i\n",sp-PL_stack_base);  
511          ENTER;          ENTER;
512          SAVETMPS;          SAVETMPS;
513          PUSHMARK(SP);          PUSHMARK(SP);
514          PUTBACK;          PUTBACK;
515          rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);          rv = call_sv(_PLfuse_callbacks[17],G_ARRAY);
516          SPAGAIN;          SPAGAIN;
517          if(rv > 5) {          DEBUGf("statfs got %i params\n",rv);
518                  st->f_bsize    = POPi;          if(rv == 6 || rv == 7) {
519                  st->f_bfree    = POPi;                  st->f_bsize     = POPi;
520                  st->f_blocks   = POPi;                  st->f_bfree     = POPi;
521                  st->f_ffree    = POPi;                  st->f_blocks    = POPi;
522                  st->f_files    = POPi;                  st->f_ffree     = POPi;
523                  st->f_namelen  = POPi;                  st->f_files     = POPi;
524                  if(rv > 6)                  st->f_namemax   = POPi;
525                    /* zero and fill-in other */
526                    st->f_fsid = 0;
527                    st->f_frsize = 4096;
528                    st->f_flag = 0;
529                    st->f_bavail = st->f_bfree;
530                    st->f_favail = st->f_ffree;
531    
532                    if(rv == 7)
533                          rv = POPi;                          rv = POPi;
534                  else                  else
535                          rv = 0;                          rv = 0;
# Line 509  int _PLfuse_statfs (const char *file, st Line 544  int _PLfuse_statfs (const char *file, st
544          FREETMPS;          FREETMPS;
545          LEAVE;          LEAVE;
546          PUTBACK;          PUTBACK;
547          DEBUGf("statfs end: %i\n",sp-PL_stack_base);          DEBUGf("statfs end: %i\n",rv);
548            FUSE_CONTEXT_POST;
549            return rv;
550    }
551    
552    int _PLfuse_flush (const char *file, struct fuse_file_info *fi) {
553            int rv;
554            FUSE_CONTEXT_PRE;
555            DEBUGf("flush begin\n");
556            ENTER;
557            SAVETMPS;
558            PUSHMARK(SP);
559            XPUSHs(sv_2mortal(newSVpv(file,0)));
560            PUTBACK;
561            rv = call_sv(_PLfuse_callbacks[18],G_SCALAR);
562            SPAGAIN;
563            if(rv)
564                    rv = POPi;
565            else
566                    rv = 0;
567            FREETMPS;
568            LEAVE;
569            PUTBACK;
570            DEBUGf("flush end: %i\n",rv);
571            FUSE_CONTEXT_POST;
572            return rv;
573    }
574    
575    int _PLfuse_release (const char *file, struct fuse_file_info *fi) {
576            int rv;
577            int flags = fi->flags;
578            FUSE_CONTEXT_PRE;
579            DEBUGf("release begin\n");
580            ENTER;
581            SAVETMPS;
582            PUSHMARK(SP);
583            XPUSHs(sv_2mortal(newSVpv(file,0)));
584            XPUSHs(sv_2mortal(newSViv(flags)));
585            PUTBACK;
586            rv = call_sv(_PLfuse_callbacks[19],G_SCALAR);
587            SPAGAIN;
588            if(rv)
589                    rv = POPi;
590            else
591                    rv = 0;
592            FREETMPS;
593            LEAVE;
594            PUTBACK;
595            DEBUGf("release end: %i\n",rv);
596            FUSE_CONTEXT_POST;
597            return rv;
598    }
599    
600    int _PLfuse_fsync (const char *file, int datasync, struct fuse_file_info *fi) {
601            int rv;
602            int flags = fi->flags;
603            FUSE_CONTEXT_PRE;
604            DEBUGf("fsync begin\n");
605            ENTER;
606            SAVETMPS;
607            PUSHMARK(SP);
608            XPUSHs(sv_2mortal(newSVpv(file,0)));
609            XPUSHs(sv_2mortal(newSViv(flags)));
610            PUTBACK;
611            rv = call_sv(_PLfuse_callbacks[20],G_SCALAR);
612            SPAGAIN;
613            if(rv)
614                    rv = POPi;
615            else
616                    rv = 0;
617            FREETMPS;
618            LEAVE;
619            PUTBACK;
620            DEBUGf("fsync end: %i\n",rv);
621            FUSE_CONTEXT_POST;
622            return rv;
623    }
624    
625    int _PLfuse_setxattr (const char *file, const char *name, const char *buf, size_t buflen, int flags) {
626            int rv;
627            FUSE_CONTEXT_PRE;
628            DEBUGf("setxattr begin\n");
629            ENTER;
630            SAVETMPS;
631            PUSHMARK(SP);
632            XPUSHs(sv_2mortal(newSVpv(file,0)));
633            XPUSHs(sv_2mortal(newSVpv(name,0)));
634            XPUSHs(sv_2mortal(newSVpvn(buf,buflen)));
635            XPUSHs(sv_2mortal(newSViv(flags)));
636            PUTBACK;
637            rv = call_sv(_PLfuse_callbacks[21],G_SCALAR);
638            SPAGAIN;
639            if(rv)
640                    rv = POPi;
641            else
642                    rv = 0;
643            FREETMPS;
644            LEAVE;
645            PUTBACK;
646            DEBUGf("setxattr end: %i\n",rv);
647            FUSE_CONTEXT_POST;
648            return rv;
649    }
650    
651    int _PLfuse_getxattr (const char *file, const char *name, char *buf, size_t buflen) {
652            int rv;
653            FUSE_CONTEXT_PRE;
654            DEBUGf("getxattr begin\n");
655            ENTER;
656            SAVETMPS;
657            PUSHMARK(SP);
658            XPUSHs(sv_2mortal(newSVpv(file,0)));
659            XPUSHs(sv_2mortal(newSVpv(name,0)));
660            PUTBACK;
661            rv = call_sv(_PLfuse_callbacks[22],G_SCALAR);
662            SPAGAIN;
663            if(!rv)
664                    rv = -ENOENT;
665            else {
666                    SV *mysv = POPs;
667    
668                    rv = 0;
669                    if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV)
670                            rv = SvIV(mysv);
671                    else {
672                            if(SvPOK(mysv)) {
673                                    rv = SvCUR(mysv);
674                            } else {
675                                    rv = 0;
676                            }
677                            if ((rv > 0) && (buflen > 0))
678                            {
679                                    if(rv > buflen)
680                                            rv = -ERANGE;
681                                    else
682                                            memcpy(buf,SvPV_nolen(mysv),rv);
683                            }
684                    }
685            }
686            FREETMPS;
687            LEAVE;
688            PUTBACK;
689            DEBUGf("getxattr end: %i\n",rv);
690            FUSE_CONTEXT_POST;
691            return rv;
692    }
693    
694    int _PLfuse_listxattr (const char *file, char *list, size_t size) {
695            int prv, rv;
696            FUSE_CONTEXT_PRE;
697            DEBUGf("listxattr begin\n");
698            ENTER;
699            SAVETMPS;
700            PUSHMARK(SP);
701            XPUSHs(sv_2mortal(newSVpv(file,0)));
702            PUTBACK;
703            prv = call_sv(_PLfuse_callbacks[23],G_ARRAY);
704            SPAGAIN;
705            if(!prv)
706                    rv = -ENOENT;
707            else {
708    
709                    char *p = list;
710                    int spc = size;
711                    int total_len = 0;
712    
713                    rv = POPi;
714                    prv--;
715    
716                    /* Always nul terminate */
717                    if (list && (size > 0))
718                            list[0] = '\0';
719    
720                    while (prv > 0)
721                    {
722                            SV *mysv = POPs;
723                            prv--;
724    
725                            if (SvPOK(mysv)) {
726                                    /* Copy nul too */
727                                    int s = SvCUR(mysv) + 1;
728                                    total_len += s;
729    
730                                    if (p && (size > 0) && (spc >= s))
731                                    {
732                                            memcpy(p,SvPV_nolen(mysv),s);
733                                            p += s;
734                                            spc -= s;
735                                    }
736                            }
737                    }
738    
739                    /*
740                     * If the Perl returned an error, return that.
741                     * Otherwise check that the buffer was big enough.
742                     */
743                    if (rv == 0)
744                    {
745                            rv = total_len;
746                            if ((size > 0) && (size < total_len))
747                                    rv = -ERANGE;
748                    }
749            }
750            FREETMPS;
751            LEAVE;
752            PUTBACK;
753            DEBUGf("listxattr end: %i\n",rv);
754            FUSE_CONTEXT_POST;
755            return rv;
756    }
757    
758    int _PLfuse_removexattr (const char *file, const char *name) {
759            int rv;
760            FUSE_CONTEXT_PRE;
761            DEBUGf("removexattr begin\n");
762            ENTER;
763            SAVETMPS;
764            PUSHMARK(SP);
765            XPUSHs(sv_2mortal(newSVpv(file,0)));
766            XPUSHs(sv_2mortal(newSVpv(name,0)));
767            PUTBACK;
768            rv = call_sv(_PLfuse_callbacks[24],G_SCALAR);
769            SPAGAIN;
770            if(rv)
771                    rv = POPi;
772            else
773                    rv = 0;
774            FREETMPS;
775            LEAVE;
776            PUTBACK;
777            DEBUGf("removexattr end: %i\n",rv);
778            FUSE_CONTEXT_POST;
779          return rv;          return rv;
780  }  }
781    
782  struct fuse_operations _available_ops = {  struct fuse_operations _available_ops = {
783  getattr:        _PLfuse_getattr,  getattr:                _PLfuse_getattr,
784                          _PLfuse_readlink,  readlink:               _PLfuse_readlink,
785                          _PLfuse_getdir,  getdir:                 _PLfuse_getdir,
786                          _PLfuse_mknod,  #if 0
787                          _PLfuse_mkdir,  readdir:                _PLfuse_readdir,
788                          _PLfuse_unlink,  #endif
789                          _PLfuse_rmdir,  mknod:                  _PLfuse_mknod,
790                          _PLfuse_symlink,  mkdir:                  _PLfuse_mkdir,
791                          _PLfuse_rename,  unlink:                 _PLfuse_unlink,
792                          _PLfuse_link,  rmdir:                  _PLfuse_rmdir,
793                          _PLfuse_chmod,  symlink:                _PLfuse_symlink,
794                          _PLfuse_chown,  rename:                 _PLfuse_rename,
795                          _PLfuse_truncate,  link:                   _PLfuse_link,
796                          _PLfuse_utime,  chmod:                  _PLfuse_chmod,
797                          _PLfuse_open,  chown:                  _PLfuse_chown,
798                          _PLfuse_read,  truncate:               _PLfuse_truncate,
799                          _PLfuse_write,  utime:                  _PLfuse_utime,
800                          _PLfuse_statfs  open:                   _PLfuse_open,
801    read:                   _PLfuse_read,
802    write:                  _PLfuse_write,
803    statfs:                 _PLfuse_statfs,
804    flush:                  _PLfuse_flush,
805    release:                _PLfuse_release,
806    fsync:                  _PLfuse_fsync,
807    setxattr:               _PLfuse_setxattr,
808    getxattr:               _PLfuse_getxattr,
809    listxattr:              _PLfuse_listxattr,
810    removexattr:            _PLfuse_removexattr,
811  };  };
812    
813  MODULE = Fuse           PACKAGE = Fuse  MODULE = Fuse           PACKAGE = Fuse
814  PROTOTYPES: DISABLE  PROTOTYPES: DISABLE
815    
816    SV*
817    fuse_get_context()
818            PREINIT:
819            struct fuse_context *fc;
820            CODE:
821            fc = fuse_get_context();
822            if(fc) {
823                    HV *hash = newHV();
824                    hv_store(hash, "uid", 3, newSViv(fc->uid), 0);
825                    hv_store(hash, "gid", 3, newSViv(fc->gid), 0);
826                    hv_store(hash, "pid", 3, newSViv(fc->pid), 0);
827                    RETVAL = newRV_noinc((SV*)hash);
828            } else {
829                    XSRETURN_UNDEF;
830            }
831            OUTPUT:
832            RETVAL
833    
834  void  void
835  perl_fuse_main(...)  perl_fuse_main(...)
836          PREINIT:          PREINIT:
837          struct fuse_operations fops = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};          struct fuse_operations fops =
838          int i, fd, varnum = 0, debug, have_mnt;                  {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
839                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
840            int i, fd, debug, threaded;
841          char *mountpoint;          char *mountpoint;
842          STRLEN n_a;          char *mountopts;
843          STRLEN l;          struct fuse_args margs = FUSE_ARGS_INIT(0, NULL);
844            struct fuse_args fargs = FUSE_ARGS_INIT(0, NULL);
845          INIT:          INIT:
846          if(items != 20) {          if(items != 29) {
847                  fprintf(stderr,"Perl<->C inconsistency or internal error\n");                  fprintf(stderr,"Perl<->C inconsistency or internal error\n");
848                  XSRETURN_UNDEF;                  XSRETURN_UNDEF;
849          }          }
850          CODE:          CODE:
851          debug = SvIV(ST(0));          debug = SvIV(ST(0));
852          mountpoint = SvPV_nolen(ST(1));          threaded = SvIV(ST(1));
853          /* FIXME: reevaluate multithreading support when perl6 arrives */          if(threaded) {
854          for(i=0;i<18;i++) {  #ifdef FUSE_USE_ITHREADS
855                  SV *var = ST(i+2);                  master_interp = PERL_GET_CONTEXT;
856                  if((var != &PL_sv_undef) && SvROK(var)) {  #else
857                          if(SvTYPE(SvRV(var)) == SVt_PVCV) {                  fprintf(stderr,"FUSE warning: Your script has requested multithreaded "
858                                  void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;                                 "mode, but your perl was not built with -Dusethreads.  "
859                                  tmp2[i] = tmp1[i];                                 "Threads are disabled.\n");
860                                  _PLfuse_callbacks[i] = var;                  threaded = 0;
861                          } else  #endif
862                                  croak("arg is not a code reference!");          }
863            mountpoint = SvPV_nolen(ST(2));
864            mountopts = SvPV_nolen(ST(3));
865            for(i=0;i<N_CALLBACKS;i++) {
866                    SV *var = ST(i+4);
867                    /* allow symbolic references, or real code references. */
868                    if(SvOK(var) && (SvPOK(var) || (SvROK(var) && SvTYPE(SvRV(var)) == SVt_PVCV))) {
869                            void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops;
870                            tmp2[i] = tmp1[i];
871    #ifdef FUSE_USE_ITHREADS
872                            if(threaded)
873                    /* note: under 5.8.7, this croaks for code references. */
874                    SvSHARE(var);
875    #endif
876                            _PLfuse_callbacks[i] = var;
877                    } else
878                    if(SvOK(var)) {
879                            croak("invalid callback passed to perl_fuse_main "
880                                  "(%s is not a string, code ref, or undef).\n",
881                                  i+4,SvPVbyte_nolen(var));
882                  }                  }
883          }          }
884          /* FIXME: need to pass fusermount arguments */          /*
885          fd = fuse_mount(mountpoint,NULL);           * XXX: What comes here is just a ridiculous use of the option parsing API
886             * to hack on compatibility with other parts of the new API. First and
887             * foremost, real C argc/argv would be good to get at...
888             */
889            if (mountopts &&
890                (fuse_opt_add_arg(&margs, "") == -1 ||
891                 fuse_opt_add_arg(&margs, "-o") == -1 ||
892                 fuse_opt_add_arg(&margs, mountopts) == -1)) {
893                    fuse_opt_free_args(&margs);
894                    croak("out of memory\n");
895            }
896            fd = fuse_mount(mountpoint,&margs);
897            fuse_opt_free_args(&margs);        
898          if(fd < 0)          if(fd < 0)
899                  croak("could not mount fuse filesystem!");                  croak("could not mount fuse filesystem!\n");
900          fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops));          if (debug) {
901                    if ( fuse_opt_add_arg(&fargs, "") == -1 ||
902                            fuse_opt_add_arg(&fargs, "-d") == -1) {
903                            fuse_opt_free_args(&fargs);
904                            croak("out of memory\n");
905                    }
906            } else {
907                    if (fuse_opt_add_arg(&fargs, "") == -1)
908                            croak("out of memory\n");
909            }
910    
911            if(threaded) {
912                    fuse_loop_mt(fuse_new(fd,&fargs,&fops,sizeof(fops)));
913            } else
914                    fuse_loop(fuse_new(fd,&fargs,&fops,sizeof(fops)));
915            fuse_opt_free_args(&fargs);

Legend:
Removed from v.4  
changed lines
  Added in v.123

  ViewVC Help
Powered by ViewVC 1.1.26