X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FFakeInotify.pm;h=45b80f505557a95ed0cd157b36667477bee3fdc9;hb=HEAD;hp=644f5b5b7229316f7ae48745d0e1421b1203668b;hpb=671e7f4c9d82b053fba475aaeaa16a94dc3adad2;p=public-inbox.git
diff --git a/lib/PublicInbox/FakeInotify.pm b/lib/PublicInbox/FakeInotify.pm
index 644f5b5b..45b80f50 100644
--- a/lib/PublicInbox/FakeInotify.pm
+++ b/lib/PublicInbox/FakeInotify.pm
@@ -1,19 +1,21 @@
-# Copyright (C) 2020-2021 all contributors
+# Copyright (C) all contributors
# License: AGPL-3.0+
# for systems lacking Linux::Inotify2 or IO::KQueue, just emulates
# enough of Linux::Inotify2
package PublicInbox::FakeInotify;
-use strict;
-use v5.10.1;
+use v5.12;
use parent qw(Exporter);
use Time::HiRes qw(stat);
use PublicInbox::DS qw(add_timer);
sub IN_MODIFY () { 0x02 } # match Linux inotify
+# my $IN_MOVED_FROM 0x00000040 /* File was moved from X. */
# my $IN_MOVED_TO = 0x80;
# my $IN_CREATE = 0x100;
sub MOVED_TO_OR_CREATE () { 0x80 | 0x100 }
-sub IN_DELETE () { 0x00000200 }
+sub IN_DELETE () { 0x200 }
+sub IN_DELETE_SELF () { 0x400 }
+sub IN_MOVE_SELF () { 0x800 }
our @EXPORT_OK = qw(fill_dirlist on_dir_change);
@@ -44,7 +46,7 @@ sub watch {
# also used by KQNotify since it kevent requires readdir on st_nlink
# count changes.
-sub on_dir_change ($$$$;$) {
+sub on_dir_change ($$$$$) {
my ($events, $dh, $path, $old_ctime, $dirlist) = @_;
my $oldlist = $dirlist->{$path};
my $newlist = $oldlist ? {} : undef;
@@ -79,7 +81,14 @@ sub read {
my @watch_gone;
for my $x (keys %$watch) {
my ($path, $mask) = split(/\0/, $x, 2);
- my @now = stat($path) or next;
+ my @now = stat($path);
+ if (!@now && $!{ENOENT} && ($mask & IN_DELETE_SELF)) {
+ push @$events, bless(\$path,
+ 'PublicInbox::FakeInotify::SelfGoneEvent');
+ push @watch_gone, $x;
+ delete $self->{dirlist}->{$path};
+ }
+ next if !@now;
my $old_ctime = $watch->{$x};
$watch->{$x} = $now[10];
next if $old_ctime == $now[10];
@@ -92,6 +101,7 @@ sub read {
$self->{dirlist});
} elsif ($!{ENOENT}) {
push @watch_gone, $x;
+ delete $self->{dirlist}->{$path};
} else {
warn "W: opendir $path: $!\n";
}
@@ -108,7 +118,7 @@ sub poll_once {
}
package PublicInbox::FakeInotify::Watch;
-use strict;
+use v5.12;
sub cancel {
my ($self) = @_;
@@ -121,16 +131,25 @@ sub name {
}
package PublicInbox::FakeInotify::Event;
-use strict;
+use v5.12;
sub fullname { ${$_[0]} }
sub IN_DELETE { 0 }
+sub IN_MOVED_FROM { 0 }
+sub IN_DELETE_SELF { 0 }
package PublicInbox::FakeInotify::GoneEvent;
-use strict;
+use v5.12;
our @ISA = qw(PublicInbox::FakeInotify::Event);
sub IN_DELETE { 1 }
+sub IN_MOVED_FROM { 0 }
+
+package PublicInbox::FakeInotify::SelfGoneEvent;
+use v5.12;
+our @ISA = qw(PublicInbox::FakeInotify::GoneEvent);
+
+sub IN_DELETE_SELF { 1 }
1;