10 local $SIG{'__WARN__'} = \&Carp::cluck;
16 my $fioc_size :shared = 0;
17 use constant FIOC_NAME => 'fioc';
18 my $fioc_buf :shared = '';
19 use constant FIOC_NONE => 0;
20 use constant FIOC_ROOT => 1;
21 use constant FIOC_FILE => 2;
23 require 'asm/ioctl.ph';
25 our %sizeof = ('int' => 4);
26 sub FIOC_GET_SIZE { _IOR(ord 'E', 0, 'int'); }
27 sub FIOC_SET_SIZE { _IOW(ord 'E', 1, 'int'); }
28 sub TCGETS { 0x5401; }
32 print 'called ', (caller(0))[3], "\n";
33 return 0 if $size == $fioc_size;
35 if ($size < $fioc_size) {
36 $fioc_buf = substr($fioc_buf, 0, $size);
39 $fioc_buf .= "\0" x ($size - $fioc_size);
47 print 'called ', (caller(0))[3], "\n";
48 if ($size > $fioc_size) {
49 return fioc_resize($size);
56 print 'called ', (caller(0))[3], "\n";
57 return FIOC_ROOT if $path eq '/';
58 return FIOC_FILE if $path eq '/' . FIOC_NAME;
64 print 'called ', (caller(0))[3], "\n";
65 my @stbuf = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
68 $stbuf[5] = (split(/\s+/, $())[0];
69 $stbuf[8] = $stbuf[9] = time();
71 my $type = fioc_file_type($path);
72 if ($type == FIOC_ROOT) {
73 $stbuf[2] = S_IFDIR | 0755;
76 elsif ($type == FIOC_FILE) {
77 $stbuf[2] = S_IFREG | 0644;
79 $stbuf[7] = $fioc_size;
88 my ($path, $flags, $info) = @_;
89 print 'called ', (caller(0))[3], "\n";
91 return 0 if fioc_file_type($path) != FIOC_NONE;
96 my ($path, $size, $offset) = @_;
97 print 'called ', (caller(0))[3], "\n";
99 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
100 return q{} if $offset > $fioc_size;
102 if ($size > $fioc_size - $offset) {
103 $size - $fioc_size - $offset;
106 return substr($fioc_buf, $offset, $size);
110 my ($path, $data, $offset) = @_;
111 print 'called ', (caller(0))[3], "\n";
114 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
115 return -&ENOMEM if fioc_expand($offset + length($data));
117 substr($fioc_buf, $offset, length($data), $data);
118 return length($data);
122 my ($path, $size) = @_;
123 print 'called ', (caller(0))[3], "\n";
126 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
128 return fioc_resize($size);
132 my ($path, $offset) = @_;
133 print 'called ', (caller(0))[3], "\n";
135 return -&EINVAL if fioc_file_type($path) != FIOC_ROOT;
137 return ('.', '..', FIOC_NAME, 0);
141 my ($path, $cmd, $flags, $data) = @_;
142 print 'called ', (caller(0))[3], "\n";
144 return -&EINVAL if fioc_file_type($path) != FIOC_FILE;
145 return -&ENOSYS if $flags & 0x1;
147 if ($cmd == FIOC_GET_SIZE) {
148 return(0, pack('L', $fioc_size));
150 elsif ($cmd == FIOC_SET_SIZE) {
152 fioc_resize(unpack('L', $data));
155 elsif ($cmd == TCGETS) {
156 # perl sends TCGETS as part of calling isatty() on opening a file;
157 # this appears to be a more canonical answer
164 croak("Fuse doesn't have ioctl") unless Fuse::fuse_version() >= 2.8;
167 'mountpoint' => $ARGV[0],
168 'getattr' => 'main::fioc_getattr',
169 'readdir' => 'main::fioc_readdir',
170 'truncate' => 'main::fioc_truncate',
171 'open' => 'main::fioc_open',
172 'read' => 'main::fioc_read',
173 'write' => 'main::fioc_write',
174 'ioctl' => 'main::fioc_ioctl',