/[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 123 - (show annotations)
Wed Mar 19 19:40:20 2008 UTC (16 years ago) by dpavlin
File size: 13622 byte(s)
another try to fix files larger than 2Gb: for this we pop
float from stack since long is limited to 4Gb
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 fuse_get_context) ],
25 'xattr' => [ qw(XATTR_CREATE XATTR_REPLACE) ]
26 );
27
28 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29
30 our @EXPORT = ();
31 our $VERSION = '0.09_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 @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 my @validOpts = qw(ro allow_other default_permissions fsname use_ino nonempty);
83 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 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 croak "Usage: Fuse::main(getattr => \"main::my_getattr\", ...)" unless $subref;
95 $subs[$mapping{$name}] = $subref;
96 }
97 }
98 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 }
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 perl_fuse_main(@otherargs{@otherargs},@subs);
122 }
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 Fuse::main(mountpoint=>$mountpoint, getattr=>"main::my_getattr", getdir=>"main::my_getdir", ...);
139
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 =head2 EXPORTED SYMBOLS
158
159 None by default.
160
161 You can request all exportable symbols by using the tag ":all".
162
163 You can request the extended attribute symbols by using the tag ":xattr".
164 This will export XATTR_CREATE and XATTR_REPLACE.
165
166 =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 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 threaded => boolean
210
211 =over 1
212
213 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
224 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
231 (If enabled, this option will cause a warning if your perl interpreter was not
232 built with USE_ITHREADS, or if you have failed to use threads or
233 threads::shared.)
234
235 =back
236
237 =head3 Fuse::fuse_get_context
238
239 use Fuse "fuse_get_context";
240 my $caller_uid = fuse_get_context()->{"uid"};
241 my $caller_gid = fuse_get_context()->{"gid"};
242 my $caller_pid = fuse_get_context()->{"pid"};
243
244 Access context information about the current Fuse operation.
245
246 =head2 FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT
247
248 =head3 getattr
249
250 Arguments: filename.
251 Returns a list, very similar to the 'stat' function (see
252 perlfunc). On error, simply return a single numeric scalar
253 value (e.g. "return -ENOENT();").
254
255 FIXME: the "ino" field is currently ignored. I tried setting it to 0
256 in an example script, which consistently caused segfaults.
257
258 Fields (the following was stolen from perlfunc(1) with apologies):
259
260 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
261 $atime,$mtime,$ctime,$blksize,$blocks)
262 = getattr($filename);
263
264 Here are the meaning of the fields:
265
266 0 dev device number of filesystem
267 1 ino inode number
268 2 mode file mode (type and permissions)
269 3 nlink number of (hard) links to the file
270 4 uid numeric user ID of file's owner
271 5 gid numeric group ID of file's owner
272 6 rdev the device identifier (special files only)
273 7 size total size of file, in bytes
274 8 atime last access time in seconds since the epoch
275 9 mtime last modify time in seconds since the epoch
276 10 ctime inode change time (NOT creation time!) in seconds
277 since the epoch
278 11 blksize preferred block size for file system I/O
279 12 blocks actual number of blocks allocated
280
281 (The epoch was at 00:00 January 1, 1970 GMT.)
282
283 =head3 readlink
284
285 Arguments: link pathname.
286 Returns a scalar: either a numeric constant, or a text string.
287
288 This is called when dereferencing symbolic links, to learn the target.
289
290 example rv: return "/proc/self/fd/stdin";
291
292 =head3 getdir
293
294 Arguments: Containing directory name.
295 Returns a list: 0 or more text strings (the filenames), followed by a numeric errno (usually 0).
296
297 This is used to obtain directory listings. Its opendir(), readdir(), filldir() and closedir() all in one call.
298
299 example rv: return ('.', 'a', 'b', 0);
300
301 =head3 mknod
302
303 Arguments: Filename, numeric modes, numeric device
304 Returns an errno (0 upon success, as usual).
305
306 This function is called for all non-directory, non-symlink nodes,
307 not just devices.
308
309 =head3 mkdir
310
311 Arguments: New directory pathname, numeric modes.
312 Returns an errno.
313
314 Called to create a directory.
315
316 =head3 unlink
317
318 Arguments: Filename.
319 Returns an errno.
320
321 Called to remove a file, device, or symlink.
322
323 =head3 rmdir
324
325 Arguments: Pathname.
326 Returns an errno.
327
328 Called to remove a directory.
329
330 =head3 symlink
331
332 Arguments: Existing filename, symlink name.
333 Returns an errno.
334
335 Called to create a symbolic link.
336
337 =head3 rename
338
339 Arguments: old filename, new filename.
340 Returns an errno.
341
342 Called to rename a file, and/or move a file from one directory to another.
343
344 =head3 link
345
346 Arguments: Existing filename, hardlink name.
347 Returns an errno.
348
349 Called to create hard links.
350
351 =head3 chmod
352
353 Arguments: Pathname, numeric modes.
354 Returns an errno.
355
356 Called to change permissions on a file/directory/device/symlink.
357
358 =head3 chown
359
360 Arguments: Pathname, numeric uid, numeric gid.
361 Returns an errno.
362
363 Called to change ownership of a file/directory/device/symlink.
364
365 =head3 truncate
366
367 Arguments: Pathname, numeric offset.
368 Returns an errno.
369
370 Called to truncate a file, at the given offset.
371
372 =head3 utime
373
374 Arguments: Pathname, numeric actime, numeric modtime.
375 Returns an errno.
376
377 Called to change access/modification times for a file/directory/device/symlink.
378
379 =head3 open
380
381 Arguments: Pathname, numeric flags (which is an OR-ing of stuff like O_RDONLY
382 and O_SYNC, constants you can import from POSIX).
383 Returns an errno.
384
385 No creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be passed to open().
386 Your open() method needs only check if the operation is permitted for the given flags, and return 0 for success.
387
388 =head3 read
389
390 Arguments: Pathname, numeric requestedsize, numeric offset.
391 Returns a numeric errno, or a string scalar with up to $requestedsize bytes of data.
392
393 Called in an attempt to fetch a portion of the file.
394
395 =head3 write
396
397 Arguments: Pathname, scalar buffer, numeric offset. You can use length($buffer) to
398 find the buffersize.
399 Returns an errno.
400
401 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.
402
403 =head3 statfs
404
405 Arguments: none
406 Returns any of the following:
407
408 -ENOANO()
409
410 or
411
412 $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
413
414 or
415
416 -ENOANO(), $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
417
418 =head3 flush
419
420 Arguments: Pathname
421 Returns an errno or 0 on success.
422
423 Called to synchronise any cached data. This is called before the file
424 is closed. It may be called multiple times before a file is closed.
425
426 =head3 release
427
428 Arguments: Pathname, numeric flags passed to open
429 Returns an errno or 0 on success.
430
431 Called to indicate that there are no more references to the file. Called once
432 for every file with the same pathname and flags as were passed to open.
433
434 =head3 fsync
435
436 Arguments: Pathname, numeric flags
437 Returns an errno or 0 on success.
438
439 Called to synchronise the file's contents. If flags is non-zero,
440 only synchronise the user data. Otherwise synchronise the user and meta data.
441
442 =head3 setxattr
443
444 Arguments: Pathname, extended attribute's name, extended attribute's value, numeric flags (which is an OR-ing of XATTR_CREATE and XATTR_REPLACE
445 Returns an errno or 0 on success.
446
447 Called to set the value of the named extended attribute.
448
449 If you wish to reject setting of a particular form of extended attribute name
450 (e.g.: regexps matching user\..* or security\..*), then return - EOPNOTSUPP.
451
452 If flags is set to XATTR_CREATE and the extended attribute already exists,
453 this should fail with - EEXIST. If flags is set to XATTR_REPLACE
454 and the extended attribute doesn't exist, this should fail with - ENOATTR.
455
456 XATTR_CREATE and XATTR_REPLACE are provided by this module, but not exported
457 by default. To import them:
458
459 use Fuse ':xattr';
460
461 or:
462
463 use Fuse ':all';
464
465 =head3 getxattr
466
467 Arguments: Pathname, extended attribute's name
468 Returns an errno, 0 if there was no value, or the extended attribute's value.
469
470 Called to get the value of the named extended attribute.
471
472 =head3 listxattr
473
474 Arguments: Pathname
475 Returns a list: 0 or more text strings (the extended attribute names), followed by a numeric errno (usually 0).
476
477 =head3 removexattr
478
479 Arguments: Pathname, extended attribute's name
480 Returns an errno or 0 on success.
481
482 =head1 AUTHOR
483
484 Mark Glines, E<lt>mark@glines.orgE<gt>
485
486 =head1 SEE ALSO
487
488 L<perl>, the FUSE documentation.
489
490 =cut

  ViewVC Help
Powered by ViewVC 1.1.26