]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/FakeInotify.pm
imap+nntp: share COMPRESS implementation
[public-inbox.git] / lib / PublicInbox / FakeInotify.pm
index 644f5b5b7229316f7ae48745d0e1421b1203668b..6d2696019d8324fc3676d4e49efb783e10efc15a 100644 (file)
@@ -10,10 +10,13 @@ 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 +47,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 +82,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 +102,7 @@ sub read {
                                                $self->{dirlist});
                        } elsif ($!{ENOENT}) {
                                push @watch_gone, $x;
+                               delete $self->{dirlist}->{$path};
                        } else {
                                warn "W: opendir $path: $!\n";
                        }
@@ -126,11 +137,20 @@ use strict;
 sub fullname { ${$_[0]} }
 
 sub IN_DELETE { 0 }
+sub IN_MOVED_FROM { 0 }
+sub IN_DELETE_SELF { 0 }
 
 package PublicInbox::FakeInotify::GoneEvent;
 use strict;
 our @ISA = qw(PublicInbox::FakeInotify::Event);
 
 sub IN_DELETE { 1 }
+sub IN_MOVED_FROM { 0 }
+
+package PublicInbox::FakeInotify::SelfGoneEvent;
+use strict;
+our @ISA = qw(PublicInbox::FakeInotify::GoneEvent);
+
+sub IN_DELETE_SELF { 1 }
 
 1;