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);
# 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;
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];
$self->{dirlist});
} elsif ($!{ENOENT}) {
push @watch_gone, $x;
+ delete $self->{dirlist}->{$path};
} else {
warn "W: opendir $path: $!\n";
}
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;