Use asm/ioctl.ph instead of my home-cooked ioctl business.
[perl-fuse.git] / examples / fioclient.pl
1 #!/usr/bin/env perl
2
3 use strict;
4 no strict qw(refs);
5
6 use Carp;
7 local $SIG{'__WARN__'} = \&Carp::cluck;
8
9 use Fcntl qw(:mode);
10 use Errno qw(:POSIX);
11 use POSIX;
12
13 use constant FIOC_NAME => 'fioc';
14 use constant FIOC_NONE  => 0;
15 use constant FIOC_ROOT  => 1;
16 use constant FIOC_FILE  => 2;
17
18 require 'asm/ioctl.ph';
19
20 our %sizeof = ('int' => 4);
21 sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'int'); }
22 sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'int'); }
23
24 sub usage {
25     print <<'_EOT_';
26 Usage: fioclient.pl FIOC_FILE COMMAND
27
28 COMMANDS
29   s [SIZE]     : get size if SIZE is omitted, set size otherwise
30   r SIZE [OFF] : read SIZE bytes @ OFF (default 0) and output to stdout
31   w SIZE [OFF] : write SIZE bytes @ OFF (default 0) from stdin
32
33 _EOT_
34     exit(1);
35 }
36
37
38 usage() if scalar(@ARGV) < 2;
39
40 open(my $file, '+<', $ARGV[0]) or usage();
41
42 if ($ARGV[1] eq 's') {
43     if (!defined $ARGV[2]) {
44         my $size;
45         my $rv = ioctl($file, FIOC_GET_SIZE, $size);
46         if (ioctl($file, FIOC_GET_SIZE, $size) != 0) {
47             croak($!);
48         }
49         printf("\%u\n", unpack('L', $size));
50     }
51     else {
52         if (ioctl($file, FIOC_SET_SIZE, pack('L', $ARGV[2])) != 0) {
53             croak($!);
54         }
55     }
56 }
57 elsif ($ARGV[1] eq 'r' || $ARGV[1] eq 'w') {
58     usage() unless defined $ARGV[2];
59     my $size = $ARGV[2];
60     my $off = 0;
61     if (defined $ARGV[3]) {
62         $off = $ARGV[3];
63     }
64     seek($file, SEEK_SET, $off);
65     if ($ARGV[1] eq 'r') {
66         read($file, my $data, $size);
67         print $data;
68     }
69     else {
70         read(STDIN, my $data, $size);
71         print $file $data;
72     }
73 }
74 else {
75     usage();
76 }
77
78 close($file);