Fuse
view release on metacpan or search on metacpan
bootstrap Fuse $VERSION;
use constant FUSE_IOCTL_COMPAT => (1 << 0);
use constant FUSE_IOCTL_UNRESTRICTED => (1 << 1);
use constant FUSE_IOCTL_RETRY => (1 << 2);
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
opendir readdir releasedir fsyncdir init destroy access
create ftruncate fgetattr lock utimens bmap);
my ($fuse_vmajor, $fuse_vminor, $fuse_vmicro) = fuse_version();
my $fuse_version = $fuse_vmajor + ($fuse_vminor * 1.0 / 1_000) +
($fuse_vmicro * 1.0 / 1_000_000);
if ($fuse_version >= 2.008) {
# junk doesn't contain a function pointer, and hopefully
# never will; it's a "dead" zone in the struct
# fuse_operations where a flag bit is declared. we don't
Called to create hard links.
=head3 chmod
Arguments: Pathname, numeric modes.
Returns an errno.
Called to change permissions on a file/directory/device/symlink.
=head3 chown
Arguments: Pathname, numeric uid, numeric gid.
Returns an errno.
Called to change ownership of a file/directory/device/symlink.
=head3 truncate
Arguments: Pathname, numeric offset.
SPAGAIN;
rv = (rv ? POPi : 0);
FREETMPS;
LEAVE;
PUTBACK;
DEBUGf("chmod end: %i\n",rv);
FUSE_CONTEXT_POST;
return rv;
}
int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) {
int rv;
FUSE_CONTEXT_PRE;
DEBUGf("chown begin\n");
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(file,0)));
XPUSHs(sv_2mortal(newSViv(uid)));
XPUSHs(sv_2mortal(newSViv(gid)));
PUTBACK;
rv = call_sv(MY_CXT.callback[11],G_SCALAR);
SPAGAIN;
rv = (rv ? POPi : 0);
FREETMPS;
LEAVE;
PUTBACK;
DEBUGf("chown end: %i\n",rv);
FUSE_CONTEXT_POST;
return rv;
}
int _PLfuse_truncate (const char *file, off_t off) {
int rv;
#ifndef PERL_HAS_64BITINT
char *temp;
#endif
FUSE_CONTEXT_PRE;
.readlink = _PLfuse_readlink,
.getdir = _PLfuse_getdir,
.mknod = _PLfuse_mknod,
.mkdir = _PLfuse_mkdir,
.unlink = _PLfuse_unlink,
.rmdir = _PLfuse_rmdir,
.symlink = _PLfuse_symlink,
.rename = _PLfuse_rename,
.link = _PLfuse_link,
.chmod = _PLfuse_chmod,
.chown = _PLfuse_chown,
.truncate = _PLfuse_truncate,
.utime = _PLfuse_utime,
.open = _PLfuse_open,
.read = _PLfuse_read,
.write = _PLfuse_write,
.statfs = _PLfuse_statfs,
.flush = _PLfuse_flush,
.release = _PLfuse_release,
.fsync = _PLfuse_fsync,
.setxattr = _PLfuse_setxattr,
Makefile.PL
MANIFEST
README
test.pl
META.yml Module meta-data (added by MakeMaker)
test/helper.pm
test/s/umount.t
test/s/mount.t
test/test-template
test/chmod.t
test/chown.t
test/getattr.t
test/getdir.t
test/link.t
test/mkdir.t
test/mknod.t
test/open.t
test/readlink.t
test/read.t
test/rename.t
test/rmdir.t
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"Filesys::Statvfs" : "0",
"Lchown" : "0",
"Unix::Mknod" : "0"
}
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
"web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Fuse"
},
"license" : [
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Fuse
no_index:
directory:
- t
- inc
requires:
Filesys::Statvfs: 0
Lchown: 0
Unix::Mknod: 0
resources:
bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Fuse
license: http://www.gnu.org/licenses/lgpl-2.1.html
repository: http://github.com/dpavlin/perl-fuse
version: 0.16
Makefile.PL view on Meta::CPAN
$micro = 0;
}
$def .= ' -DFUSE_FOUND_MAJOR_VER=' . $major;
$def .= ' -DFUSE_FOUND_MINOR_VER=' . $minor;
$def .= ' -DFUSE_FOUND_MICRO_VER=' . $micro;
WriteMakefile(
'NAME' => 'Fuse',
'VERSION_FROM' => 'Fuse.pm', # finds $VERSION
'PREREQ_PM' => { # e.g., Module::Name => 1.1
'Lchown' => 0,
'Filesys::Statvfs' => 0,
'Unix::Mknod' => 0,
},
($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'Fuse.pm', # retrieve abstract from module
AUTHOR => 'Mark Glines <mark@glines.org>') : ()),
($ExtUtils::MakeMaker::VERSION < 6.3002 ? () : (
'LICENSE' => 'LGPL_2_1',
)),
($ExtUtils::MakeMaker::VERSION < 6.46 ? () : (
as line 23:
#include <sys/filedesc.h>
For me, it wouldn't build otherwise. You should be familiar with building
a kernel, and your entire userspace; if not, read the OpenBSD FAQ.
Once you've built your kernel, installed it, and built and installed your
new userspace, reboot. You may also need to copy /usr/src/lib/libfuse/fuse.h
to /usr/include/fuse.h. (I did.) Also, for the tests, I recommend installing
devel/p5-Lchown, and installing Filesys::Statvfs, Unix::Mknod and Test::Pod
out of CPAN.
Okay, once you've done all that, run (as root):
cd /dev
./MAKEDEV fuse
If that doesn't work, do this (also as root):
cd /usr/src/etc
the read symlink path in readlink(). This causes all sorts of fun
trouble. This needs to be fixed in the kernel driver.
* fuse_get_context() returns an undef, because the reimplemented
libfuse doesn't implement that. It also doesn't do any argument
handling at all. Hence why it's all #ifndef'd out for OpenBSD.
* mknod() will not get called to create a plain file. You need to
implement create(), unless the OpenBSD devs fix libfuse to call
mknod() for plain files.
* You should probably implement release(); the kernel driver whines
a lot about the ENOSYS if you don't.
* You should probably implement all of chown(), chmod() and
utime() and/or utimens(). The kernel driver will mask out future
setattr() requests if it gets ENOSYS from ANY of these. Oops.
* Oh, and don't interrupt the FUSE implementation while it's running.
If you do (or if it aborts for some reason), umount the mountpoint
ASAP. If you don't, and especially if you then try to mount the
filesystem on that mountpoint again, you can hang your kernel. Not
even kidding. I have done this.
Anyway, happy FUSEing!
examples/loopback.pl view on Meta::CPAN
my $has_Filesys__Statvfs = 0;
eval {
require Filesys::Statvfs;
1;
} and do {
$has_Filesys__Statvfs = 1;
Filesys::Statvfs->import();
};
my $use_lchown = 0;
eval {
require Lchown;
1;
} and do {
$use_lchown = 1;
Lchown->import();
};
my $has_mknod = 0;
eval {
require Unix::Mknod;
1;
} and do {
$has_mknod = 1;
Unix::Mknod->import();
};
examples/loopback.pl view on Meta::CPAN
sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; }
sub x_rename {
my ($old) = fixup(shift);
my ($new) = fixup(shift);
my ($err) = rename($old,$new) ? 0 : -ENOENT();
return $err;
}
sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! }
sub x_chown {
my ($fn) = fixup(shift);
local $!;
print "nonexistent $fn\n" unless -e $fn;
my ($uid,$gid) = @_;
if( $use_lchown ){
lchown($uid, $gid, $fn);
}else{
chown($uid, $gid, $fn);
}
return -$!;
}
sub x_chmod {
my ($fn) = fixup(shift);
my ($mode) = shift;
my ($err) = chmod($mode,$fn) ? 0 : -$!;
return $err;
}
sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; }
examples/loopback.pl view on Meta::CPAN
'getdir' => 'main::x_getdir',
'create' => 'main::x_create',
'mknod' => 'main::x_mknod',
'mkdir' => 'main::x_mkdir',
'unlink' => 'main::x_unlink',
'rmdir' => 'main::x_rmdir',
'symlink' => 'main::x_symlink',
'rename' => 'main::x_rename',
'link' => 'main::x_link',
'chmod' => 'main::x_chmod',
'chown' => 'main::x_chown',
'truncate' => 'main::x_truncate',
'utime' => 'main::x_utime',
'open' => 'main::x_open',
'release' => 'main::x_release',
'read' => 'main::x_read',
'read_buf' => 'main::x_read_buf',
'write' => 'main::x_write',
'write_buf' => 'main::x_write_buf',
'statfs' => 'main::x_statfs',
%extraopts,
examples/rmount.pl view on Meta::CPAN
}
}
`umount $mount` unless -d $mount;
die "mountpoint $mount isn't a directory!\n" unless -d $mount;
my (%args) = (mountpoint => $mount);
map { my ($str) = $_; $args{$str} = sub { netlink($str,@_) } }
qw(getattr getdir open read write readlink unlink rmdir
symlink rename link chown chmod truncate utime mkdir
rmdir mknod statfs);
sub connect_remote {
push(@Net::SSH::ssh_options, "-p $port") if $port;
sshopen2($host, *READER, *WRITER, "./rmount_remote.pl $dir")
or die "ssh: $!\n";
select WRITER;
$| = 1;
select STDOUT;
}
examples/rmount_remote.pl view on Meta::CPAN
#!/usr/bin/perl
use strict;
use IO::File;
use POSIX qw(ENOENT ENOSYS EEXIST EPERM O_RDONLY O_RDWR O_APPEND O_CREAT);
use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET);
use Data::Dumper;
require 'syscall.ph'; # for SYS_mknod and SYS_lchown
my ($rootdir) = @ARGV;
# strip leading and trailing slashes
$rootdir = $1 if($rootdir =~ /^\/?(.*)\/?$/);
sub fixup { return "/$rootdir" . shift }
sub x_getattr {
my ($file) = fixup(shift);
examples/rmount_remote.pl view on Meta::CPAN
sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; }
sub x_rename {
my ($old) = fixup(shift);
my ($new) = fixup(shift);
my ($err) = rename($old,$new) ? 0 : -ENOENT();
return $err;
}
sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! }
sub x_chown {
my ($fn) = fixup(shift);
print "nonexistent $fn\n" unless -e $fn;
my ($uid,$gid) = @_;
# perl's chown() does not chown symlinks, it chowns the symlink's
# target. it fails when the link's target doesn't exist, because
# the stat64() syscall fails.
# this causes error messages when unpacking symlinks in tarballs.
my ($err) = syscall(&SYS_lchown,$fn,$uid,$gid,$fn) ? -$! : 0;
return $err;
}
sub x_chmod {
my ($fn) = fixup(shift);
my ($mode) = shift;
my ($err) = chmod($mode,$fn) ? 0 : -$!;
return $err;
}
sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; }
sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; }
test/chown.t view on Meta::CPAN
my (@stat);
chdir($_point);
open($file, '>', 'file');
print $file "frog\n";
close($file);
SKIP: {
skip('Need root to give away ownership', 4) unless ($UID == 0);
ok(chown(0,0,"file"),"set 0,0");
@stat = stat("file");
ok($stat[4] == 0 && $stat[5] == 0,"0,0");
ok(chown(1,1,"file"),"set 1,1");
@stat = stat("file");
ok($stat[4] == 1 && $stat[5] == 1,"1,1");
}
unlink("file");
( run in 1.346 second using v1.01-cache-2.11-cpan-71847e10f99 )