7 local $SIG{'__WARN__'} = \&Carp::cluck;
15 use constant FIOC_NAME => 'fioc';
17 use constant FIOC_NONE => 0;
18 use constant FIOC_ROOT => 1;
19 use constant FIOC_FILE => 2;
22 sub _IOC_NRMASK { ( 1 << &_IOC_NRBITS ) - 1 }
23 sub _IOC_NRSHIFT { 0 }
25 sub _IOC_TYPEBITS { 8 }
26 sub _IOC_TYPEMASK { ( 1 << &_IOC_TYPEBITS ) - 1 }
27 sub _IOC_TYPESHIFT { &_IOC_NRSHIFT + &_IOC_NRBITS }
29 sub _IOC_SIZEBITS { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 14 : 13 }
30 sub _IOC_SIZEMASK { ( 1 << &_IOC_SIZEBITS ) - 1 }
31 sub _IOC_SIZESHIFT { &_IOC_TYPESHIFT + &_IOC_TYPEBITS }
33 sub _IOC_DIRBITS { 32 - &_IOC_NRBITS - &_IOC_TYPEBITS - &_IOC_SIZEBITS }
34 sub _IOC_DIRMASK { ( 1 << &_IOC_DIRBITS ) - 1 }
35 sub _IOC_DIRSHIFT { &_IOC_SIZESHIFT + &_IOC_SIZEBITS }
37 sub _IOC_NONE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 0 : 1 }
38 sub _IOC_WRITE { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 1 : 4 }
39 sub _IOC_READ { ( POSIX::uname() )[4] =~ /^i[3-6]86|x86_64$/ ? 2 : 2 }
42 ( $_[0] << &_IOC_DIRSHIFT ) | ( ord( $_[1] ) << &_IOC_TYPESHIFT ) |
43 ( $_[2] << &_IOC_NRSHIFT ) | ( $_[3] << &_IOC_SIZESHIFT );
46 sub _IO ($$) { &_IOC( &_IOC_NONE, $_[0], $_[1], 0 ) }
47 sub _IOR ($$$) { &_IOC( &_IOC_READ, $_[0], $_[1], $_[2] ) }
48 sub _IOW ($$$) { &_IOC( &_IOC_WRITE, $_[0], $_[1], $_[2] ) }
49 sub _IOWR ($$$) { &_IOC( &_IOC_READ | &_IOC_WRITE, $_[0], $_[1], $_[2] ) }
51 sub FIOC_GET_SIZE { _IOR('E', 0, 4); }
52 sub FIOC_SET_SIZE { _IOW('E', 1, 4); }
56 print 'called ', (caller(0))[3], "\n";
57 return 0 if $size == $fioc_size;
59 if ($size < $fioc_size) {
60 $fioc_buf = substr($fioc_buf, 0, $size);
63 $fioc_buf .= "\0" x ($size - $fioc_size);
71 print 'called ', (caller(0))[3], "\n";
72 if ($size > $fioc_size) {
73 return fioc_resize($size);
80 print 'called ', (caller(0))[3], "\n";
81 return FIOC_ROOT if $path eq '/';
82 return FIOC_FILE if $path eq '/' . FIOC_NAME;
88 print 'called ', (caller(0))[3], "\n";
89 my @stbuf = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
92 $stbuf[5] = (split(/\s+/, $())[0];
93 $stbuf[8] = $stbuf[9] = time();
95 my $type = fioc_file_type($path);
96 if ($type == FIOC_ROOT) {
97 $stbuf[2] = S_IFDIR | 0755;
100 elsif ($type == FIOC_FILE) {
101 $stbuf[2] = S_IFREG | 0644;
103 $stbuf[7] = $fioc_size;
112 my ($path, $flags, $info) = @_;
113 print 'called ', (caller(0))[3], "\n";
115 if (fioc_file_type($path) != FIOC_NONE) {
122 my ($path, $size, $offset) = @_;
123 print 'called ', (caller(0))[3], "\n";
125 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
127 if ($offset > $fioc_size) {
131 if ($size > $fioc_size - $offset) {
132 $size - $fioc_size - $offset;
135 return substr($fioc_buf, $offset, $size);
139 my ($path, $data, $offset) = @_;
140 print 'called ', (caller(0))[3], "\n";
142 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
144 if (fioc_expand($offset + length($data))) {
148 substr($fioc_buf, $offset, length($data), $data);
149 return length($data);
153 my ($path, $size) = @_;
154 print 'called ', (caller(0))[3], "\n";
156 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
158 return fioc_resize($size);
162 my ($path, $offset) = @_;
163 print 'called ', (caller(0))[3], "\n";
165 return -&EINVAL if fioc_file_type($path) != FIOC_ROOT;
167 return ('.', '..', FIOC_NAME, 0);
171 my ($path, $cmd, $flags, $data) = @_;
172 print 'called ', (caller(0))[3], "\n";
173 $cmd = unpack('L', pack('l', $cmd));
175 print("fioc_ioctl(): path is \"$path\", cmd is $cmd, flags is $flags\n");
176 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
178 return -&ENOSYS if $flags & 0x1;
180 if ($cmd == FIOC_GET_SIZE) {
181 print "handling FIOC_GET_SIZE\n";
182 return(0, pack('L', $fioc_size));
184 elsif ($cmd == FIOC_SET_SIZE) {
185 print "handling FIOC_SET_SIZE\n";
186 fioc_resize(unpack('L', $data));
193 croak("Fuse doesn't have ioctl") unless Fuse::fuse_version() >= 2.8;
196 'mountpoint' => $ARGV[0],
197 'getattr' => 'main::fioc_getattr',
198 'readdir' => 'main::fioc_readdir',
199 'truncate' => 'main::fioc_truncate',
200 'open' => 'main::fioc_open',
201 'read' => 'main::fioc_read',
202 'write' => 'main::fioc_write',
203 'ioctl' => 'main::fioc_ioctl');