X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=examples%2Ffioc.pl;h=811cb80b8abc8d7ce7ab6131cd32d4e98ec40677;hb=7f982ef01e7f172d79086ef68ddfd5591397f541;hp=031067bdbb7545c6697d99d1e50c8e73932934c2;hpb=bfce636c5682a59880c9f7777c613ac86023d2dc;p=perl-fuse.git diff --git a/examples/fioc.pl b/examples/fioc.pl index 031067b..811cb80 100755 --- a/examples/fioc.pl +++ b/examples/fioc.pl @@ -3,59 +3,34 @@ use strict; no strict qw(refs); -use Carp (); +use threads; +use threads::shared; + +use Carp; local $SIG{'__WARN__'} = \&Carp::cluck; use Fuse; use Fcntl qw(:mode); -use Errno qw(:POSIX); use POSIX; -my $fioc_size = 0; +my $fioc_size :shared = 0; use constant FIOC_NAME => 'fioc'; -my $fioc_buf = ''; +my $fioc_buf :shared = ''; use constant FIOC_NONE => 0; use constant FIOC_ROOT => 1; use constant FIOC_FILE => 2; -sub _IOC_NRBITS { 8 } -sub _IOC_NRMASK { ( 1 << &_IOC_NRBITS ) - 1 } -sub _IOC_NRSHIFT { 0 } - -sub _IOC_TYPEBITS { 8 } -sub _IOC_TYPEMASK { ( 1 << &_IOC_TYPEBITS ) - 1 } -sub _IOC_TYPESHIFT { &_IOC_NRSHIFT + &_IOC_NRBITS } - -sub _IOC_SIZEBITS { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 14 : 13 } -sub _IOC_SIZEMASK { ( 1 << &_IOC_SIZEBITS ) - 1 } -sub _IOC_SIZESHIFT { &_IOC_TYPESHIFT + &_IOC_TYPEBITS } +require 'asm/ioctl.ph'; -sub _IOC_DIRBITS { 32 - &_IOC_NRBITS - &_IOC_TYPEBITS - &_IOC_SIZEBITS } -sub _IOC_DIRMASK { ( 1 << &_IOC_DIRBITS ) - 1 } -sub _IOC_DIRSHIFT { &_IOC_SIZESHIFT + &_IOC_SIZEBITS } - -sub _IOC_NONE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 0 : 1 } -sub _IOC_WRITE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 1 : 4 } -sub _IOC_READ { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 2 : 2 } - -sub _IOC ($$$$) { - ( $_[0] << &_IOC_DIRSHIFT ) | ( ord( $_[1] ) << &_IOC_TYPESHIFT ) | - ( $_[2] << &_IOC_NRSHIFT ) | ( $_[3] << &_IOC_SIZESHIFT ); -} - -sub _IO ($$) { &_IOC( &_IOC_NONE, $_[0], $_[1], 0 ) } -sub _IOR ($$$) { &_IOC( &_IOC_READ, $_[0], $_[1], $_[2] ) } -sub _IOW ($$$) { &_IOC( &_IOC_WRITE, $_[0], $_[1], $_[2] ) } -sub _IOWR ($$$) { &_IOC( &_IOC_READ | &_IOC_WRITE, $_[0], $_[1], $_[2] ) } - -sub FIOC_GET_SIZE { _IOR('E', 0, 4); } -sub FIOC_SET_SIZE { _IOW('E', 1, 4); } +our %sizeof = ('int' => 4); +sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'int'); } +sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'int'); } sub fioc_resize { my ($size) = @_; print 'called ', (caller(0))[3], "\n"; return 0 if $size == $fioc_size; - + if ($size < $fioc_size) { $fioc_buf = substr($fioc_buf, 0, $size); } @@ -138,6 +113,7 @@ sub fioc_read { sub fioc_write { my ($path, $data, $offset) = @_; print 'called ', (caller(0))[3], "\n"; + lock($fioc_buf); return -&EINVAL if fioc_file_type($path) != FIOC_FILE; @@ -152,6 +128,7 @@ sub fioc_write { sub fioc_truncate { my ($path, $size) = @_; print 'called ', (caller(0))[3], "\n"; + lock($fioc_buf); return -&EINVAL if fioc_file_type($path) != FIOC_FILE; @@ -170,19 +147,16 @@ sub fioc_readdir { sub fioc_ioctl { my ($path, $cmd, $flags, $data) = @_; print 'called ', (caller(0))[3], "\n"; - $cmd = unpack('L', pack('l', $cmd)); - print("fioc_ioctl(): path is \"$path\", cmd is $cmd, flags is $flags\n"); return -&EINVAL if fioc_file_type($path) != FIOC_FILE; return -&ENOSYS if $flags & 0x1; if ($cmd == FIOC_GET_SIZE) { - print "handling FIOC_GET_SIZE\n"; return(0, pack('L', $fioc_size)); } elsif ($cmd == FIOC_SET_SIZE) { - print "handling FIOC_SET_SIZE\n"; + lock($fioc_buf); fioc_resize(unpack('L', $data)); return 0; } @@ -200,4 +174,5 @@ Fuse::main( 'open' => 'main::fioc_open', 'read' => 'main::fioc_read', 'write' => 'main::fioc_write', - 'ioctl' => 'main::fioc_ioctl'); + 'ioctl' => 'main::fioc_ioctl', + 'threaded' => 1);