Adding FUSE 2.8 specific operation 'ioctl'.
authorDerrik Pates <demon@now.ai>
Mon, 1 Aug 2011 17:51:43 +0000 (11:51 -0600)
committerDerrik Pates <demon@now.ai>
Mon, 1 Aug 2011 17:51:43 +0000 (11:51 -0600)
Not sure if this will actually work yet, but it builds cleanly, and from
my reading of docs and examples, this *seems* like the right way to
implement the ioctl() call wrapper. (I'd already had this mostly
implemented and disabled, but wasn't sure it was ready for prime time.
We'll find out.)

Fuse.pm
Fuse.xs

diff --git a/Fuse.pm b/Fuse.pm
index 49f3588..9a68207 100755 (executable)
--- a/Fuse.pm
+++ b/Fuse.pm
@@ -77,16 +77,17 @@ sub main {
        if ($fuse_version >= 2.6) {
                push(@names, qw/lock utimens bmap/);
        }
-#      if ($fuse_version >= 2.8) {
-#              # junk doesn't contain a function pointer, and hopefully
-#              # never will; it's a "dead" zone in the struct
-#              # fuse_operations where a flag bit is declared. we don't
-#              # need to concern ourselves with it, and it appears any
-#              # arch with a 64 bit pointer will align everything to
-#              # 8 bytes, making the question of pointer alignment for
-#              # the last 2 wrapper functions no big thing.
+       if ($fuse_version >= 2.8) {
+               # junk doesn't contain a function pointer, and hopefully
+               # never will; it's a "dead" zone in the struct
+               # fuse_operations where a flag bit is declared. we don't
+               # need to concern ourselves with it, and it appears any
+               # arch with a 64 bit pointer will align everything to
+               # 8 bytes, making the question of pointer alignment for
+               # the last 2 wrapper functions no big thing.
+               push(@names, qw/junk ioctl/);
 #              push(@names, qw/junk ioctl poll/);
-#      }
+       }
        my @subs = map {undef} @names;
        my $tmp = 0;
        my %mapping = map { $_ => $tmp++ } @names;
diff --git a/Fuse.xs b/Fuse.xs
index 98fcef2..fb73a12 100755 (executable)
--- a/Fuse.xs
+++ b/Fuse.xs
 /* Global Data */
 
 #define MY_CXT_KEY "Fuse::_guts" XS_VERSION
-/* #if FUSE_VERSION >= 28
-# define N_CALLBACKS 41 */
-#if FUSE_VERSION >= 26
+#if FUSE_VERSION >= 28
+# define N_CALLBACKS 40
+/* # define N_CALLBACKS 41 */
+#elif FUSE_VERSION >= 26
 # define N_CALLBACKS 38
 #elif FUSE_VERSION >= 25
 # define N_CALLBACKS 35
@@ -1418,7 +1419,6 @@ int _PLfuse_bmap(const char *file, size_t blocksize, uint64_t *idx) {
 }
 #endif /* FUSE_VERSION >= 26 */
 
-#if 0
 #if FUSE_VERSION >= 28
 int _PLfuse_ioctl(const char *file, int cmd, void *arg,
                   struct fuse_file_info *fi, unsigned int flags, void *data) {
@@ -1430,6 +1430,7 @@ int _PLfuse_ioctl(const char *file, int cmd, void *arg,
        PUSHMARK(SP);
        XPUSHs(sv_2mortal(newSVpv(file,0)));
        XPUSHs(sv_2mortal(newSViv(cmd)));
+    XPUSHs(sv_2mortal(newSViv((uintptr_t)arg)));
        XPUSHs(sv_2mortal(newSViv(flags)));
        if (_IOC_DIR(cmd) & _IOC_READ)
                XPUSHs(sv_2mortal(newSVpvn(data, _IOC_SIZE(cmd))));
@@ -1442,8 +1443,10 @@ int _PLfuse_ioctl(const char *file, int cmd, void *arg,
        if (_IOC_DIR(cmd) & _IOC_WRITE) {
                if (rv == 2) {
                        SV *sv = POPs;
-                       unsigned int len;
+                       size_t len;
                        char *rdata = SvPV(sv, len);
+            rv--;
+
                        if (len > _IOC_SIZE(cmd)) {
                                fprintf(stderr, "ioctl(): returned data was too large for data area\n");
                                rv = -EFBIG;
@@ -1452,8 +1455,6 @@ int _PLfuse_ioctl(const char *file, int cmd, void *arg,
                                memset(data, 0, _IOC_SIZE(cmd));
                                memcpy(data, rdata, len);
                        }
-
-                       rv--;
                }
                else {
                        fprintf(stderr, "ioctl(): ioctl was a write op, but no data was returned from call?\n");
@@ -1470,12 +1471,13 @@ int _PLfuse_ioctl(const char *file, int cmd, void *arg,
        return rv;
 }
 
+#if 0
 int _PLfuse_poll(const char *file, struct fuse_file_info *fi,
                  struct fuse_pollhandle *ph, unsigned *reventsp) {
 
 }
-#endif /* FUSE_VERSION >= 28 */
 #endif
+#endif /* FUSE_VERSION >= 28 */
 
 struct fuse_operations _available_ops = {
 getattr:               _PLfuse_getattr,
@@ -1522,12 +1524,12 @@ lock:                   _PLfuse_lock,
 utimens:               _PLfuse_utimens,
 bmap:                  _PLfuse_bmap,
 #endif /* FUSE_VERSION >= 26 */
-#if 0
 #if FUSE_VERSION >= 28
 ioctl:                 _PLfuse_ioctl,
+#if 0
 poll:                  _PLfuse_poll,
-#endif /* FUSE_VERSION >= 28 */
 #endif
+#endif /* FUSE_VERSION >= 28 */
 };
 
 MODULE = Fuse          PACKAGE = Fuse