• R/O
  • SSH
  • HTTPS

perl-fuse-fv: 提交


Commit MetaInfo

修订版81 (tree)
时间2011-12-23 17:03:12
作者tofjw

Log Message

Fuse::Class 0.02

更改概述

差异

--- Fuse-Class/tags/Fuse-Class-0.02/test/fuse28.pm (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/test/fuse28.pm (revision 81)
@@ -0,0 +1,735 @@
1+#
2+# test filesystem for Fuse 2.8
3+# (file operations are done via file/directory handle.)
4+#
5+
6+use strict;
7+use warnings;
8+
9+use Fcntl;
10+use Errno;
11+
12+package test::fuse28;
13+
14+use base qw(Fuse::Class);
15+
16+sub new {
17+ my $class = shift;
18+
19+ my $self = {
20+ root => test::fuse28::Directory->new,
21+
22+ handle => {
23+ }
24+ };
25+
26+ return bless $self, $class;
27+}
28+
29+sub issue_handle {
30+ my $self = shift;
31+ my $obj = shift;
32+
33+ my $i = 0;
34+ while ($self->{handle}->{$i}) {
35+ $i++;
36+ }
37+
38+ $self->{handle}->{$i} = $obj;
39+
40+ return $i;
41+}
42+
43+sub release_handle {
44+ my $self = shift;
45+ my ($fh) = @_;
46+
47+ delete $self->{handle}->{$fh};
48+}
49+
50+sub pickup {
51+ my $self = shift;
52+ my $path = shift;
53+
54+ my $ret = $self->{root};
55+
56+ for my $e (split('/', $path)) {
57+ next if ($e eq '');
58+
59+ if ($ret->isa('test::fuse28::Directory')) {
60+ if ($e eq '..') {
61+ $ret = $ret->parent;
62+ }
63+ elsif ($e eq '.') {
64+ ; # nothing
65+ }
66+ else {
67+ $ret = $ret->entity($e);
68+ }
69+ }
70+ else {
71+ return undef;
72+ }
73+ }
74+
75+ return $ret;
76+}
77+
78+sub init {
79+ # print STDERR "perl28.pm is started\n";
80+ return "perl28";
81+}
82+
83+# I don't know when this method is called...?
84+sub destroy {
85+ my $param = shift;
86+ print STDERR "$param is ended\n";
87+}
88+
89+sub fgetattr {
90+ my $self = shift;
91+ my ($path, $fh) = @_;
92+
93+ my $entity = $self->{handle}->{$fh};
94+ return (-2) unless ($entity);
95+ return (-1) unless ($entity->can('attr'));
96+
97+ $entity->attr;
98+}
99+
100+sub getattr {
101+ my $self = shift;
102+ my ($path) = @_;
103+
104+ my $entity = $self->pickup($path);
105+ return -2 unless ($entity);
106+
107+ return $entity->attr;
108+}
109+
110+sub readlink {
111+ my $self = shift;
112+ my ($path) = @_;
113+
114+ my $entity = $self->pickup($path);
115+ return -2 unless ($entity);
116+ return -1 unless ($entity->can('readlink'));
117+
118+ return $entity->readlink;
119+}
120+
121+sub getdir {
122+ my $self = shift;
123+ my ($path) = @_;
124+
125+ # die "this function must not be called.";
126+ return -1;
127+}
128+
129+sub mknod {
130+ my $self = shift;
131+ my ($path, $mode, $devno) = @_;
132+
133+ my ($dirname, $name) = ($path =~ m/^(.*)\/([^\/]+)$/);
134+ return -2 unless (defined($dirname) && defined($name)); # badname ?
135+
136+ my $dir = $self->pickup($dirname);
137+ return -2 unless ($dir);
138+
139+ return $dir->mknod($name, $mode, $devno);
140+}
141+
142+sub mkdir {
143+ my $self = shift;
144+ my ($path, $mode) = @_;
145+
146+ my ($dirname, $name) = ($path =~ m/^(.*)\/([^\/]+)$/);
147+ return -2 unless (defined($dirname) && defined($name)); # badname ?
148+
149+ my $dir = $self->pickup($dirname);
150+ return -2 unless ($dir);
151+
152+ return $dir->mkdir($name, $mode);
153+}
154+
155+sub unlink {
156+ my $self = shift;
157+ my ($path) = @_;
158+
159+ my ($dirname, $name) = ($path =~ m/^(.*)\/([^\/]+)$/);
160+ return -2 unless (defined($dirname) && defined($name)); # badname ?
161+
162+ my $dir = $self->pickup($dirname);
163+ return -2 unless ($dir);
164+
165+ return $dir->unlink($name);
166+}
167+
168+sub rmdir {
169+ my $self = shift;
170+ my ($path) = @_;
171+
172+ my ($dirname, $name) = ($path =~ m/^(.*)\/([^\/]+)$/);
173+ return -2 unless (defined($dirname) && defined($name)); # badname ?
174+
175+ my $dir = $self->pickup($dirname);
176+ return -2 unless ($dir);
177+
178+ return $dir->rmdir($name);
179+}
180+
181+sub symlink {
182+ my $self = shift;
183+ my ($existing, $symlink) = @_;
184+
185+ my ($dirname, $name) = ($symlink =~ m/^(.*)\/([^\/]+)$/);
186+ return -2 unless (defined($dirname) && defined($name)); # badname ?
187+
188+ my $dir = $self->pickup($dirname);
189+ return -2 unless ($dir);
190+
191+ return $dir->symlink($name, $existing);
192+}
193+
194+sub rename {
195+ my $self = shift;
196+ my ($old_name, $new_name) = @_;
197+
198+ my ($dirname1, $name1) = ($old_name =~ m/^(.*)\/([^\/]+)$/);
199+ return -2 unless (defined($dirname1) && defined($name1)); # badname ?
200+
201+ my ($dirname2, $name2) = ($new_name =~ m/^(.*)\/([^\/]+)$/);
202+ return -2 unless (defined($dirname2) && defined($name2)); # badname ?
203+
204+ my $dir1 = $self->pickup($dirname1);
205+ return -2 unless ($dir1);
206+
207+ my $dir2 = $self->pickup($dirname2);
208+ return -2 unless ($dir2);
209+
210+ return $dir1->rename($name1, $dir2, $name2);
211+}
212+
213+sub opendir {
214+ my $self = shift;
215+ my ($path) = @_;
216+
217+ my $entity = $self->pickup($path);
218+ return (-2) unless ($entity);
219+
220+ if ($entity->isa('test::fuse28::Directory')) {
221+ my $fh = $self->issue_handle($entity);
222+ return (0, $fh);
223+ }
224+ else {
225+ return (-2);
226+ }
227+}
228+
229+sub readdir {
230+ my $self = shift;
231+ my ($path, $offset, $dh) = @_;
232+
233+ if ($path eq '/test/readdir-type-1') {
234+ return $self->readdir_test_type_1(@_);
235+ }
236+ elsif ($path eq '/test/readdir-type-2') {
237+ return $self->readdir_test_type_2(@_);
238+ }
239+
240+ my $dir = $self->{handle}->{$dh};
241+ return (-2) unless ($dir);
242+
243+ my @names = $dir->readdir;
244+
245+ if ($offset < $#names) {
246+ return (@names[$offset..$#names], 0);
247+ }
248+
249+ return (0);
250+}
251+
252+sub readdir_test_type_1 {
253+ my $self = shift;
254+ my ($path, $offset, $dh) = @_;
255+
256+ my $dir = $self->{handle}->{$dh};
257+ return (-2) unless ($dir);
258+
259+ # print STDERR "readdir_test_type_1, path=$path, offset=$offset\n";
260+
261+ my $i = 1;
262+ my @list;
263+
264+ foreach my $name ($dir->readdir) {
265+ push(@list, [$i++, $name]);
266+ }
267+
268+ if ($offset < $#list) {
269+ return (@list[$offset..$#list], 0);
270+ }
271+
272+ return (0);
273+}
274+
275+sub readdir_test_type_2 {
276+ my $self = shift;
277+ my ($path, $offset, $dh) = @_;
278+
279+ my $dir = $self->{handle}->{$dh};
280+ return (-2) unless ($dir);
281+
282+ # print STDERR "readdir_test_type_2, path=$path, offset=$offset\n";
283+
284+ my $i = 1;
285+ my @list;
286+
287+ foreach my $name ($dir->readdir) {
288+ my $entity = $self->pickup("$path/$name");
289+ next unless ($entity);
290+
291+ push(@list, [$i++, $name, [$entity->attr]]);
292+ }
293+
294+ if ($offset < $#list) {
295+ return (@list[$offset..$#list], 0);
296+ }
297+
298+ return (0);
299+}
300+
301+sub releasedir {
302+ my $self = shift;
303+ my ($path, $dh) = @_;
304+
305+ if ($self->{handle}->{$dh}) {
306+ $self->release_handle($dh);
307+ return 0;
308+ }
309+
310+ return -2;
311+}
312+
313+sub chmod {
314+ my $self = shift;
315+ my ($path, $modes) = @_;
316+
317+ my $entity = $self->pickup($path);
318+ return -2 unless ($entity);
319+
320+ $entity->chmod($modes);
321+}
322+
323+sub chown {
324+ my $self = shift;
325+ my ($path, $uid, $gid) = @_;
326+
327+ my $entity = $self->pickup($path);
328+ return -2 unless ($entity);
329+
330+ $entity->chown($uid, $gid);
331+}
332+
333+sub ftruncate {
334+ my $self = shift;
335+ my ($path, $offset, $fh) = @_;
336+
337+ my $entity = $self->{handle}->{$fh};
338+ return (-2) unless ($entity);
339+ return (-1) unless ($entity->can('truncate'));
340+
341+ $entity->truncate($offset);
342+}
343+
344+sub truncate {
345+ my $self = shift;
346+ my ($path, $offset) = @_;
347+
348+ my $entity = $self->pickup($path);
349+ return -2 unless ($entity);
350+ return -1 unless ($entity->can('truncate'));
351+
352+ $entity->truncate($offset);
353+}
354+
355+sub utime {
356+ my $self = shift;
357+ my ($path, $atime, $mtime) = @_;
358+
359+ # die "utimens must be called";
360+ return -1;
361+}
362+
363+sub open {
364+ my $self = shift;
365+ my ($path, $flags, $fileinfo) = @_;
366+
367+ my $entity = $self->pickup($path);
368+ return (-2) unless ($entity);
369+
370+ return (0, $self->issue_handle($entity));
371+}
372+
373+sub write {
374+ my $self = shift;
375+ my ($path, $buffer, $offset, $fh) = @_;
376+
377+ my $entity = $self->{handle}->{$fh};
378+ return (-2) unless ($entity);
379+ return (-1) unless ($entity->can('write'));
380+
381+ $entity->write($buffer, $offset);
382+}
383+
384+sub read {
385+ my $self = shift;
386+ my ($path, $size, $offset, $fh) = @_;
387+
388+ my $entity = $self->{handle}->{$fh};
389+ return (-2) unless ($entity);
390+ return (-1) unless ($entity->can('read'));
391+
392+ $entity->read($size, $offset);
393+}
394+
395+sub statfs {
396+ my $self = shift;
397+
398+ return (255, 50000, 40000, 30000, 20000, 10000);
399+}
400+
401+sub utimens {
402+ my $self = shift;
403+ my ($path, $atime, $mtime) = @_;
404+
405+ my $entity = $self->pickup($path);
406+ return -2 unless ($entity);
407+
408+ return $entity->utimens($atime, $mtime);
409+}
410+
411+sub access {
412+ my $self = shift;
413+ my ($path, $mode) = @_;
414+
415+ if ($path eq '/test/access_no_perm') {
416+ # if exsits, it's not accesible!!
417+ return -Errno::EPERM() if $self->pickup($path);
418+ }
419+
420+ return 0;
421+}
422+
423+sub create {
424+ my $self = shift;
425+ my ($path, $mask, $mode) = @_;
426+ my ($dirname, $name) = ($path =~ m/^(.*)\/([^\/]+)$/);
427+ return -2 unless (defined($dirname) && defined($name)); # badname ?
428+
429+ my $dir = $self->pickup($dirname);
430+ return -2 unless ($dir);
431+
432+ return Errno::EXISTS if ($self->pickup($path));
433+
434+ my $ret = $dir->mknod($name, $mask, 0);
435+ return ($ret) if ($ret != 0);
436+
437+ my $entity = $self->pickup($path);
438+ return (-2) unless ($entity);
439+
440+ return (0, $self->issue_handle($entity));
441+}
442+
443+package test::fuse28::Entity;
444+
445+my $last_ino = 0;
446+
447+sub new {
448+ my $class = shift;
449+
450+ my $t = time;
451+
452+ my $self = {
453+ # ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
454+ # $atime,$mtime,$ctime,$blksize,$blocks)
455+ attr => [0, $last_ino++, 0, 1, $>+0, $)+0, 0, 0,
456+ $t, $t, $t, 1024, 0],
457+ };
458+
459+ $self->{attr}->[8] = $t;
460+ $self->{attr}->[9] = $t;
461+ $self->{attr}->[10] = $t;
462+
463+ bless $self, $class;
464+}
465+
466+sub attr {
467+ my $self = shift;
468+ return @{$self->{attr}};
469+}
470+
471+sub chmod {
472+ my $self = shift;
473+ my ($modes) = @_;
474+
475+ my $attr = $self->{attr}->[2] & ~(07777);
476+ $self->{attr}->[2] = $attr | $modes;
477+
478+ return 0;
479+}
480+
481+sub utimens {
482+ my $self = shift;
483+ my ($atime, $mtime) = @_;
484+
485+ my $attr = $self->{attr};
486+ $attr->[8] = $atime if ($atime >= 0);
487+ $attr->[9] = $mtime if ($mtime >= 0);
488+
489+ return 0;
490+}
491+
492+sub chown {
493+ my $self = shift;
494+ my ($uid, $gid) = @_;
495+
496+ $self->{attr}->[4] = $uid if ($uid >= 0);
497+ $self->{attr}->[5] = $gid if ($gid >= 0);
498+
499+ return 0;
500+}
501+
502+#
503+# Directory
504+#
505+package test::fuse28::Directory;
506+
507+use Fcntl qw(:mode);
508+use base qw(test::fuse28::Entity);
509+use Scalar::Util qw(weaken);
510+
511+sub new {
512+ my $class = shift;
513+ my $parent = shift;
514+
515+ my $self = $class->SUPER::new;
516+ $self->{attr}->[2] = S_IFDIR | S_IRWXU;
517+
518+ if (!defined($parent)) {
519+ $self->{parent} = $self;
520+ }
521+ else {
522+ $self->{parent} = $parent;
523+ }
524+
525+ $self->{children} = {};
526+
527+ # avoid cyclic reference
528+ weaken($self->{parent});
529+
530+ bless $self, $class;
531+}
532+
533+sub parent {
534+ my $self = shift;
535+ return $self->{parent};
536+}
537+
538+sub entity {
539+ my $self = shift;
540+ my $name = shift;
541+
542+ return $self if ($name eq '.');
543+ return $self->parent if ($name eq '..');
544+
545+ return $self->{children}->{$name};
546+}
547+
548+sub readdir {
549+ my $self = shift;
550+ return ('..', '.', keys %{$self->{children}});
551+}
552+
553+sub mknod {
554+ my $self = shift;
555+ my ($name, $mode, $devno) = @_;
556+
557+ my $umask = 0;
558+ $umask |= S_IRUSR if ($mode & 0400);
559+ $umask |= S_IWUSR if ($mode & 0200);
560+ $umask |= S_IXUSR if ($mode & 0100);
561+ $umask |= S_IRGRP if ($mode & 0040);
562+ $umask |= S_IWGRP if ($mode & 0020);
563+ $umask |= S_IXGRP if ($mode & 0010);
564+ $umask |= S_IROTH if ($mode & 0004);
565+ $umask |= S_IWOTH if ($mode & 0002);
566+ $umask |= S_IXOTH if ($mode & 0001);
567+
568+ if (S_ISREG($mode)) {
569+ my $newfile = test::fuse28::File->new;
570+ my $attr = S_IFREG | $umask;
571+ $newfile->{attr}->[2] = $attr;
572+ $self->{children}->{$name} = $newfile;
573+ return 0;
574+ }
575+ if (S_ISDIR($mode)) {
576+ return $self->mkdir($name, $mode);
577+ }
578+
579+ if (S_ISLNK($mode)) {
580+ return -1;
581+ }
582+ if (S_ISBLK($mode)) {
583+ return -1;
584+ }
585+ if (S_ISCHR($mode)) {
586+ return -1;
587+ }
588+ if (S_ISFIFO($mode)) {
589+ return -1;
590+ }
591+ if (S_ISSOCK($mode)) {
592+ return -1;
593+ }
594+
595+ return -1;
596+}
597+
598+sub mkdir {
599+ my $self = shift;
600+ my ($name, $mode) = @_;
601+
602+ my $newdir = test::fuse28::Directory->new($self);
603+ my $attr = S_IFDIR;
604+ $attr |= S_IRUSR if ($mode & 0400);
605+ $attr |= S_IWUSR if ($mode & 0200);
606+ $attr |= S_IXUSR if ($mode & 0100);
607+ $attr |= S_IRGRP if ($mode & 0040);
608+ $attr |= S_IWGRP if ($mode & 0020);
609+ $attr |= S_IXGRP if ($mode & 0010);
610+ $attr |= S_IROTH if ($mode & 0004);
611+ $attr |= S_IWOTH if ($mode & 0002);
612+ $attr |= S_IXOTH if ($mode & 0001);
613+ $newdir->{attr}->[2] = $attr;
614+
615+ $self->{children}->{$name} = $newdir;
616+
617+ return 0;
618+}
619+
620+sub unlink {
621+ my $self = shift;
622+ my ($name) = @_;
623+
624+ my $entity = $self->{children}->{$name};
625+ return -2 unless ($entity);
626+ delete $self->{children}->{$name};
627+
628+ return 0;
629+}
630+
631+sub rmdir {
632+ my $self = shift;
633+ my ($name) = @_;
634+
635+ my $entity = $self->{children}->{$name};
636+ return -2 unless ($entity);
637+ delete $self->{children}->{$name};
638+
639+ return 0;
640+}
641+
642+sub rename {
643+ my $self = shift;
644+ my ($old_name, $new_dir, $new_name) = @_;
645+
646+ my $entity = $self->{children}->{$old_name};
647+ return -2 unless ($entity);
648+
649+ delete $self->{children}->{$old_name};
650+ $new_dir->{children}->{$new_name} = $entity;
651+
652+ return 0;
653+}
654+
655+sub symlink {
656+ my $self = shift;
657+ my ($name, $existing) = @_;
658+
659+ my $link = test::fuse28::Symlink->new($existing);
660+ my $attr = S_IFLNK | 0777;
661+ $link->{attr}->[2] = $attr;
662+ $self->{children}->{$name} = $link;
663+
664+ return 0;
665+}
666+
667+#
668+# Normal File
669+#
670+package test::fuse28::File;
671+
672+use base qw(test::fuse28::Entity);
673+
674+sub new {
675+ my $class = shift;
676+
677+ my $self = $class->SUPER::new;
678+ $self->{content} = '';
679+
680+ bless $self, $class;
681+}
682+
683+sub write {
684+ my $self = shift;
685+ my ($buffer, $offset) = @_;
686+
687+ substr($self->{content}, $offset) = $buffer;
688+ $self->{attr}->[7] = length($self->{content});
689+ $self->{attr}->[12] = int(($self->{attr}->[7] + $self->{attr}->[11] - 1) / $self->{attr}->[11]);
690+
691+ return length($buffer);
692+}
693+
694+sub read {
695+ my $self = shift;
696+ my ($size, $offset) = @_;
697+
698+ return substr($self->{content}, $offset, $size);
699+}
700+
701+sub truncate {
702+ my $self = shift;
703+ my ($offset) = @_;
704+
705+ $self->{content} = substr($self->{content}, 0, $offset);
706+ $self->{attr}->[7] = length($self->{content});
707+
708+ return 0;
709+}
710+
711+#
712+# Symlink
713+#
714+package test::fuse28::Symlink;
715+
716+use base qw(test::fuse28::Entity);
717+use Scalar::Util qw(weaken);
718+
719+sub new {
720+ my $class = shift;
721+ my ($existing) = @_;
722+
723+ my $self = $class->SUPER::new;
724+ $self->{link} = $existing;
725+
726+ bless $self, $class;
727+}
728+
729+sub readlink {
730+ my $self = shift;
731+
732+ return $self->{link};
733+}
734+
735+1;
--- Fuse-Class/tags/Fuse-Class-0.02/test/test-run.pl (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/test/test-run.pl (revision 81)
@@ -0,0 +1,29 @@
1+#!/usr/local/bin/perl
2+
3+#
4+# You can mount 'fuse28.pm' filesystem by running this script.
5+#
6+
7+use strict;
8+use lib '..';
9+use lib '../blib/lib';
10+use lib '../blib/arch/auto';
11+
12+use Cwd qw(abs_path);
13+
14+use Fuse;
15+use test::fuse28;
16+
17+my $mount_point = abs_path('mnt');
18+
19+#
20+# make mount point if not exists
21+#
22+
23+-d $mount_point || mkdir $mount_point, 0777;
24+
25+print "fuse version: ", Fuse::fuse_version, "\n";
26+print "To umount, run:\n fusermount -u $mount_point\nfrom other terminal.\n";
27+my $fs = new test::fuse28;
28+$fs->main(mountpoint => $mount_point,
29+ debug=>1);
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
--- Fuse-Class/tags/Fuse-Class-0.02/t/80fuse28.t (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/t/80fuse28.t (revision 81)
@@ -0,0 +1,233 @@
1+#
2+# test filesystem using test::fuse28.pm test mudule
3+#
4+
5+use strict;
6+use POSIX ":sys_wait_h";
7+use Test::Class;
8+use Test::More;
9+use Fuse;
10+
11+use test::fuse28;
12+
13+my $mount_point = "/tmp/fuse-class-test-$<-$$";
14+
15+my $reason = "no reason (test error?)";
16+
17+sub start_check {
18+ #
19+ # Fuse version must be 2.8 or later for this test.
20+ #
21+ my $version = Fuse::fuse_version;
22+ if ($version < 2.6) {
23+ $reason = "Fuse version is lower than 2.6.";
24+ return 0;
25+ }
26+
27+ #
28+ # fusermount command is available?
29+ #
30+ my $res = `fusermount -V 2>&1`;
31+ unless ($res =~ /version/) {
32+ $reason = "fusermount command is not available.";
33+ return 0;
34+ }
35+
36+ #
37+ # Test::Virtual::Filesystem
38+ #
39+ eval "use Test::Virtual::Filesystem;";
40+ if ($@) {
41+ $reason = "Test::Virtual::Filesystem is not available.";
42+ return 0;
43+ }
44+
45+ return 1;
46+}
47+
48+#
49+# start Fuse main loop in child process
50+#
51+sub child_process {
52+ mkdir $mount_point, 0777;
53+ diag $mount_point;
54+ die "$mount_point: cannot create directoy: $!" unless (-d $mount_point);
55+
56+ my $fs = new test::fuse28;
57+ $fs->main(mountpoint => $mount_point);
58+}
59+
60+sub cleanup {
61+ my $child_pid = shift;
62+
63+ my $kid = 0;
64+ my $n = 0;
65+ do {
66+ system("fusermount", "-u", $mount_point);
67+ sleep(1);
68+ $kid = waitpid $child_pid, WNOHANG;
69+ } while($kid != $child_pid && $n++ < 10);
70+
71+ rmdir $mount_point;
72+}
73+
74+#
75+# test start
76+#
77+unless (start_check) {
78+ plan skip_all => $reason;
79+}
80+else {
81+ eval "use Test::Virtual::Filesystem;";
82+ my $child_pid = -1;
83+
84+ eval {
85+ plan tests => 165;
86+
87+ $child_pid = fork();
88+ die $! if ($child_pid < 0);
89+
90+ if ($child_pid == 0) {
91+ child_process;
92+ exit 0;
93+ }
94+
95+ sleep(3);
96+
97+ my $test = Test::Virtual::Filesystem->new({mountdir => $mount_point,
98+ compatible => '0.08'});
99+ $test->enable_test_xattr(0);
100+ $test->enable_test_time(1);
101+ # $test->enable_test_atime(1);
102+ # $test->enable_test_mtime(1);
103+ # $test->enable_test_ctime(1);
104+ $test->enable_test_permissions(0);
105+ $test->enable_test_special(0);
106+ # $test->enable_test_fifo(0);
107+ $test->enable_test_symlink(1);
108+ # $test->enable_test_hardlink(0);
109+ # $test->enable_test_nlink(0);
110+ # $test->enable_test_chown(0);
111+
112+ $test->runtests;
113+
114+ # unlink
115+ {
116+ my $fname = "$mount_point/unlink-test";
117+ unlink $fname;
118+ open(my $fh, "> $fname");
119+ close($fh);
120+
121+ ok(-f $fname);
122+ unlink $fname;
123+ ok(!-f $fname);
124+ }
125+
126+ # chmod
127+ {
128+ my $fname = "$mount_point/chmod-test";
129+ unlink $fname;
130+ open(my $fh, "> $fname");
131+ close($fh);
132+ chmod(0642, $fname);
133+ my $perm = (stat $fname)[2] & 0777;
134+ ok($perm == 0642);
135+ }
136+
137+ # ftrunate
138+ {
139+ my $fname = "$mount_point/ftruncate-test";
140+ unlink $fname;
141+ open(my $fh1, "> $fname");
142+ print $fh1 "12345";
143+ close($fh1);
144+
145+ open(my $fh2, "+< $fname");
146+ truncate($fh2, 3);
147+ close($fh2);
148+
149+ my $size = (stat $fname)[7];
150+ ok($size == 3);
151+ }
152+
153+ # readdir (1)
154+ {
155+ my $test_dir = "$mount_point/test";
156+ my $test_dir_1 = "$test_dir/readdir-type-1";
157+ mkdir $test_dir, 0777;
158+ mkdir $test_dir_1, 0777;
159+
160+ opendir(my $dh, $test_dir_1);
161+
162+ my @entries;
163+ while(readdir $dh) {
164+ push(@entries, $_);
165+ }
166+ is(scalar @entries, 2);
167+ is(scalar(grep { $_ eq '..' } @entries), 1);
168+ is(scalar(grep { $_ eq '.' } @entries), 1);
169+ }
170+
171+ # readdir (2)
172+ {
173+ my $test_dir = "$mount_point/test";
174+ my $test_dir_2 = "$test_dir/readdir-type-2";
175+ mkdir $test_dir, 0777;
176+ mkdir $test_dir_2, 0777;
177+
178+ opendir(my $dh, $test_dir_2);
179+
180+ my @entries;
181+ while(readdir $dh) {
182+ push(@entries, $_);
183+ }
184+
185+ is(scalar @entries, 2);
186+ is(scalar(grep { $_ eq '..' } @entries), 1);
187+ is(scalar(grep { $_ eq '.' } @entries), 1);
188+ }
189+
190+ # access
191+ {
192+ use POSIX;
193+
194+ my $test_dir = "$mount_point/test";
195+ mkdir $test_dir, 0777;
196+
197+ my $test_dir_bad = "$test_dir/access_no_perm";
198+ mkdir $test_dir_bad, 0777;
199+ my $test_dir_ok = "$test_dir/access_with_perm";
200+ mkdir $test_dir_ok, 0777;
201+
202+ ok(!POSIX::access($test_dir_bad, &POSIX::R_OK));
203+ ok(POSIX::access($test_dir_ok, &POSIX::R_OK));
204+ }
205+
206+ # ftruncate & fgetattr
207+ {
208+ my $test_dir = "$mount_point/test";
209+ mkdir $test_dir, 0777;
210+
211+ my $file = "$test_dir/ftruncate_test";
212+ open(my $fh1, ">", $file);
213+ print $fh1 "hello world\n";
214+ close($fh1);
215+
216+ open(my $fh2, "+<", $file);
217+ truncate($fh2, 3);
218+
219+ my @st = stat($fh2);
220+ is($st[7], 3);
221+
222+ close($fh2);
223+
224+ @st = stat($file);
225+ is($st[7], 3);
226+ }
227+ };
228+
229+ my $err = $@;
230+ cleanup($child_pid);
231+
232+ die $err if ($err);
233+}
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
--- Fuse-Class/tags/Fuse-Class-0.02/t/10subclass.t (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/t/10subclass.t (revision 81)
@@ -0,0 +1,89 @@
1+
2+use strict;
3+
4+use Test::More tests => 14;
5+
6+#################################################
7+package TestClass;
8+
9+use base qw(Fuse::Class);
10+
11+sub getdir {
12+ my $self = shift;
13+ my ($dir) = @_;
14+
15+ return (".", "..", "x$dir", 0);
16+}
17+
18+sub mknod {
19+ my $self = shift;
20+ my ($fname) = @_;
21+
22+ $! = Errno::EINTR;
23+ die "error";
24+}
25+
26+sub mkdir {
27+ my $self = shift;
28+ my ($fname) = @_;
29+
30+ $! = 0;
31+ die "error";
32+}
33+
34+#################################################
35+
36+package main;
37+
38+my %Fuse_main;
39+
40+#
41+# override Fuse::main for test
42+#
43+{
44+ no warnings "redefine";
45+ no strict "refs";
46+
47+ *Fuse::main = sub {
48+ %Fuse_main = @_;
49+ for my $k (keys %Fuse_main) {
50+ my $subname = $Fuse_main{$k};
51+ $Fuse_main{$k} = sub { &$subname(@_); };
52+ }
53+ };
54+}
55+
56+use Errno;
57+
58+my $fs = TestClass->new();
59+is(ref($fs), "TestClass", "constructor");
60+
61+$fs->main(mountpoint => "/never-found");
62+$Fuse::Class::_Module = $fs; # set in Fuse::Class
63+
64+# overrided method
65+my $getdir = $Fuse_main{getdir};
66+is_deeply([&$getdir("abc")], [".", "..", "xabc", 0]);
67+
68+# error (in $!)
69+my $mknod = $Fuse_main{mknod};
70+is(&$mknod("/never-found"), -Errno::EINTR());
71+
72+# error (not in $!)
73+my $mkdir = $Fuse_main{mkdir};
74+is(&$mkdir("/never-found"), -Errno::EPERM());
75+
76+# not implemented
77+my $getattr = $Fuse_main{getattr};
78+is($fs->can('getattr') ? &$getattr("/") : -Errno::EPERM(), -Errno::EPERM());
79+
80+# default implement
81+is($fs->readlink("/not/found"), -Errno::ENOENT());
82+is($fs->statfs(), -Errno::ENOANO());
83+is($fs->flush("/some/file"), 0);
84+is($fs->release("/some/file"), 0);
85+is($fs->fsync("/some/file"), 0);
86+is($fs->getxattr("/some/file"), 0);
87+is($fs->listxattr("/some/file"), 0);
88+is($fs->removexattr("/some/file"), 0);
89+is($fs->setxattr("/some/file", "name", "value", 0), -Errno::EOPNOTSUPP());
--- Fuse-Class/tags/Fuse-Class-0.02/t/pod.t (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/t/pod.t (revision 81)
@@ -0,0 +1,12 @@
1+#!perl -T
2+
3+use strict;
4+use warnings;
5+use Test::More;
6+
7+# Ensure a recent version of Test::Pod
8+my $min_tp = 1.22;
9+eval "use Test::Pod $min_tp";
10+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
11+
12+all_pod_files_ok();
--- Fuse-Class/tags/Fuse-Class-0.02/t/pod-coverage.t (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/t/pod-coverage.t (revision 81)
@@ -0,0 +1,18 @@
1+use strict;
2+use warnings;
3+use Test::More;
4+
5+# Ensure a recent version of Test::Pod::Coverage
6+my $min_tpc = 1.08;
7+eval "use Test::Pod::Coverage $min_tpc";
8+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
9+ if $@;
10+
11+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
12+# but older versions don't recognize some common documentation styles
13+my $min_pc = 0.18;
14+eval "use Pod::Coverage $min_pc";
15+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
16+ if $@;
17+
18+all_pod_coverage_ok();
--- Fuse-Class/tags/Fuse-Class-0.02/t/00-load.t (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/t/00-load.t (revision 81)
@@ -0,0 +1,9 @@
1+#!perl -T
2+
3+use Test::More tests => 1;
4+
5+BEGIN {
6+ use_ok( 'Fuse::Class' );
7+}
8+
9+diag( "Testing Fuse::Class $Fuse::Class::VERSION, Perl $], $^X" );
--- Fuse-Class/tags/Fuse-Class-0.02/lib/Fuse/Class.pm (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/lib/Fuse/Class.pm (revision 81)
@@ -0,0 +1,649 @@
1+#
2+# Fuse::Class
3+#
4+# For implementation using class.
5+#
6+
7+package Fuse::Class;
8+
9+use warnings;
10+use strict;
11+
12+=head1 NAME
13+
14+Fuse::Class - Base clsas for Fuse module implementation using class.
15+
16+=head1 VERSION
17+
18+Version 0.02
19+
20+=cut
21+
22+our $VERSION = '0.02';
23+
24+=head1 SYNOPSIS
25+
26+Fuse::Class is just a abstract class. First, you must write subclass
27+overriding methods like named 'getattr'. (callbacks defined in Fuse)
28+
29+Subclass will be written like following:
30+
31+ package SampleFS;
32+
33+ use base qw(Fuse::Class);
34+
35+ sub getattr {
36+ my $self = shift; # instance or class is passed as first argment.
37+ my ($fname) = @_; # same as Fuse.
38+
39+ ...
40+
41+ return @attr; # same as Fuse.
42+ }
43+ ...
44+
45+To mount your filesystem:
46+
47+ use SampleFS;
48+
49+ my $fuse = SampleFS->new("your", "parameters", "here");
50+ $fuse->main(mountpoint => '/mnt/sample', mountopts => "allow_other");
51+
52+ # control will be not returned until file system is unmouted...
53+
54+When file on your filesystem is opened, it will be seen that method
55+is called like this:
56+
57+ $fuse->open($path_name, $flags, $file_info);
58+
59+=head1 DESCRIPTION
60+
61+This module supports writing Fuse callback as method.
62+Method name is same as Fuse callback, but first argment is an object (it's named '$self' usually).
63+
64+This is a small change for Fuse, but you can use power of OO like
65+inheritance, encapsulation, ...
66+
67+Exception handling:
68+
69+Returned value will be treated as negative errno in Fuse way, but you can
70+use exception, too.
71+If exception is thrown in your method ("die" is called), $! will be used
72+as errno to notify error to Fuse.
73+
74+
75+=head1 EXPORT
76+
77+Nothing.
78+
79+=head1 CONSTRUCTOR
80+
81+=cut
82+
83+use Fuse;
84+use Errno;
85+
86+# instance calling main
87+use vars qw($_Module);
88+
89+=head2 new
90+
91+Create a new instance. This method is defined just for your convenience.
92+Default implementation returns blessed empty HASHREF.
93+
94+=cut
95+
96+#
97+# for your convenience.
98+#
99+sub new {
100+ my $class = shift;
101+ bless {}, $class;
102+}
103+
104+my @callback;
105+
106+=head1 METHODS
107+
108+=cut
109+
110+=head2 main(OPT_KEY1 => OPT_VALUE1, OPT_KEY2 => OPT_VALUE2, ...)
111+
112+Start a main loop. Filesystem is mounted to the mountpoint pointed by
113+option "mountpoint".
114+
115+Options are taken as key=>value pair selected from following:
116+
117+=over
118+
119+=item debug => boolean
120+
121+This option controls tracing on or off. (Default is off).
122+
123+=item mountpoint => "path_to_mountpoint"
124+
125+Directory name to mount filesystem like "/mnt/mypoint".
126+This option has no default value and is mandatory.
127+
128+=item mountopts => "opt1,op2,..."
129+
130+Comma separated options for FUSE kernel module.
131+
132+=item nullpath_ok => boolean
133+
134+If true, empty pathname is passed to the methods like read, write, flush,
135+release, fsync, readdir, releasedir, fsyncdir, ftruncate, fgetattr and lock.
136+
137+To use this option, you must return file/directory handle from
138+open, opendir and create, and you must operate file/directory by
139+that handle insted of pathname.
140+
141+Only effective on Fuse 2.8 or later.
142+
143+=back
144+
145+For more information, see the documentation of Fuse.
146+
147+=cut
148+
149+sub main {
150+ my $self = shift;
151+ my %attr = @_;
152+
153+ my @args;
154+ for my $opt (qw(debug mountpoint mountopts nullpath_ok)) {
155+ push(@args, $opt, $attr{$opt}) if (defined($attr{$opt}));
156+ }
157+
158+ local $_Module = $self;
159+
160+ my %fnmap;
161+ foreach my $fnname (@callback) {
162+ if ($_Module->can($fnname)) {
163+ $fnmap{$fnname} = __PACKAGE__ . '::_' . $fnname;
164+ }
165+ }
166+
167+ Fuse::main(@args, %fnmap);
168+}
169+
170+BEGIN {
171+ @callback = qw (getattr readlink getdir mknod mkdir unlink
172+ rmdir symlink rename link chmod chown truncate
173+ utime open read write statfs flush release fsync
174+ setxattr getxattr listxattr removexattr);
175+ if (Fuse->can('fuse_version')) {
176+ my $fuse_version = Fuse::fuse_version();
177+ if ($fuse_version >= 2.3) {
178+ push(@callback, qw(opendir readdir releasedir fsyncdir init destroy));
179+ }
180+ if ($fuse_version >= 2.5) {
181+ push(@callback, qw(access create ftruncate fgetattr));
182+ }
183+ if ($fuse_version >= 2.6) {
184+ push(@callback, qw(lock utimens bmap));
185+ }
186+ }
187+
188+ no strict "refs";
189+ for my $m (@callback) {
190+ my $method = __PACKAGE__ . "::_$m";
191+
192+ *$method = sub {
193+ my $method_name = $m;
194+
195+ if ($_Module->can($method_name)) {
196+ my @ret = eval {
197+ $_Module->$m(@_);
198+ };
199+ if ($@) {
200+ return $! ? -$! : -Errno::EPERM();
201+ }
202+ else {
203+ return (wantarray() ? @ret : $ret[0]);
204+ }
205+ }
206+ else {
207+ return -Errno::EPERM();
208+ }
209+ }
210+ }
211+}
212+
213+=head1 METHODS MAY BE OVERRIDDEN
214+
215+=cut
216+
217+=head2 getattr(PATH_NAME)
218+
219+Return a list of file attributes. Meaning of fields are same as
220+"stat" function like this:
221+
222+ ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
223+ $atime,$mtime,$ctime,$blksize,$blocks)
224+
225+On error, return scalar value like -ENOENT().
226+
227+=head2 readlink(PATH_NAME)
228+
229+This method is called to dereference symbolic link.
230+Return a destination path string or numeric error value.
231+
232+By Default implementation, returns -ENOENT().
233+You can leave this method if your FS does not have symlink.
234+
235+=cut
236+
237+sub readlink {
238+ return -Errno::ENOENT();
239+}
240+
241+=head2 getdir(DIRECTORY_NAME)
242+
243+Return a list of file/directory names and an errno (0 if success).
244+ex: ('..', '.', 'a', 'b', 0)
245+
246+If 'readdir' method is implemented, this function will never be called.
247+
248+=head2 mknod(PATH_NAME, MODE, DEVNO)
249+
250+Return an errno (0 if success).
251+This method is called to create an entity (device or file).
252+
253+=head2 mkdir(DIRECTORY_NAME, MODE)
254+
255+Return an errno (0 if success).
256+This method is called to create a directory.
257+
258+=head2 unlink(PATH_NAME)
259+
260+Return an errno (0 if success).
261+This method is called to remove an entity (device, file or symlink).
262+
263+=head2 rmdir(PATH_NAME)
264+
265+Return an errno (0 if success).
266+This method is called to remove a directory.
267+
268+=head2 symlink(EXISTING_PATH_NAME, SYMLINK_NAME)
269+
270+Return an errno (0 if success).
271+This method is called to create a symbolic link.
272+
273+=head2 rename(OLD_NAME, NEW_NAME)
274+
275+Return an errno (0 if success).
276+This method is called to rename/move a entity.
277+
278+=head2 link(EXISTING_PATH_NAME, HADLINK_NAME)
279+
280+Return an errno (0 if success).
281+This method is called to create a hard link.
282+
283+=head2 chmod(PATH_NAME, MODE).
284+
285+Return an errno (0 if success).
286+This method is called to change permissions on a entity.
287+
288+=head2 chown(PATH_NAME, UID, GID).
289+
290+Return an errno (0 if success).
291+This method is called to change ownership of a entity.
292+
293+=head2 truncate(PATH_NAME, OFFSET).
294+
295+Return an errno (0 if success).
296+This method is called to truncate a file at the given offset.
297+
298+=head2 utime(PATH_NAME, ACCESS_TIME, MODIFIED_TIME).
299+
300+Return an errno (0 if success).
301+This method is called to change atime/mtime on a entity.
302+
303+=head2 open(PATH_NAME, FLAGS, FILE_INFO)
304+
305+Return an errno, and a file handle (optional)
306+
307+First style means like this:
308+
309+ return 0; # success
310+
311+and second one is following:
312+
313+ return (0, $file_handle_you_made); # success and handle
314+
315+FLAGS is an OR-combined value of flags (O_RDONLY, O_SYNC, etc).
316+FILE_INFO is a hashref.
317+
318+Returned file handle will be passed to subsequent method call
319+to operate on opend file.
320+
321+=head2 read(PATH_NAME, SIZE, OFFSET, FILE_HANDLE)
322+
323+Return an errno, or string scalar of read data.
324+
325+This method is called to read data (SIZE bytes)
326+at the given offset of opened file.
327+
328+=head2 write(PATH_NAME, BUFFER, OFFSET, FILE_HANDLE)
329+
330+Return a written byte size or an errno.
331+
332+This method is called to write data (BUFFER)
333+at the given offset of opened file.
334+
335+=head2 statfs
336+
337+Return status of filesystem in one of follwing style:
338+
339+=over
340+
341+=item -ENOANO()
342+
343+or
344+
345+=item $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
346+
347+or
348+
349+=item -ENOANO(), $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize
350+
351+=back
352+
353+=cut
354+
355+sub statfs {
356+ return -Errno::ENOANO();
357+}
358+
359+=head2 flush(PATH_NAME, FILE_HANDLE)
360+
361+Return an errno (0 if success).
362+This method is called to synchronize any cached data.
363+
364+=cut
365+
366+sub flush {
367+ return 0;
368+}
369+
370+=head2 release(PATH_NAME, FLAGS, FILE_HANDLE)
371+
372+Return an errno (0 if success).
373+
374+FLAGS is a same value passed when 'open' is called.
375+
376+Called to indicate that there are no more references to the file and flags.
377+
378+=cut
379+
380+sub release {
381+ return 0;
382+}
383+
384+=head2 fsync(PATH_NAME, DATA_SYNC, FILE_HANDLE)
385+
386+Return an errno (0 if success).
387+
388+Called to synchronize file contents.
389+
390+DATA_SYNC indicates 'user data only'. If DATA_SYNC is non-zero,
391+only the user data should be synchronized. Otherwise synchronize
392+user and meta data.
393+
394+=cut
395+
396+sub fsync {
397+ return 0;
398+}
399+
400+=head2 setxattr(PATH_NAME, ATTR_NAME, ATTR_VALUE, FLAGS)
401+
402+FLAGS is OR-ed value of Fuse::XATTR_CREATE and Fuse::XATTR_REPLACE
403+
404+Return an errno (0 if success).
405+
406+This method is called to set extended attribute.
407+
408+-EOPNOTSUPP means that setting the attribute is rejected.
409+
410+If XATTR_CREATE is passed and the attribute already exists, return -EEXIST.
411+
412+If XATTR_REPLACE is passed and the attribute does not exist, return -ENOATTR.
413+
414+By default implementation, returns -EOPNOTSUPP.
415+You can leave this method if your FS does not have any extended attributes.
416+
417+=cut
418+
419+sub setxattr {
420+ return -Errno::EOPNOTSUPP();
421+}
422+
423+=head2 getxattr(PATH_NAME, ATTR_NAME)
424+
425+Return attribute value or errno (0 if no value).
426+
427+This method is called to get extended attribute value.
428+
429+By default implementation, returns 0.
430+You can leave this method if your FS does not have any extended attributes.
431+
432+=cut
433+
434+sub getxattr {
435+ return 0;
436+}
437+
438+=head2 listxattr(PATH_NAME)
439+
440+Return a list of attribute names and an errno (0 if success).
441+ex: ('attr1', 'attr2', 'attr3', 0)
442+
443+By default implementation, returns 0.
444+You can leave this method if your FS does not have any extended attributes.
445+
446+=cut
447+
448+sub listxattr {
449+ return 0;
450+}
451+
452+=head2 removexattr(PATH_NAME, ATTR_NAME)
453+
454+Return an errno (0 if success).
455+
456+This method is called to remove an attribute from entity.
457+
458+By default implementation, returns 0.
459+You can leave this method if your FS does not have any extended attributes.
460+
461+=cut
462+
463+sub removexattr {
464+ return 0;
465+}
466+
467+=head2 opendir(DIRECTORY_NAME)
468+
469+Return an errno, and a directory handle (optional).
470+
471+This method is called to open a directory for reading.
472+If special handling is required to open a directory, this method
473+can be implemented.
474+
475+Supported by Fuse version 2.3 or later.
476+
477+=cut
478+
479+# sub opendir {
480+# return -Errno::EOPNOTSUPP();
481+# }
482+
483+=head2 readdir(DIRECTORY_NAME, OFFSET, HANDLE)
484+
485+(HANDLE is optional. see opendir)
486+
487+Return list consists of entries and an errno. Most simple style is
488+same as getdir(). ex: ('..', '.', 'a', 'b', 0)
489+
490+Entry can be array ref containing offset and attributes in following way:
491+
492+ ([1, '..'], [2, '.'], [3, 'a'], [4, 'b', ], 0)
493+
494+or
495+ ([1, '..', [array_like_getattr]], [2, '.', [array_like_getattr]], 0)
496+
497+
498+Supported by Fuse version 2.3 or later.
499+
500+=cut
501+
502+# sub readdir {
503+# return -Errno::EOPNOTSUPP();
504+# }
505+
506+=head2 releasedir(DIRECTORY_NAME, HANDLE)
507+
508+(HANDLE is optional. see opendir)
509+
510+Return an errno (0 if success).
511+
512+Called to indicate that there are no more references to the opened directory.
513+
514+Supported by Fuse version 2.3 or later.
515+
516+=cut
517+
518+=head2 fsyncdir(DIRECTORY_NAME, FLAGS, HANDLE)
519+
520+(HANDLE is optional. see opendir)
521+
522+Return an errno (0 if success).
523+This method is called to synchronize user data (FLAG is non-zero value)
524+or user data and meta data in directory.
525+
526+Supported by Fuse version 2.3 or later.
527+
528+=cut
529+
530+=head2 init
531+
532+You can return scalar. It can be accessed using fuse_get_context().
533+
534+Supported by Fuse version 2.3 or later.
535+
536+=cut
537+
538+=head2 destroy(SCALAR_VALUE)
539+
540+(SCALAR_VALUE is returned value by init method)
541+
542+Supported by Fuse version 2.3 or later.
543+
544+=cut
545+
546+=head2 access(PATH_NAME, ACCESS_MODE_FLAG)
547+
548+Return an errno (0 if success).
549+
550+This method is called to determine if user can access the file.
551+For more information, see Fuse document and manual for access(2).
552+
553+Supported by Fuse version 2.5 or later.
554+
555+=cut
556+
557+=head2 create(PATH_NAME, MASK, MODE)
558+
559+Return an errno, and a file handle (optional)
560+
561+This method is called to create a file with MASK (like mknod)
562+and open it with MODE atomically.
563+If this method is not implemented, mknod() and open() will be used.
564+
565+Supported by Fuse version 2.5 or later.
566+
567+=cut
568+
569+=head2 ftruncate(PATH_NAME, OFFSET, FILE_HANDLE)
570+
571+(HANDLE is optional. see open)
572+
573+Return an errno (0 if success).
574+This method is called to truncate an opened file at the given offset.
575+
576+Supported by Fuse version 2.5 or later.
577+
578+=cut
579+
580+=head2 fgetattr(PATH_NAME, FILE_HANDLE)
581+
582+(HANDLE is optional. see open)
583+
584+Return a list of file attributes like getattr().
585+This method is called to get attributes for opened file.
586+
587+Supported by Fuse version 2.5 or later.
588+
589+=cut
590+
591+=head2 lock(PATH_NAME, COMMAND_CODE, LOCK_PARAMS, FILE_HANDLE)
592+
593+(HANDLE is optional. see open)
594+
595+Return an errno (0 if success).
596+
597+This method is called to lock or unlock regions of file. Parameters
598+for locking is passed in LOCK_PARAMS as hashref.
599+
600+For more information, see the documentation of Fuse.
601+
602+Supported by Fuse version 2.6 or later.
603+
604+=cut
605+
606+=head2 utimens(PATH_NAME, ACCESS_TIME, MODIFIED_TIME)
607+
608+Return an errno (0 if success).
609+This method is called to change atime/mtime on a entity.
610+(Time has a resolution in nanosecond.)
611+
612+Supported by Fuse version 2.6 or later.
613+
614+=cut
615+
616+=head2 bmap(PATH_NAME, BLOCK_SIZE, BLOCK_NUMBER)
617+
618+Return 0 and physical block numeber on success, otherwise errno.
619+
620+This method is called to get physical block offset on block device.
621+
622+For more information, see the documentation of Fuse.
623+
624+Supported by Fuse version 2.6 or later.
625+
626+=cut
627+
628+=head1 AUTHOR
629+
630+Toshimitsu FUJIWARA, C<< <tttfjw at gmail.com> >>
631+
632+=head1 BUGS
633+
634+Threading is not tested.
635+
636+=head1 COPYRIGHT & LICENSE
637+
638+Copyright 2008-2011 Toshimitsu FUJIWARA, all rights reserved.
639+
640+This program is free software; you can redistribute it and/or modify it
641+under the same terms as Perl itself.
642+
643+=head1 SEE ALSO
644+
645+Fuse
646+
647+=cut
648+
649+1; # End of xxx
--- Fuse-Class/tags/Fuse-Class-0.02/README (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/README (revision 81)
@@ -0,0 +1,38 @@
1+Fuse-Class
2+
3+Fuse::Class - Base clsas for Fuse module implementation using class.
4+
5+This module supports writing Fuse callback as method.
6+Method name is same as Fuse callback, but first argment is object.
7+
8+This is a small change for Fuse, but you can use power of OO like
9+inheritance, encapsulation, ...
10+
11+
12+INSTALLATION
13+
14+To install this module, run the following commands:
15+
16+ perl Makefile.PL
17+ make
18+ make test
19+ make install
20+
21+(For the full test, you need Test::Virtual::Filesystem module.)
22+
23+
24+SUPPORT AND DOCUMENTATION
25+
26+After installing, you can find documentation for this module with the
27+perldoc command.
28+
29+ perldoc Fuse::Class
30+
31+
32+COPYRIGHT AND LICENCE
33+
34+Copyright (C) 2008 Toshimitsu FUJIWARA
35+
36+This program is free software; you can redistribute it and/or modify it
37+under the same terms as Perl itself.
38+
--- Fuse-Class/tags/Fuse-Class-0.02/META.yml (nonexistent)
+++ Fuse-Class/tags/Fuse-Class-0.02/META.yml (revision 81)
@@ -0,0 +1,12 @@
1+# http://module-build.sourceforge.net/META-spec.html
2+#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
3+name: Fuse-Class
4+version: 0.02
5+version_from: lib/Fuse/Class.pm
6+installdirs: site
7+requires:
8+ Fuse: 0
9+ Test::More: 0
10+
11+distribution_type: module
12+generated_by: ExtUtils::MakeMaker version 6.17
Show on old repository browser