Lion compat for -lfuse_ino64 hack.
[perl-fuse.git] / examples / fioc.pl
index 3461180..35115d5 100755 (executable)
@@ -1,5 +1,12 @@
 #!/usr/bin/env perl
 
+# fioc.pl: A Perl conversion of the fioc example IOCTL server program
+# from the FUSE distribution. I've endeavored to stay pretty close
+# structure-wise to the C version, while using Perl-specific features.
+# I wrote this to provide a way to verify my ioctl() wrapper
+# implementation would work properly. So far, it seems to, and it will
+# interoperate with the C client as well.
+
 use strict;
 no strict qw(refs);
 
@@ -9,7 +16,7 @@ use threads::shared;
 use Carp;
 local $SIG{'__WARN__'} = \&Carp::cluck;
 
-use Fuse;
+use Fuse qw(:all);
 use Fcntl qw(:mode);
 use POSIX;
 
@@ -22,9 +29,10 @@ use constant FIOC_FILE  => 2;
 
 require 'asm/ioctl.ph';
 
-our %sizeof = ('int' => 4);
-sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'int'); }
-sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'int'); }
+our %sizeof = ('size_t' => length(pack('L!')));
+sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'size_t'); }
+sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'size_t'); }
+sub TCGETS { 0x5401; }
 
 sub fioc_resize {
     my ($size) = @_;
@@ -87,9 +95,7 @@ sub fioc_open {
     my ($path, $flags, $info) = @_;
     print 'called ', (caller(0))[3], "\n";
 
-    if (fioc_file_type($path) != FIOC_NONE) {
-        return 0;
-    }
+    return 0 if fioc_file_type($path) != FIOC_NONE;
     return -&ENOENT;
 }
 
@@ -98,10 +104,7 @@ sub fioc_read {
     print 'called ', (caller(0))[3], "\n";
 
     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
-
-    if ($offset > $fioc_size) {
-        return q{};
-    }
+    return q{} if $offset > $fioc_size;
 
     if ($size > $fioc_size - $offset) {
         $size - $fioc_size - $offset;
@@ -116,10 +119,7 @@ sub fioc_write {
     lock($fioc_buf);
 
     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
-
-    if (fioc_expand($offset + length($data))) {
-        return -&ENOMEM;
-    }
+    return -&ENOMEM if fioc_expand($offset + length($data));
 
     substr($fioc_buf, $offset, length($data), $data);
     return length($data);
@@ -147,20 +147,23 @@ sub fioc_readdir {
 sub fioc_ioctl {
     my ($path, $cmd, $flags, $data) = @_;
     print 'called ', (caller(0))[3], "\n";
-    $cmd = unpack('L', pack('l', $cmd));
 
     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
-
-    return -&ENOSYS if $flags & 0x1;
+    return -&ENOSYS if $flags & FUSE_IOCTL_COMPAT;
 
     if ($cmd == FIOC_GET_SIZE) {
-        return(0, pack('L', $fioc_size));
+        return(0, pack('L!', $fioc_size));
     }
     elsif ($cmd == FIOC_SET_SIZE) {
         lock($fioc_buf);
-        fioc_resize(unpack('L', $data));
+        fioc_resize(unpack('L!', $data));
         return 0;
     }
+    elsif ($cmd == TCGETS) {
+        # perl sends TCGETS as part of calling isatty() on opening a file;
+        # this appears to be a more canonical answer
+        return -&ENOTTY;
+    }
 
     return -&EINVAL;
 }