Linux-realtimed
view release on metacpan or search on metacpan
bin/realtimed view on Meta::CPAN
my $runnable = qx{runuser -l $user -c 'if test -x "\$(command -v $command)"; then echo 1; else echo 0; fi;'};
chomp $runnable;
$ENV{PATH} = '';
unless ($runnable && $runnable eq '1') {
notice "$errline - output: $runnable";
next;
}
initTree({
path => $path,
events => $events,
eventNames => $textevents,
recursive => $recursive,
user => $user,
command => $command,
arguments => $arguments,
version => $nextversion,
userid => $userid,
groupid => $groupid
});
}
}
}
watchDir($dirtree->{conf}->{$nextversion});
$dirtree->{curversion}++;
releaseInotifyWatchers($dirtree->{conf}->{$curversion}) if $curversion; # if $curversion 0 daemon just started and no previous config
delete $dirtree->{conf}->{$curversion};
printCurrentConf();
}
sub getCanonicalPath {
my ($path) = @_;
unless( -e $path ){
err "dir $path does not exist";
return '';
}
if ( -d $path) {
my $dh; my $fd;
opendir $dh, $path;
$fd = fileno $dh;
$path = readlink("/proc/$$/fd/$fd");
closedir $dh;
} else {
my $fh; my $fd;
open $fh, '<', $path;
$fd = fileno $fh;
$path = readlink("/proc/$$/fd/$fd");
close $fh;
}
return $path;
}
sub initTree {
my ($conf) = @_;
my $path = getCanonicalPath($conf->{path});
return unless $path;
my $curpath = '';
my @path = split m|/|, $path;
shift @path;
my $version = $conf->{version};
$dirtree->{conf}->{$version} //= {};
my $node = $dirtree->{conf}->{$version};
for (@path) {
$curpath .= "/$_";
$node->{$curpath} = { path => $curpath } unless $node->{$curpath};
$node = $node->{$curpath};
next unless $curpath eq $path;
# $node->{conf} //= {};
# $node = $node->{conf};
$node->{events} |= $conf->{events};
$node->{textevents} = eventsList($node->{events});
$node->{recursive} ||= $conf->{recursive};
$node->{triggers} //= [];
push @{$node->{triggers}}, $conf;
}
}
sub releaseInotifyWatchers {
my ($node) = @_;
return unless ref $node eq 'HASH';
$node->{iw}->cancel if defined $node->{iw};
for(keys %$node){
next if $_ eq 'path';
next if $_ eq 'events';
next if $_ eq 'recursive';
releaseInotifyWatchers($node->{$_});
}
}
sub watchDir {
my ($node) = @_;
unless(defined $node->{events}){
for(keys %$node){
next if $_ eq 'path';
next if $_ eq 'events';
next if $_ eq 'recursive';
watchDir($node->{$_});
}
return;
}
my $recursive = $node->{recursive};
my $triggers = $node->{triggers};
my $events = $node->{events};
my $dir = $node->{path};
unless($node->{iw} && $node->{ew}) { # avoid watchers duplication
my $in = Linux::Inotify2->new;
$node->{iw} = $in->watch($node->{path}, $events | $direvents, sub {
my $e = shift;
# realtimed itself triggers opendir events while parsing dir tree, we need to filter them out, sorry
# return if $e->IN_ISDIR && $e->IN_OPEN;
$e->{eventMask} = $e->mask;
$e->{eventName} = eventsList($e->mask);
$e->{node} = $node;
eventQueueOverflowed($e) if $e->mask & IN_Q_OVERFLOW;
manageEvents($e) if $e->mask & $events;
( run in 1.398 second using v1.01-cache-2.11-cpan-71847e10f99 )