The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
NAME
    Fuse::Simple - Simple way to write filesystems in Perl using FUSE

SYNOPSIS
      use Fuse::Simple qw(accessor main);
      my $var = "this is a variable you can modify. write to me!\n";
      my $filesystem = {
        foo => "this is the contents of a file called foo\n",
        subdir => {
          "foo"  => "this foo is in a subdir called subdir\n",
          "blah" => "this blah is in a subdir called subdir\n",
        },
        "blah" => \ "subdir/blah",        # scalar refs are symlinks
        "magic" => sub { return "42\n" }, # will be called to get value
        "var"  => accessor(\$var),        # read and write this variable
        "var2" => accessor(\$var),        # and the same variable
        "var.b" => accessor(\ my $tmp),   # and an anonymous var
      };
      main(
        "mountpoint" => "/mnt",      # actually optional
        "debug"      => 0,           # for debugging Fuse::Simple. optional
        "fuse_debug" => 0,           # for debugging FUSE itself. optional
        "threaded"   => 0,           # optional
        "/"          => $filesystem, # required :-)
      );

DESCRIPTION
    Fuse lets you write filesystems in Perl. Fuse::Simple makes this REALLY
    Simple, as you just need a hash for your root directory, containing
    strings for files, more hashes for subdirs, or functions to be called
    for magical functionality a bit like /proc.

IMPORT TAGS
    Fuse::Simple exports nothing by default, but individual functions can be
    exported, or any ofthe following tags:

    :usual
        Includes: main accessor fserr nocache

    :debug
        Includes: wrap quoted dump_open_flags

    :tools
        Includes: fetch runcode saferun easy_getattr

    :filesys
        Includes: fs_not_imp fs_flush fs_getattr fs_getdir fs_open fs_read
        fs_readlink fs_release fs_statfs fs_truncate fs_write

MAIN FUNCTION
    main(arg => *value*, ...)
        Mount your filesystem, and probably never return. Arguments are:

        mountpoint => *"/mnt"*,
            This is actually optional. If you don't supply a mountpoint,
            it'll take it from @ARGV !

        debug => *0|1*,
            Debug Fuse::Simple. All filesystem calls, arguments, and return
            values will be dumped, a bit like strace for perl.

        fuse_debug => *0|1*,
            Debug FUSE itself. More low-level than debug

        threaded => *0|1*,
            See Fuse

        "/" => { hash for your root directory },
        chmod chown flush fsync getattr getdir etc
            See 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 Fuse::Simple, would you?

        others
            If I've forgotten any Fuse args, you can supply them too.

UTIL FUNCTIONS
    These might be useful for people writing their own filesystems

    fetch(*$path, @args*) (not exported)
        Given /a/path/within/my/fs/foo, return the foo dir or file or
        whatever. @args will be passed to the final coderef if supplied.

    runcode(*$code, @args*) (not exported)
        IF WE'RE GIVEN A CODEREF, run it, or return our cached version
        return after all CODE refs have been followed. also returns first
        arg if it wasn't a coderef.

    saferun(*$sub*,*@args*)
        Runs the supplied $sub coderef, safely (IE catches die() etc),
        returns something usable by the rest of Fuse::Simple.

    fserr(*$error_number*)
        Used by called coderef files, to return an error indication, for
        example:

          return fserr(E2BIG());

    nocache(*$stuff_to_return*)
        Used by called coderef files, to return something that should not be
        cached.

    wrap(*$sub, @name_etc*)
        Wrap a function with something that'll dump args on the way in and
        return values on the way out. This is a debugging fuction, sorta
        like strace for perl really.

    quoted(*@list*)
        return a nice printable version of the args, a little like
        Data::Dumper would

    dump_open_flags(*$flags*)
        Translate the flags to the open() call

    accessor(*\$var*)
        return a sub that can be used to read and write the (scalar)
        variable $var:

          my $var = "default value";
          my $fs = { "filename" => accessor(\$var) };

        This accessor is a bit over-simple, doesn't handle multi-block
        writes, partial block writes, seeked reads, non-saclar values, or
        anything particularly clever.

    easy_getattr(*$mode, $size*)
        Internal function, to make it easier to return getattr()s 13
        arguments when there's probably only 2 you really care about.

        Returns everything else that getattr() should.

FUSE FILESYSTEM FUNCTIONS
    These can be overridden if you really want to get at the guts of the
    filesystem, but if you really wanted to get that dirty, you probably
    wouldn't be using Fuse::Simple, would you?

    fs_not_imp()
        return ENOSYS "Function not implemented" to the program that's
        accessing this function.

    fs_flush(*$path*)
    fs_getattr(*$path*)
    fs_getdir(*$path*)
    fs_open(*$path, $flags*)
    fs_read(*$path, $size, $offset*)
    fs_readlink(*$path*)
    fs_release(*$path, $flags*)
    fs_statfs()
    fs_truncate(*$path, $offset*)
    fs_write(*$path, $buffer, $offset*)

CODEREF FILES / ACCESSORS
    coderefs in the filesystem tree will be called (with no args) whenever
    they're read, and should return some contents (usually a string, but see
    below).

    They will be called with new contents and an offset if there's something
    to be written to them, and can return almost anything, which will be
    ignored unless it's an fserr().

    It's also called with an empty string and an offset if it's to be
    truncated, and can return almost anything, which will be ignored unless
    it's an fserr().

      sub mysub {
        my ($contents, $off) = @_;
        if (defined $contents) {
          # we are writing to this file
        } else {
          # 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
    "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

EXAMPLES
      see L</SYNOPSIS>

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 :-)

BUGS
    accessor() is a bit thick, doesn't handle seeks, multi-block writes,
    etc.

    Please report any bugs or feature requests to <bug-fuse-simple at
    rt.cpan.org>, or through the web interface at
    <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.

SUPPORT
    After installing, you can find documentation for this module with the
    perldoc command.

        perldoc Fuse::Simple

    You can also look for information at:

    *   AnnoCPAN: Annotated CPAN documentation

        <http://annocpan.org/dist/Fuse-Simple>

    *   CPAN Ratings

        <http://cpanratings.perl.org/d/Fuse-Simple>

    *   RT: CPAN's request tracker

        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Fuse-Simple>

    *   Search CPAN

        <http://search.cpan.org/dist/Fuse-Simple>

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.

SEE ALSO
    Fuse, by Mark Glines, <mark@glines.org>

    The FUSE documentation at <http://fuse.sourceforge.net/>

    <http://noseynick.org/>

AUTHOR
    "Nosey" Nick Waterman of Nilex <perl@noseynick.org>
    <http://noseynick.org/>

COPYRIGHT AND LICENSE
    (C) Copyright 2006 "Nosey" Nick Waterman of Nilex. All wrongs righted.
    All rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    The full text of the license can be found in the LICENSE file included
    with this module.