Remove import causing dup symbol warnings, and drop () from Carp import.
[perl-fuse.git] / examples / fioc.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 Fuse;
10 use Fcntl qw(:mode);
11 use POSIX;
12
13 my $fioc_size = 0;
14 use constant FIOC_NAME => 'fioc';
15 my $fioc_buf = '';
16 use constant FIOC_NONE  => 0;
17 use constant FIOC_ROOT  => 1;
18 use constant FIOC_FILE  => 2;
19
20 require 'asm/ioctl.ph';
21
22 our %sizeof = ('int' => 4);
23 sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'int'); }
24 sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'int'); }
25
26 sub fioc_resize {
27     my ($size) = @_;
28     print 'called ', (caller(0))[3], "\n";
29     return 0 if $size == $fioc_size;
30     
31     if ($size < $fioc_size) {
32         $fioc_buf = substr($fioc_buf, 0, $size);
33     }
34     else {
35         $fioc_buf .= "\0" x ($size - $fioc_size);
36     }
37     $fioc_size = $size;
38     return 0;
39 }
40
41 sub fioc_expand {
42     my ($size) = @_;
43     print 'called ', (caller(0))[3], "\n";
44     if ($size > $fioc_size) {
45         return fioc_resize($size);
46     }
47     return 0;
48 }
49
50 sub fioc_file_type {
51     my ($path) = @_;
52     print 'called ', (caller(0))[3], "\n";
53     return FIOC_ROOT if $path eq '/';
54     return FIOC_FILE if $path eq '/' . FIOC_NAME;
55     return FIOC_NONE;
56 }
57
58 sub fioc_getattr {
59     my ($path) = @_;
60     print 'called ', (caller(0))[3], "\n";
61     my @stbuf = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
62
63     $stbuf[4] = $<;
64     $stbuf[5] = (split(/\s+/, $())[0];
65     $stbuf[8] = $stbuf[9] = time();
66
67     my $type = fioc_file_type($path);
68     if ($type == FIOC_ROOT) {
69         $stbuf[2] = S_IFDIR | 0755;
70         $stbuf[3] = 2;
71     }
72     elsif ($type == FIOC_FILE) {
73         $stbuf[2] = S_IFREG | 0644;
74         $stbuf[3] = 1;
75         $stbuf[7] = $fioc_size;
76     }
77     else {
78         return -&ENOENT;
79     }
80     return @stbuf;
81 }
82
83 sub fioc_open {
84     my ($path, $flags, $info) = @_;
85     print 'called ', (caller(0))[3], "\n";
86
87     if (fioc_file_type($path) != FIOC_NONE) {
88         return 0;
89     }
90     return -&ENOENT;
91 }
92
93 sub fioc_read {
94     my ($path, $size, $offset) = @_;
95     print 'called ', (caller(0))[3], "\n";
96
97     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
98
99     if ($offset > $fioc_size) {
100         return q{};
101     }
102
103     if ($size > $fioc_size - $offset) {
104         $size - $fioc_size - $offset;
105     }
106
107     return substr($fioc_buf, $offset, $size);
108 }
109
110 sub fioc_write {
111     my ($path, $data, $offset) = @_;
112     print 'called ', (caller(0))[3], "\n";
113
114     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
115
116     if (fioc_expand($offset + length($data))) {
117         return -&ENOMEM;
118     }
119
120     substr($fioc_buf, $offset, length($data), $data);
121     return length($data);
122 }
123
124 sub fioc_truncate {
125     my ($path, $size) = @_;
126     print 'called ', (caller(0))[3], "\n";
127
128     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
129
130     return fioc_resize($size);
131 }
132
133 sub fioc_readdir {
134     my ($path, $offset) = @_;
135     print 'called ', (caller(0))[3], "\n";
136
137     return -&EINVAL if fioc_file_type($path) != FIOC_ROOT;
138
139     return ('.', '..', FIOC_NAME, 0);
140 }
141
142 sub fioc_ioctl {
143     my ($path, $cmd, $flags, $data) = @_;
144     print 'called ', (caller(0))[3], "\n";
145     $cmd = unpack('L', pack('l', $cmd));
146
147     return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
148
149     return -&ENOSYS if $flags & 0x1;
150
151     if ($cmd == FIOC_GET_SIZE) {
152         return(0, pack('L', $fioc_size));
153     }
154     elsif ($cmd == FIOC_SET_SIZE) {
155         fioc_resize(unpack('L', $data));
156         return 0;
157     }
158
159     return -&EINVAL;
160 }
161
162 croak("Fuse doesn't have ioctl") unless Fuse::fuse_version() >= 2.8;
163
164 Fuse::main(
165     'mountpoint' => $ARGV[0],
166     'getattr'   => 'main::fioc_getattr',
167     'readdir'   => 'main::fioc_readdir',
168     'truncate'  => 'main::fioc_truncate',
169     'open'      => 'main::fioc_open',
170     'read'      => 'main::fioc_read',
171     'write'     => 'main::fioc_write',
172     'ioctl'     => 'main::fioc_ioctl');