/[fuse.before_github]/perl-llin/Fuse.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /perl-llin/Fuse.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show annotations)
Wed Jun 22 16:15:17 2005 UTC (18 years, 9 months ago) by dpavlin
Original Path: perl/trunk/Fuse.pm
File size: 12583 byte(s)
added changes from Mark Wilkinson to support mount options, list all
contributors in AUTHORS, added pod tests

1 package Fuse;
2
3 use 5.006;
4 use strict;
5 use warnings;
6 use Errno;
7 use Carp;
8
9 require Exporter;
10 require DynaLoader;
11 use AutoLoader;
12 use Data::Dumper;
13 our @ISA = qw(Exporter DynaLoader);
14
15 # Items to export into callers namespace by default. Note: do not export
16 # names by default without a very good reason. Use EXPORT_OK instead.
17 # Do not simply export all your public functions/methods/constants.
18
19 # This allows declaration use Fuse ':all';
20 # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21 # will save memory.
22 our %EXPORT_TAGS = (
23 'all' => [ qw(FUSE_DEBUG XATTR_CREATE XATTR_REPLACE) ],
24 'debug' => [ qw(FUSE_DEBUG) ],
25 'xattr' => [ qw(XATTR_CREATE XATTR_REPLACE) ]
26 );
27
28 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29
30 our @EXPORT = qw(
31 FUSE_DEBUG
32 );
33 our $VERSION = '0.06';
34
35 sub AUTOLOAD {
36 # This AUTOLOAD is used to 'autoload' constants from the constant()
37 # XS function. If a constant is not found then control is passed
38 # to the AUTOLOAD in AutoLoader.
39
40 my $constname;
41 our $AUTOLOAD;
42 ($constname = $AUTOLOAD) =~ s/.*:://;
43 croak "& not defined" if $constname eq 'constant';
44 my $val = constant($constname, @_ ? $_[0] : 0);
45 if ($! != 0) {
46 if ($!{EINVAL}) {
47 $AutoLoader::AUTOLOAD = $AUTOLOAD;
48 goto &AutoLoader::AUTOLOAD;
49 }
50 else {
51 croak "Your vendor has not defined Fuse macro $constname";
52 }
53 }
54 {
55 no strict 'refs';
56 # Fixed between 5.005_53 and 5.005_61
57 if ($] >= 5.00561) {
58 *$AUTOLOAD = sub () { $val };
59 }
60 else {
61 *$AUTOLOAD = sub { $val };
62 }
63 }
64 goto &$AUTOLOAD;
65 }
66
67 sub XATTR_CREATE {
68 # See <sys/xattr.h>.
69 return 1;
70 }
71
72 sub XATTR_REPLACE {
73 # See <sys/xattr.h>.
74 return 2;
75 }
76
77 bootstrap Fuse $VERSION;
78
79 sub main {
80 my (@subs) = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
81 my (@names) = qw(getattr readlink getdir mknod mkdir unlink rmdir symlink
82 rename link chmod chown truncate utime open read write statfs
83 flush release fsync setxattr getxattr listxattr removexattr);
84 my (@validOpts) = qw(allow_other);
85 my ($tmp) = 0;
86 my (%mapping) = map { $_ => $tmp++ } (@names);
87 my (%optmap) = map { $_ => 1 } (@validOpts);
88 my (%otherargs) = (debug=>0, mountpoint=>"", mountopts=>"");
89 while(my $name = shift) {
90 my ($subref) = shift;
91 if(exists($otherargs{$name})) {
92 $otherargs{$name} = $subref;
93 } else {
94 croak "There is no function $name" unless exists($mapping{$name});
95 croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless $subref;
96 croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref);
97 croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref) eq "CODE";
98 $subs[$mapping{$name}] = $subref;
99 }
100 }
101 foreach my $opt ( split(/,/,$otherargs{mountopts}) ) {
102 if ( ! exists($optmap{$opt}) ) {
103 croak "Use of an invalid mountopt argument";
104 }
105 }
106 perl_fuse_main($otherargs{debug},$otherargs{mountpoint},$otherargs{mountopts},@subs);
107 }
108
109 # Autoload methods go after =cut, and are processed by the autosplit program.
110
111 1;
112 __END__
113
114 =head1 NAME
115
116 Fuse - write filesystems in Perl using FUSE
117
118 =head1 SYNOPSIS
119
120 use Fuse;
121 my ($mountpoint) = "";
122 $mountpoint = shift(@ARGV) if @ARGV;
123 Fuse::main(mountpoint=>$mountpoint, getattr=>\&my_getattr, getdir=>\&my_getdir, ...);
124
125 =head1 DESCRIPTION
126
127 This lets you implement filesystems in perl, through the FUSE
128 (Filesystem in USErspace) kernel/lib interface.
129
130 FUSE expects you to implement callbacks for the various functions.
131
132 NOTE: I have only tested the things implemented in example.pl!
133 It should work, but some things may not.
134
135 In the following definitions, "errno" can be 0 (for a success),
136 -EINVAL, -ENOENT, -EONFIRE, any integer less than 1 really.
137
138 You can import standard error constants by saying something like
139 "use POSIX qw(EDOTDOT ENOANO);".
140
141 Every constant you need (file types, open() flags, error values,
142 etc) can be imported either from POSIX or from Fcntl, often both.
143 See their respective documentations, for more information.
144
145 =head2 EXPORTED SYMBOLS
146
147 FUSE_DEBUG by default.
148
149 You can request all exportable symbols by using the tag ":all".
150
151 You can request all debug symbols by using the tag ":debug".
152 This will export FUSE_DEBUG.
153
154 You can request the extended attribute symbols by using the tag ":xattr".
155 This will export XATTR_CREATE and XATTR_REPLACE.
156
157 =head2 FUNCTIONS
158
159 =head3 Fuse::main
160
161 Takes arguments in the form of hash key=>value pairs. There are
162 many valid keys. Most of them correspond with names of callback
163 functions, as described in section 'FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT'.
164 A few special keys also exist:
165
166
167 debug => boolean
168
169 =over 1
170
171 This turns FUSE call tracing on and off. Default is 0 (which means off).
172
173 =back
174
175 mountpoint => string
176
177 =over 1
178
179 The point at which to mount this filesystem. There is no default, you must
180 specify this. An example would be '/mnt'.
181
182 =back
183
184 mountopts => string
185
186 =over 1
187
188 This is a comma seperated list of mount options to pass to the FUSE kernel
189 module.
190
191 At present, it allows the specification of the allow_other
192 argument when mounting the new FUSE filesystem. To use this, you will also
193 need 'user_allow_other' in /etc/fuse.conf as per the FUSE documention
194
195 mountopts => "allow_other" or
196 mountopts => ""
197
198 =back
199
200 unthreaded => boolean
201
202 =over 1
203
204 This turns FUSE multithreading off and on. NOTE: This perlmodule does not
205 currently work properly in multithreaded mode! The author is unfortunately
206 not familiar enough with perl-threads internals, and according to the
207 documentation available at time of writing (2002-03-08), those internals are
208 subject to changing anyway. Note that singlethreaded mode also means that
209 you will not have to worry about reentrancy, though you will have to worry
210 about recursive lookups (since the kernel holds a global lock on your
211 filesystem and blocks waiting for one callback to complete before calling
212 another).
213
214 I hope to add full multithreading functionality later, but for now, I
215 recommend you leave this option at the default, 1 (which means
216 unthreaded, no threads will be used and no reentrancy is needed).
217
218 =back
219
220 =head2 FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT
221
222 =head3 getattr
223
224 Arguments: filename.
225 Returns a list, very similar to the 'stat' function (see
226 perlfunc). On error, simply return a single numeric scalar
227 value (e.g. "return -ENOENT();").
228
229 FIXME: the "ino" field is currently ignored. I tried setting it to 0
230 in an example script, which consistently caused segfaults.
231
232 Fields (the following was stolen from perlfunc(1) with apologies):
233
234 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
235 $atime,$mtime,$ctime,$blksize,$blocks)
236 = getattr($filename);
237
238 Here are the meaning of the fields:
239
240 0 dev device number of filesystem
241 1 ino inode number
242 2 mode file mode (type and permissions)
243 3 nlink number of (hard) links to the file
244 4 uid numeric user ID of file's owner
245 5 gid numeric group ID of file's owner
246 6 rdev the device identifier (special files only)
247 7 size total size of file, in bytes
248 8 atime last access time in seconds since the epoch
249 9 mtime last modify time in seconds since the epoch
250 10 ctime inode change time (NOT creation time!) in seconds
251 since the epoch
252 11 blksize preferred block size for file system I/O
253 12 blocks actual number of blocks allocated
254
255 (The epoch was at 00:00 January 1, 1970 GMT.)
256
257 =head3 readlink
258
259 Arguments: link pathname.
260 Returns a scalar: either a numeric constant, or a text string.
261
262 This is called when dereferencing symbolic links, to learn the target.
263
264 example rv: return "/proc/self/fd/stdin";
265
266 =head3 getdir
267
268 Arguments: Containing directory name.
269 Returns a list: 0 or more text strings (the filenames), followed by a numeric errno (usually 0).
270
271 This is used to obtain directory listings. Its opendir(), readdir(), filldir() and closedir() all in one call.
272
273 example rv: return ('.', 'a', 'b', 0);
274
275 =head3 mknod
276
277 Arguments: Filename, numeric modes, numeric device
278 Returns an errno (0 upon success, as usual).
279
280 This function is called for all non-directory, non-symlink nodes,
281 not just devices.
282
283 =head3 mkdir
284
285 Arguments: New directory pathname, numeric modes.
286 Returns an errno.
287
288 Called to create a directory.
289
290 =head3 unlink
291
292 Arguments: Filename.
293 Returns an errno.
294
295 Called to remove a file, device, or symlink.
296
297 =head3 rmdir
298
299 Arguments: Pathname.
300 Returns an errno.
301
302 Called to remove a directory.
303
304 =head3 symlink
305
306 Arguments: Existing filename, symlink name.
307 Returns an errno.
308
309 Called to create a symbolic link.
310
311 =head3 rename
312
313 Arguments: old filename, new filename.
314 Returns an errno.
315
316 Called to rename a file, and/or move a file from one directory to another.
317
318 =head3 link
319
320 Arguments: Existing filename, hardlink name.
321 Returns an errno.
322
323 Called to create hard links.
324
325 =head3 chmod
326
327 Arguments: Pathname, numeric modes.
328 Returns an errno.
329
330 Called to change permissions on a file/directory/device/symlink.
331
332 =head3 chown
333
334 Arguments: Pathname, numeric uid, numeric gid.
335 Returns an errno.
336
337 Called to change ownership of a file/directory/device/symlink.
338
339 =head3 truncate
340
341 Arguments: Pathname, numeric offset.
342 Returns an errno.
343
344 Called to truncate a file, at the given offset.
345
346 =head3 utime
347
348 Arguments: Pathname, numeric actime, numeric modtime.
349 Returns an errno.
350
351 Called to change access/modification times for a file/directory/device/symlink.
352
353 =head3 open
354
355 Arguments: Pathname, numeric flags (which is an OR-ing of stuff like O_RDONLY
356 and O_SYNC, constants you can import from POSIX).
357 Returns an errno.
358
359 No creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be passed to open().
360 Your open() method needs only check if the operation is permitted for the given flags, and return 0 for success.
361
362 =head3 read
363
364 Arguments: Pathname, numeric requestedsize, numeric offset.
365 Returns a numeric errno, or a string scalar with up to $requestedsize bytes of data.
366
367 Called in an attempt to fetch a portion of the file.
368
369 =head3 write
370
371 Arguments: Pathname, scalar buffer, numeric offset. You can use length($buffer) to
372 find the buffersize.
373 Returns an errno.
374
375 Called in an attempt to write (or overwrite) a portion of the file. Be prepared because $buffer could contain random binary data with NULLs and all sorts of other wonderful stuff.
376
377 =head3 statfs
378
379 Arguments: none
380 Returns any of the following:
381
382 -ENOANO()
383
384 or
385
386 $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
387
388 or
389
390 -ENOANO(), $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
391
392 =head3 flush
393
394 Arguments: Pathname
395 Returns an errno or 0 on success.
396
397 Called to synchronise any cached data. This is called before the file
398 is closed. It may be called multiple times before a file is closed.
399
400 =head3 release
401
402 Arguments: Pathname, numeric flags passed to open
403 Returns an errno or 0 on success.
404
405 Called to indicate that there are no more references to the file. Called once
406 for every file with the same pathname and flags as were passed to open.
407
408 =head3 fsync
409
410 Arguments: Pathname, numeric flags
411 Returns an errno or 0 on success.
412
413 Called to synchronise the file's contents. If flags is non-zero,
414 only synchronise the user data. Otherwise synchronise the user and meta data.
415
416 =head3 setxattr
417
418 Arguments: Pathname, extended attribute's name, extended attribute's value, numeric flags (which is an OR-ing of XATTR_CREATE and XATTR_REPLACE
419 Returns an errno or 0 on success.
420
421 Called to set the value of the named extended attribute.
422
423 If you wish to reject setting of a particular form of extended attribute name
424 (e.g.: regexps matching user\..* or security\..*), then return - EOPNOTSUPP.
425
426 If flags is set to XATTR_CREATE and the extended attribute already exists,
427 this should fail with - EEXIST. If flags is set to XATTR_REPLACE
428 and the extended attribute doesn't exist, this should fail with - ENOATTR.
429
430 XATTR_CREATE and XATTR_REPLACE are provided by this module, but not exported
431 by default. To import them:
432
433 use Fuse ':xattr';
434
435 or:
436
437 use Fuse ':all';
438
439 =head3 getxattr
440
441 Arguments: Pathname, extended attribute's name
442 Returns an errno, 0 if there was no value, or the extended attribute's value.
443
444 Called to get the value of the named extended attribute.
445
446 =head3 listxattr
447
448 Arguments: Pathname
449 Returns a list: 0 or more text strings (the extended attribute names), followed by a numeric errno (usually 0).
450
451 =head3 removexattr
452
453 Arguments: Pathname, extended attribute's name
454 Returns an errno or 0 on success.
455
456 =head1 AUTHOR
457
458 Mark Glines, E<lt>mark@glines.orgE<gt>
459
460 =head1 SEE ALSO
461
462 L<perl>, the FUSE documentation.
463
464 =cut

  ViewVC Help
Powered by ViewVC 1.1.26