/[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 69 - (show annotations)
Tue Jan 3 16:42:06 2006 UTC (16 years, 11 months ago) by dpavlin
File size: 13448 byte(s)
0.07_3 which works on FreeBSD (tests are still broken)
1 package Fuse;
2
3 use 5.006;
4 use strict;
5 use warnings;
6 use Errno;
7 use Carp;
8 use Config;
9
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 our %EXPORT_TAGS = (
24 'all' => [ qw(XATTR_CREATE XATTR_REPLACE) ],
25 'xattr' => [ qw(XATTR_CREATE XATTR_REPLACE) ]
26 );
27
28 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29
30 our @EXPORT = ();
31 our $VERSION = '0.07_3';
32
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 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 bootstrap Fuse $VERSION;
76
77 sub main {
78 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 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, threaded=>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 => \"main::my_getattr\", ...)" unless $subref;
96 $subs[$mapping{$name}] = $subref;
97 }
98 }
99 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 }
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 Fuse::main(mountpoint=>$mountpoint, getattr=>"main::my_getattr", getdir=>"main::my_getdir", ...);
141
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 =head2 EXPORTED SYMBOLS
160
161 None by default.
162
163 You can request all exportable symbols by using the tag ":all".
164
165 You can request the extended attribute symbols by using the tag ":xattr".
166 This will export XATTR_CREATE and XATTR_REPLACE.
167
168 =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 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 threaded => boolean
212
213 =over 1
214
215 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
226 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
233 (If enabled, this option will cause a warning if your perl interpreter was not
234 built with USE_ITHREADS, or if you have failed to use threads or
235 threads::shared.)
236
237 =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 =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 =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