diff options
Diffstat (limited to 'perl/example.pl')
-rwxr-xr-x | perl/example.pl | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/perl/example.pl b/perl/example.pl new file mode 100755 index 0000000..257f2c9 --- /dev/null +++ b/perl/example.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +use Fuse; +use POSIX qw(ENOENT EISDIR EINVAL); + +my (%files) = ( + '.' => { + type => 0040, + mode => 0755, + ctime => time()-1000 + }, + a => { + cont => "File 'a'.\n", + type => 0100, + mode => 0755, + ctime => time()-2000 + }, + b => { + cont => "This is file 'b'.\n", + type => 0100, + mode => 0644, + ctime => time()-1000 + }, +); + +sub filename_fixup { + my ($file) = shift; + $file =~ s,^/,,; + $file = '.' unless length($file); + return $file; +} + +sub e_getattr { + my ($file) = filename_fixup(shift); + $file =~ s,^/,,; + $file = '.' unless length($file); + return -ENOENT() unless exists($files{$file}); + my ($size) = exists($files{$file}{cont}) ? length($files{$file}{cont}) : 0; + my ($modes) = ($files{$file}{type}<<9) + $files{$file}{mode}; + my ($blocks, $gid, $uid, $nlink) = (1,0,0,1); + # 4 possible return values: + #return -ENOENT(); # or any other error you care to + return ($blocks,$size,$gid,$uid,$nlink,$modes,$files{$file}{ctime}); + # return ($errno,$blocks,$size,$gid,$uid,$nlink,$modes,$time); + # return ($errno,$blksize,$blocks,$size,$gid,$uid,$nlink,$modes,$time); + # if omitted, errno defaults to 0, and blksize defaults to 1024. +} + +sub e_getdir { + # return as many text filenames as you like, followed by the retval. + return (keys %files),0; +} + +sub e_open { + # VFS sanity check; it keeps all the necessary state, not much to do here. + my ($file) = filename_fixup(shift); + return -ENOENT() unless exists($files{$file}); + return -EISDIR() unless exists($files{$file}{cont}); + return 0; +} + +sub e_read { + # return an error numeric, or binary/text string. (note: 0 means EOF, "0" will + # give a byte (ascii "0") to the reading program) + my ($file) = filename_fixup(shift); + my ($buf,$off) = @_; + return -ENOENT() unless exists($files{$file}); + return -EINVAL() if $off > length($files{$file}{cont}); + return 0 if $off == length($files{$file}{cont}); + return substr($files{$file}{cont},$off,$buf); +} + +# If you run the script directly, it will run fusermount, which will in turn +# re-run this script. Hence the funky semantics. +my ($mountpoint) = ""; +$mountpoint = shift(@ARGV) if @ARGV; +Fuse::main( + mountpoint=>$mountpoint, + getattr=>\&e_getattr, + getdir=>\&e_getdir, + open=>\&e_open, + read=>\&e_read, +); |