Fuse-Simple
view release on metacpan or search on metacpan
lib/Fuse/Simple.pm view on Meta::CPAN
Includes:
fs_not_imp fs_flush fs_getattr fs_getdir fs_open fs_read
fs_readlink fs_release fs_statfs fs_truncate fs_write
=back
=begin testing
BEGIN { use_ok( 'Fuse::Simple', qw(:usual :debug :tools :filesys)); }
=end testing
=cut
######################################################################
# Some useful stuff
######################################################################
our $debug = 0; # can be set if you really really need it to be
my $ctime = time();
my $uid = $>;
my $gid = $) + 0;
our $fs = {
# "empty" dir by default
"README" => "You forgot to pass a '/' parameter to Fuse::Simple::main!\n"
};
######################################################################
=head1 MAIN FUNCTION
=over
=item B<main>(B<arg> => I<value>, ...)
Mount your filesystem, and probably never return. Arguments are:
=over
=item B<mountpoint> => I<"/mnt">,
This is actually optional. If you don't supply a mountpoint, it'll
take it from @ARGV !
=item B<debug> => I<0|1>,
Debug Fuse::Simple. All filesystem calls, arguments, and return values
will be dumped, a bit like L<strace> for perl.
=item B<fuse_debug> => I<0|1>,
Debug FUSE itself. More low-level than B<debug>
=item B<threaded> => I<0|1>,
See L<Fuse>
=item B<"/"> => { hash for your root directory },
=item B<chmod> B<chown> B<flush> B<fsync> B<getattr> B<getdir> etc
See L<Fuse>
You can replace any of the low-level functions if you want, but if
you wanted to mess around with the dirty bits, you'd probably not be
using L<Fuse::Simple>, would you?
=item others
If I've forgotten any L<Fuse> args, you can supply them too.
=back
=back
=cut
sub main {
# some default args
my %args = (
"mountpoint" => $ARGV[0] || "",
"debug" => $debug,
"fuse_debug" => 0,
"threaded" => 0,
"/" => $fs,
);
# the default subs
my %fs_subs = (
"chmod" => \&fs_not_imp,
"chown" => \&fs_not_imp,
"flush" => \&fs_flush,
"fsync" => \&fs_not_imp,
"getattr" => \&fs_getattr,
"getdir" => \&fs_getdir,
"getxattr" => \&fs_not_imp,
"link" => \&fs_not_imp,
"listxattr" => \&fs_not_imp,
"mkdir" => \&fs_not_imp,
"mknod" => \&fs_not_imp,
"open" => \&fs_open,
"read" => \&fs_read,
"readlink" => \&fs_readlink,
"release" => \&fs_release,
"removexattr" => \&fs_not_imp,
"rmdir" => \&fs_not_imp,
"rename" => \&fs_not_imp,
"setxattr" => \&fs_not_imp,
"statfs" => \&fs_statfs,
"symlink" => \&fs_not_imp,
"truncate" => \&fs_truncate,
"unlink" => \&fs_not_imp,
"utime" => sub{return 0},
"write" => \&fs_write,
);
my $name;
# copy across the arg supplied to main()
while ($name = shift) {
$args{$name} = shift;
}
# except extract these ones back out.
$debug = delete $args{"debug"};
$args{"debug"} = delete( $args{"fuse_debug"} ) || 0;
$fs = delete $args{"/"};
# add the functions, if not already defined.
# wrap in debugger if debug is set.
for $name (keys %fs_subs) {
my $sub = $fs_subs{$name};
$sub = wrap($sub, $name) if $debug;
$args{$name} ||= $sub;
}
Fuse::main(%args);
}
=head1 UTIL FUNCTIONS
These might be useful for people writing their own filesystems
=over
=item B<fetch>(I<$path, @args>) (not exported)
Given F</a/path/within/my/fs/foo>, return the F<foo> dir or file or
whatever. @args will be passed to the final coderef if supplied.
=begin testing
is(fetch("README"), $Fuse::Simple::fs->{README}, "fetch() test");
=end testing
lib/Fuse/Simple.pm view on Meta::CPAN
# we are to return the contents
}
}
my $fs = {
"magic" => \&mysub,
};
Will be called like:
cat /mnt/magic
mysub(); # the file is being read
echo "123" > /mnt/magic
mysub("123\n", 0); # the file is being written
: > /mnt/magic
mysub("", 0); # the file is being truncated
You can return a string, which is the contents of the file.
You can return an fserr() for an error.
You can return a hashref (your sub will look like a directory!)
You can return a scalar ref (your sub will look like a symlink), etc.
You can even return another coderef, which will be called with the same args.
If your program die()s, you'll return ESTALE "Stale file handle".
If you die(fserr(E2BIG)), you'll return that specified error.
If you die(nocache("An error message\n")) you'll actually not return
an error, but return a file containing that error message.
It would be rather disgusting to suggest that you could also
die { "README" => "Contents\n" } to return a directory, so I won't :-)
Now... This isn't actually the whole story. An "ls" command will also
"read" your "file", because it needs to know the length. To avoid
calling your routines TOO often, the result will be cached on the
first C<getdir()> type operation, and then returned when you REALLY
read it. The cache will then be cleared so, for example:
ls /mnt/ # mysub("");
ls /mnt/magic # return cached copy
ls -Fal /mnt/magic # return cached copy
cat /mnt/magic # return cached copy, but clear cache
cat /mnt/magic # mysub(""); and clear cache
ls /mnt/magic # mysub("");
ls /mnt/magic # return cached copy
echo foo >/mnt/magic # mysub("foo",0);
ls /mnt/magic # mysub("");
ls /mnt/magic # return cached copy
=head1 EXAMPLES
see L</SYNOPSIS>
=head1 NOTES
Most things apart from coderefs can't be written, and nothing can be
renamed, chown()ed, deleted, etc. This is not considered a bug, but I
reserve the right to add something clever in a later release :-)
=head1 BUGS
accessor() is a bit thick, doesn't handle seeks, multi-block writes,
etc.
Please report any bugs or feature requests to
E<lt>bug-fuse-simple at rt.cpan.orgE<gt>, or through the web interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Fuse-Simple>.
I will be notified, and then you'll automatically be notified of progress on
your bug as I make changes.
=head1 SUPPORT
After installing, you can find documentation for this module with the
perldoc command.
perldoc Fuse::Simple
You can also look for information at:
=over
=item * AnnoCPAN: Annotated CPAN documentation
L<http://annocpan.org/dist/Fuse-Simple>
=item * CPAN Ratings
L<http://cpanratings.perl.org/d/Fuse-Simple>
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Fuse-Simple>
=item * Search CPAN
L<http://search.cpan.org/dist/Fuse-Simple>
=back
=head1 ACKNOWLEDGEMENTS
Many thanks to:
Mark Glines, for the Fuse Perl module upon which this is based.
Dobrica Pavlinusic, for maintaining it.
Miklos Szeredi et al for the underlying FUSE itself.
=head1 SEE ALSO
L<Fuse>, by Mark Glines, E<lt>mark@glines.orgE<gt>
The FUSE documentation at L<http://fuse.sourceforge.net/>
L<http://noseynick.org/>
=head1 AUTHOR
"Nosey" Nick Waterman of Nilex
( run in 0.805 second using v1.01-cache-2.11-cpan-71847e10f99 )