7 local $SIG{'__WARN__'} = \&Carp::cluck;
13 use constant FIOC_NAME => 'fioc';
14 use constant FIOC_NONE => 0;
15 use constant FIOC_ROOT => 1;
16 use constant FIOC_FILE => 2;
19 sub _IOC_NRMASK { ( 1 << &_IOC_NRBITS ) - 1 }
20 sub _IOC_NRSHIFT { 0 }
22 sub _IOC_TYPEBITS { 8 }
23 sub _IOC_TYPEMASK { ( 1 << &_IOC_TYPEBITS ) - 1 }
24 sub _IOC_TYPESHIFT { &_IOC_NRSHIFT + &_IOC_NRBITS }
26 sub _IOC_SIZEBITS { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 14 : 13 }
27 sub _IOC_SIZEMASK { ( 1 << &_IOC_SIZEBITS ) - 1 }
28 sub _IOC_SIZESHIFT { &_IOC_TYPESHIFT + &_IOC_TYPEBITS }
30 sub _IOC_DIRBITS { 32 - &_IOC_NRBITS - &_IOC_TYPEBITS - &_IOC_SIZEBITS }
31 sub _IOC_DIRMASK { ( 1 << &_IOC_DIRBITS ) - 1 }
32 sub _IOC_DIRSHIFT { &_IOC_SIZESHIFT + &_IOC_SIZEBITS }
34 sub _IOC_NONE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 0 : 1 }
35 sub _IOC_WRITE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 1 : 4 }
36 sub _IOC_READ { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 2 : 2 }
39 ( $_[0] << &_IOC_DIRSHIFT ) | ( ord( $_[1] ) << &_IOC_TYPESHIFT ) |
40 ( $_[2] << &_IOC_NRSHIFT ) | ( $_[3] << &_IOC_SIZESHIFT );
43 sub _IO ($$) { &_IOC( &_IOC_NONE, $_[0], $_[1], 0 ) }
44 sub _IOR ($$$) { &_IOC( &_IOC_READ, $_[0], $_[1], $_[2] ) }
45 sub _IOW ($$$) { &_IOC( &_IOC_WRITE, $_[0], $_[1], $_[2] ) }
46 sub _IOWR ($$$) { &_IOC( &_IOC_READ | &_IOC_WRITE, $_[0], $_[1], $_[2] ) }
48 sub FIOC_GET_SIZE { _IOR('E', 0, 4); }
49 sub FIOC_SET_SIZE { _IOW('E', 1, 4); }
53 Usage: fioclient.pl FIOC_FILE COMMAND
56 s [SIZE] : get size if SIZE is omitted, set size otherwise
57 r SIZE [OFF] : read SIZE bytes @ OFF (default 0) and output to stdout
58 w SIZE [OFF] : write SIZE bytes @ OFF (default 0) from stdin
65 usage() if scalar(@ARGV) < 2;
67 open(my $file, '+<', $ARGV[0]) or usage();
69 if ($ARGV[1] eq 's') {
70 if (!defined $ARGV[2]) {
72 my $rv = ioctl($file, FIOC_GET_SIZE, $size);
73 if (ioctl($file, FIOC_GET_SIZE, $size) != 0) {
76 printf("\%u\n", unpack('L', $size));
79 if (ioctl($file, FIOC_SET_SIZE, pack('L', $ARGV[2])) != 0) {
84 elsif ($ARGV[1] eq 'r' || $ARGV[1] eq 'w') {
85 usage() unless defined $ARGV[2];
88 if (defined $ARGV[3]) {
91 seek($file, SEEK_SET, $off);
92 if ($ARGV[1] eq 'r') {
93 read($file, my $data, $size);
97 read(STDIN, my $data, $size);