X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=examples%2Floopback_t.pl;h=db03fb9fce65e4e81109013c53b461936b66b389;hb=3bdd22cf0cf94b4feb0646a45f64bc8c7abfc792;hp=9ae10fef6ca0f95d5a0aa1b8d2e673eef36f6fcc;hpb=b3bffb7389c1e867e0e7b63c03c6acc629d57e12;p=perl-fuse.git diff --git a/examples/loopback_t.pl b/examples/loopback_t.pl old mode 100644 new mode 100755 index 9ae10fe..db03fb9 --- a/examples/loopback_t.pl +++ b/examples/loopback_t.pl @@ -3,11 +3,25 @@ use strict; use threads; use threads::shared; +use blib; use Fuse; 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); -require 'syscall.ph'; # for SYS_mknod and SYS_lchown +use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET S_ISREG S_ISFIFO S_IMODE); +my $can_syscall = eval { + require 'syscall.ph'; # for SYS_mknod and SYS_lchown +}; +if (!$can_syscall && open my $fh, '<', '/usr/include/sys/syscall.h') { + my %sys = do { local $/ = undef; + <$fh> =~ m/\#define \s+ (\w+) \s+ (\d+)/gxms; + }; + close $fh; + if ($sys{SYS_mknod} && $sys{SYS_lchown}) { + *SYS_mknod = sub { $sys{SYS_mknod} }; + *SYS_lchown = sub { $sys{SYS_lchown} }; + $can_syscall = 1; + } +} sub fixup { return "/tmp/fusetest-" . $ENV{LOGNAME} . shift } @@ -78,6 +92,7 @@ sub x_rename { } sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! } sub x_chown { + return -ENOSYS() if ! $can_syscall; my ($fn) = fixup(shift); print "nonexistent $fn\n" unless -e $fn; my ($uid,$gid) = @_; @@ -101,11 +116,23 @@ sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); ret sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } sub x_mknod { + return -ENOSYS() if ! $can_syscall; # since this is called for ALL files, not just devices, I'll do some checks # and possibly run the real mknod command. my ($file, $modes, $dev) = @_; $file = fixup($file); - $! = 0; + undef $!; + if ($^O eq 'freebsd') { + if (S_ISREG($modes)) { + open(FILE, '>', $file) || return -$!; + print FILE ""; + close(FILE); + return 0; + } elsif (S_ISFIFO($modes)) { + my ($rv) = POSIX::mkfifo($file, S_IMODE($modes)); + return $rv ? 0 : -POSIX::errno(); + } + } syscall(&SYS_mknod,$file,$modes,$dev); return -$!; }