/[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

Annotation of /perl-llin/Fuse.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (hide annotations)
Tue Dec 27 12:47:00 2005 UTC (18 years, 3 months ago) by dpavlin
Original Path: perl/trunk/Fuse.pm
File size: 13446 byte(s)
Changes from Mark Glines in preparation for 0.07
- Remove the FUSE_DEBUG constant; we never actually implemented
  it to begin with.
- "make test" now uses the version of Fuse you've just built,
  not the one installed in /usr/lib/perl5.
- getattr test now allows blksize to vary between host and fuse
  fs, as this is not a bug.
- Add experimental support for threading.  The following minor
  API changes accommodate this:
- The nonexistent (yet documented) "unthreaded=>1" attribute
  has been replaced with the "threaded=>1" attribute, and this
  time it actually exists.
- Symbolic refs like "main::e_getattr" are now allowed for
  callbacks, because threaded mode needs to share() the
  callbacks, yet perl 5.8.7 does not allow share()ing code
  refs yet.  Direct code-refs are still supported as much
  as possible (currently, non-threaded mode).
- testsuite uses a multithreaded loopback.pl, when available.
- Update docs accordingly.  Update examples accordingly.

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

  ViewVC Help
Powered by ViewVC 1.1.26