avoid cpan indexing of test::helper
[perl-fuse.git] / Fuse.pm
diff --git a/Fuse.pm b/Fuse.pm
index 1771856..0985ae0 100755 (executable)
--- a/Fuse.pm
+++ b/Fuse.pm
@@ -28,7 +28,7 @@ our %EXPORT_TAGS = (
 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
 
 our @EXPORT = ();
-our $VERSION = '0.14';
+our $VERSION = '0.15';
 
 sub AUTOLOAD {
     # This AUTOLOAD is used to 'autoload' constants from the constant()
@@ -72,17 +72,10 @@ use constant FUSE_IOCTL_MAX_IOV             => 256;
 sub main {
        my @names = qw(getattr readlink getdir mknod mkdir unlink rmdir symlink
                        rename link chmod chown truncate utime open read write statfs
-                       flush release fsync setxattr getxattr listxattr removexattr);
+                       flush release fsync setxattr getxattr listxattr removexattr
+                       opendir readdir releasedir fsyncdir init destroy access
+                       create ftruncate fgetattr lock utimens bmap);
        my $fuse_version = fuse_version();
-       if ($fuse_version >= 2.3) {
-               push(@names, qw/opendir readdir releasedir fsyncdir init destroy/);
-       }
-       if ($fuse_version >= 2.5) {
-               push(@names, qw/access create ftruncate fgetattr/);
-       }
-       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
@@ -96,13 +89,14 @@ sub main {
        my @subs = map {undef} @names;
        my $tmp = 0;
        my %mapping = map { $_ => $tmp++ } @names;
-       my @otherargs = qw(debug threaded mountpoint mountopts nullpath_ok);
+       my @otherargs = qw(debug threaded mountpoint mountopts nullpath_ok utimens_as_array);
        my %otherargs = (
-                         debug         => 0,
-                         threaded      => 0,
-                         mountpoint    => "",
-                         mountopts     => "",
-                         nullpath_ok   => 0,
+                         debug                 => 0,
+                         threaded              => 0,
+                         mountpoint            => "",
+                         mountopts             => "",
+                         nullpath_ok           => 0,
+                         utimens_as_array      => 0,
                        );
        while(my $name = shift) {
                my ($subref) = shift;
@@ -187,27 +181,18 @@ many valid keys.  Most of them correspond with names of callback
 functions, as described in section 'FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT'.
 A few special keys also exist:
 
-
-debug => boolean
-
 =over 1
 
-This turns FUSE call tracing on and off.  Default is 0 (which means off).
-
-=back
+=item debug => boolean
 
-mountpoint => string
+This turns FUSE call tracing on and off.  Default is 0 (which means off).
 
-=over 1
+=item mountpoint => string
 
 The point at which to mount this filesystem.  There is no default, you must
 specify this.  An example would be '/mnt'.
 
-=back
-
-mountopts => string
-
-=over 1
+=item mountopts => string
 
 This is a comma separated list of mount options to pass to the FUSE kernel
 module.
@@ -219,11 +204,7 @@ need 'user_allow_other' in /etc/fuse.conf as per the FUSE documention
   mountopts => "allow_other" or
   mountopts => ""
 
-=back
-
-threaded => boolean
-
-=over 1
+=item threaded => boolean
 
 This turns FUSE multithreading on and off.  The default is 0, meaning your FUSE
 script will run in single-threaded mode.  Note that single-threaded mode also
@@ -247,11 +228,7 @@ you're using are also thread-safe.
 built with USE_ITHREADS, or if you have failed to use threads or
 threads::shared.)
 
-=back
-
-nullpath_ok => boolean
-
-=over 1
+=item nullpath_ok => boolean
 
 This flag tells Fuse to not pass paths for functions that operate on file
 or directory handles. This will yield empty path parameters for functions
@@ -260,6 +237,14 @@ fsyncdir, truncate, fgetattr and lock. If you use this, you must return
 file/directory handles from open, opendir and create. Default is 0 (off).
 Only effective on Fuse 2.8 and up; with earlier versions, this does nothing.
 
+=item utimens_as_array => boolean
+
+This flag causes timestamps passed via the utimens() call to be passed
+as arrays containing the time in seconds, and a second value containing
+the number of nanoseconds, instead of a floating point value. This allows
+for more precise times, as the normal floating point type used by Perl
+(double) loses accuracy starting at about tenths of a microsecond.
+
 =back
 
 =head3 Fuse::fuse_get_context
@@ -348,6 +333,14 @@ Here are the meaning of the fields:
 
 (The epoch was at 00:00 January 1, 1970 GMT.)
 
+If you wish to provide sub-second precision timestamps, they may be
+passed either as the fractional part of a floating-point value, or as a
+two-element array, passed as an array ref, with the first element
+containing the number of seconds since the epoch, and the second
+containing the number of nanoseconds. This provides complete time
+precision, as a floating point number starts losing precision at about
+a tenth of a microsecond. So if you really care about that sort of thing...
+
 =head3 readlink
 
 Arguments:  link pathname.
@@ -468,7 +461,7 @@ No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) will be passed to op
 The fileinfo hash reference contains flags from the Fuse open call which may be modified by the module. The only fields presently supported are:
  direct_io (version 2.4 onwards)
  keep_cache (version 2.4 onwards)
- nonseekable (version 2.9 onwards)
+ nonseekable (version 2.8 onwards)
 Your open() method needs only check if the operation is permitted for the given flags, and return 0 for success.
 Optionally a file handle may be returned, which will be passed to subsequent read, write, flush, fsync and release calls.
 
@@ -516,6 +509,7 @@ is closed. It may be called multiple times before a file is closed.
 =head3 release
 
 Arguments: Pathname, numeric flags passed to open, file handle
+
 Returns an errno or 0 on success.
 
 Called to indicate that there are no more references to the file. Called once
@@ -574,6 +568,8 @@ Arguments: Pathname, extended attribute's name
 
 Returns an errno or 0 on success.
 
+Removes the named extended attribute (if present) from a file.
+
 =head3 opendir
 
 Arguments: Pathname of a directory
@@ -691,10 +687,12 @@ Arguments: Pathname, last accessed time, last modified time
 
 Returns errno or 0 on success
 
-Like utime(), but allows time resolution down to the nanosecond. Currently
-times are passed as "numeric" (internally I believe these are represented
-typically as "long double"), so the sub-second portion is represented as
-fractions of a second.
+Like utime(), but allows time resolution down to the nanosecond. By default,
+times are passed as "numeric" (internally these are typically represented
+as "double"), so the sub-second portion is represented as fractions of a
+second. If you want times passed as arrays instead of floating point
+values, for higher precision, you should pass the C<utimens_as_array> option
+to C<Fuse::main>.
 
 Note that if this call is implemented, it overrides utime() ALWAYS.
 
@@ -711,7 +709,7 @@ option passed.
 
 =head3 ioctl
 
-Arguments: Pathname, (signed) ioctl command code, flags, data if ioctl op is a write, (optional) file handle
+Arguments: Pathname, ioctl command code, flags, data if ioctl op is a write, (optional) file handle
 
 Returns errno or 0 on success, and data if ioctl op is a read
 
@@ -724,7 +722,7 @@ Keep in mind that read and write are from the client perspective, so
 read from our end means data is going *out*, and write means data is
 coming *in*. It can be slightly confusing.
 
-=head1 poll
+=head3 poll
 
 Arguments: Pathname, poll handle ID (or undef if none), event mask, (optional) file handle