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

  ViewVC Help
Powered by ViewVC 1.1.26