Funifs
view release on metacpan or search on metacpan
#----------- flush() ---------------------------------------
#--- Useless on read-only branches, however called from fuse
#- before every close file, opened even for read().
sub u_flush {
#&Say("---41---u_flush(@_)\n");
return 0;
}
#----------- readlink() ------------------------------------
#--- Return the symlink string value
sub u_readlink {
#&Say("---42---u_readlink(@_)\n");
my $file = shift();
my $path = upath($file) or return -ENOENT();
return readlink($path);
#EINVAL
}
#----------- listxattr() -----------------------------------
#--- Return the list of extended attribute names
#--NOTE: do not include this in Fuse::main() args, --
# to supress 2+ extra calls on each file.
sub u_listxattr {
#&Say("---43---u_listxattr(@_)\n");
my $file = shift();
my $path = upath($file) or return ();
#return listxattr($path); #-- no native support in perl
return (0);
}
#----------- getxattr() ------------------------------------
#--- Return an extended attribute value
#--NOTE: avoid to include this in Fuse::main() args, --
# to supress 2+ extra calls on each file.
sub u_getxattr {
&Say("---44---u_getxattr(@_)\n");
# my ($file,$name) = @_;
# my $path = upath($file) or return ();
# #return lgetxattr($path,$name,$value,$size);
return (0);
}
#----------- statfs() --------------------------------------
#--- Return an error numeric, or binary/text string.
sub u_statfs {
#-- No args.
my @st = statvfs($Branch[0]) or return -$!;
my $statvfs = { map {$_ => shift(@st)} qw(
bsize frsize blocks bfree bavail files
ffree favail fsid basetype flag namemax fstr
) };
return ( 0, map {$statvfs->{$_}} qw(
namemax files ffree blocks bfree bsize
) );
}
#----------- rofs() ----------------------------------------
#--- Return "read-only filesystem" error
sub rofs {
&Say("---45---rofs(@_)\n");
return -EROFS();
}
sub u_chmod { &rofs('chmod' ,@_); }
sub u_chown { &rofs('chown' ,@_); }
sub u_fsync { &rofs('fsync' ,@_); }
sub u_link { &rofs('link' ,@_); }
sub u_mkdir { &rofs('mkdir' ,@_); }
sub u_mknod { &rofs('mknod' ,@_); }
sub u_removexattr { &rofs('removexattr' ,@_); }
sub u_rename { &rofs('rename' ,@_); }
sub u_rmdir { &rofs('rmdir' ,@_); }
sub u_setxattr { &rofs('setxattr' ,@_); }
sub u_symlink { &rofs('symlink' ,@_); }
sub u_truncate { &rofs('truncate' ,@_); }
sub u_unlink { &rofs('unlink' ,@_); }
sub u_utime { &rofs('utime' ,@_); }
sub u_write { &rofs('write' ,@_); }
#------------------------------------------------------------------#
#--- daemon(3) emulation
#--- Shrinked down variant of Net::Server::Daemonize
sub daemon { #-- dissociate process from terminal
my $pid = fork();
exit(0) if $pid; #-- parent process
croak("Couldn't fork: [$!]\n") unless defined $pid;
#-- child process will continue on
#-- close all input/output and separate
#-- from the parent process group
open STDIN, '</dev/null' or croak("Can't open STDIN from /dev/null: [$!]\n");
open STDOUT, '>/dev/null' or croak("Can't open STDOUT to /dev/null: [$!]\n");
open STDERR, '>&STDOUT' or croak("Can't open STDERR to STDOUT: [$!]\n");
#-- Change to root dir to avoid locking a mounted file system
#chdir '/' or croak("Can't chdir to \"/\": [$!]");
#-- Turn process into session leader, and ensure no controlling terminal
POSIX::setsid();
return 1;
}
############ Fuse::main call ###########################################
# If you run the script directly, it will run fusermount, which will in turn
# re-run this script. Hence the funky semantics.
#print STDERR "---19--- ok.\n";
my $args = {
'mountpoint' => $Union,
'mountopts' => join(','
,'ro'
, 'allow_other'
,'default_permissions'
#,'use_ino'
,"fsname=$fsSpec"
),
'debug' => 0,
#'debug' => 1,
#'threaded' => 0,
'threaded' => 1,
#-- Implemented callbacks
'getattr' => 'Fuse::Funifs::u_getattr' ,
'getdir' => 'Fuse::Funifs::u_getdir' ,
'open' => 'Fuse::Funifs::u_open' ,
'read' => 'Fuse::Funifs::u_read' ,
'flush' => 'Fuse::Funifs::u_flush' ,
'statfs' => 'Fuse::Funifs::u_statfs' ,
'listxattr' => 'Fuse::Funifs::u_listxattr' ,
'readlink' => 'Fuse::Funifs::u_readlink' ,
'release' => 'Fuse::Funifs::u_release' ,
#-- Not implemented callbacks
'getxattr' => 'Fuse::Funifs::u_getxattr', #--NOTE: avoid (keep this undef) to supress 2+ extra calls on each file
#-- Disabled access
'chmod' => 'Fuse::Funifs::u_chmod' ,
'chown' => 'Fuse::Funifs::u_chown' ,
'fsync' => 'Fuse::Funifs::u_fsync' ,
'link' => 'Fuse::Funifs::u_link' ,
'mkdir' => 'Fuse::Funifs::u_mkdir' ,
'mknod' => 'Fuse::Funifs::u_mknod' ,
'removexattr' => 'Fuse::Funifs::u_removexattr',
'rename' => 'Fuse::Funifs::u_rename' ,
'rmdir' => 'Fuse::Funifs::u_rmdir' ,
'setxattr' => 'Fuse::Funifs::u_setxattr' ,
'symlink' => 'Fuse::Funifs::u_symlink' ,
'truncate' => 'Fuse::Funifs::u_truncate' ,
'unlink' => 'Fuse::Funifs::u_unlink' ,
'utime' => 'Fuse::Funifs::u_utime' ,
'write' => 'Fuse::Funifs::u_write' ,
};
#use Data::Dumper;
#BEGIN { $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; }
#print STDERR "---21---\$args: ".Dumper($args);
#exit 0;
#-- Change to root dir to avoid locking a mounted file system
chdir('/') or croak("Can't chdir to \"/\": [$!]");
#-- Ensure consistent behaviour across debug and normal modes
daemon() unless $opt->{'debug'};
&Fuse::main(%$args);
############ Exit after umount #########################################
#Feb 8 20:37:39 knob funifs[10318]: unmount: funifs#/dev /web/me.nu/dev ro,noexec,nosuid,nodev,dirs=/web/sites/me.nu/Delta/dev:/web/sites/me.nu/www
&printLog('unmount: '.$LogMsg);
0;
__END__
########################################################################
#
( run in 1.384 second using v1.01-cache-2.11-cpan-71847e10f99 )