about summary refs log tree commit homepage
path: root/lib/PublicInbox/FakeInotify.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/FakeInotify.pm')
-rw-r--r--lib/PublicInbox/FakeInotify.pm23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/PublicInbox/FakeInotify.pm b/lib/PublicInbox/FakeInotify.pm
index 644f5b5b..641bc5bd 100644
--- a/lib/PublicInbox/FakeInotify.pm
+++ b/lib/PublicInbox/FakeInotify.pm
@@ -13,7 +13,9 @@ sub IN_MODIFY () { 0x02 } # match Linux inotify
 # 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";
                         }
@@ -126,6 +136,7 @@ use strict;
 sub fullname { ${$_[0]} }
 
 sub IN_DELETE { 0 }
+sub IN_DELETE_SELF { 0 }
 
 package PublicInbox::FakeInotify::GoneEvent;
 use strict;
@@ -133,4 +144,10 @@ our @ISA = qw(PublicInbox::FakeInotify::Event);
 
 sub IN_DELETE { 1 }
 
+package PublicInbox::FakeInotify::SelfGoneEvent;
+use strict;
+our @ISA = qw(PublicInbox::FakeInotify::GoneEvent);
+
+sub IN_DELETE_SELF { 1 }
+
 1;