Filesys-POSIX
view release on metacpan or search on metacpan
lib/Filesys/POSIX/Real/Directory.pm view on Meta::CPAN
our @ISA = qw(Filesys::POSIX::Directory);
sub new {
my ( $class, $path, $inode ) = @_;
return bless {
'path' => $path,
'inode' => $inode,
'mtime' => 0,
'overlays' => {},
'detached' => {},
'skipped' => {},
'members' => {
'.' => $inode,
'..' => $inode->{'parent'} ? $inode->{'parent'} : $inode
}
}, $class;
}
sub _sync_all {
my ($self) = @_;
my $mtime = ( lstat $self->{'path'} )[9] or Carp::confess("$!");
return unless $mtime > $self->{'mtime'};
$self->open;
# This uses readdir to bypass the aliased/detached overlays
while ( my $item = readdir $self->{'dh'} ) {
$self->_sync_member($item);
}
$self->close;
$self->{'mtime'} = $mtime;
}
sub _sync_member {
lib/Filesys/POSIX/Real/Directory.pm view on Meta::CPAN
'dev' => $self->{'inode'}->{'dev'},
'parent' => $self->{'inode'}
);
}
}
sub get {
my ( $self, $name ) = @_;
return undef if ( exists $self->{'detached'}->{$name} );
return $self->{'overlays'}->{$name} if ( exists $self->{'overlays'}->{$name} );
$self->_sync_member($name) unless exists $self->{'members'}->{$name};
return $self->{'members'}->{$name};
}
sub set {
my ( $self, $name, $inode ) = @_;
delete $self->{'detached'}->{$name};
$self->{'overlays'}->{$name} = $inode;
return $inode;
}
sub rename_member {
my ( $self, undef, $olddir, $oldname, $newname ) = @_;
# TODO: This operation has no awareness of aliasing and detaching
return rename( $olddir->path . '/' . $oldname, $self->path . '/' . $newname )
&& do {
$olddir->_sync_member($oldname);
$self->_sync_member($newname);
1;
};
}
sub exists {
my ( $self, $name ) = @_;
return '' if exists $self->{'detached'}->{$name};
return 1 if exists $self->{'overlays'}->{$name};
$self->_sync_member($name);
return exists $self->{'members'}->{$name};
}
sub delete {
my ( $self, $name ) = @_;
if ( exists $self->{'detached'}->{$name} ) {
return delete $self->{'detached'}->{$name};
}
if ( exists $self->{'overlays'}->{$name} ) {
return delete $self->{'overlays'}->{$name};
}
my $member = $self->{'members'}->{$name} or return;
my $subpath = "$self->{'path'}/$name";
if ( $member->dir ) {
rmdir($subpath);
}
else {
unlink($subpath);
lib/Filesys/POSIX/Real/Directory.pm view on Meta::CPAN
return $inode;
}
sub detach {
my ( $self, $name ) = @_;
return undef if ( exists $self->{'detached'}->{$name} );
$self->{'detached'}->{$name} = undef;
foreach my $table (qw(members overlays)) {
next unless exists $self->{$table}->{$name};
return $self->{$table}->{$name};
}
}
sub list {
my ( $self, $name ) = @_;
$self->_sync_all;
my %union = ( %{ $self->{'members'} }, %{ $self->{'overlays'} } );
delete @union{ keys %{ $self->{'detached'} } };
return keys %union;
}
sub count {
scalar( shift->list );
}
sub open {
my ($self) = @_;
@{ $self->{'skipped'} }{ keys %{ $self->{'overlays'} } } =
values %{ $self->{'overlays'} };
$self->close;
opendir( $self->{'dh'}, $self->{'path'} ) or Carp::confess("$!");
return $self;
}
sub rewind {
my ($self) = @_;
@{ $self->{'skipped'} }{ keys %{ $self->{'overlays'} } } =
values %{ $self->{'overlays'} };
if ( $self->{'dh'} ) {
rewinddir $self->{'dh'};
}
return;
}
sub read {
my ($self) = @_;
( run in 1.487 second using v1.01-cache-2.11-cpan-49f99fa48dc )