From 5aa8bef920a2034be264a1bb289f1c19392e8ee1 Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 14 Sep 2012 15:28:49 +0100 Subject: first working version --- .gitignore | 3 + lib/Linux/FANotify.pm | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 .gitignore create mode 100644 lib/Linux/FANotify.pm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90e6650 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/_Inline/ +*~ +.#* diff --git a/lib/Linux/FANotify.pm b/lib/Linux/FANotify.pm new file mode 100644 index 0000000..cf30ba0 --- /dev/null +++ b/lib/Linux/FANotify.pm @@ -0,0 +1,150 @@ +package Linux::FANotify; +use 5.016; +use strict; +use warnings; +my $ccode; +BEGIN { +my @constants=qw( + FAN_ACCESS + FAN_MODIFY + FAN_CLOSE_WRITE + FAN_CLOSE_NOWRITE + FAN_OPEN + FAN_Q_OVERFLOW + FAN_OPEN_PERM + FAN_ACCESS_PERM + FAN_ONDIR + FAN_EVENT_ON_CHILD + FAN_CLOSE + FAN_CLOEXEC + FAN_NONBLOCK + FAN_CLASS_NOTIF + FAN_CLASS_CONTENT + FAN_CLASS_PRE_CONTENT + FAN_ALL_CLASS_BITS + FAN_UNLIMITED_QUEUE + FAN_UNLIMITED_MARKS + FAN_ALL_INIT_FLAGS + FAN_MARK_ADD + FAN_MARK_REMOVE + FAN_MARK_DONT_FOLLOW + FAN_MARK_ONLYDIR + FAN_MARK_MOUNT + FAN_MARK_IGNORED_MASK + FAN_MARK_IGNORED_SURV_MODIFY + FAN_MARK_FLUSH + FAN_ALL_MARK_FLAGS + FAN_ALL_EVENTS + FAN_ALL_PERM_EVENTS + FAN_ALL_OUTGOING_EVENTS + FANOTIFY_METADATA_VERSION + FAN_ALLOW + FAN_DENY + FAN_NOFD + ); +$ccode=< +#include +#include +EOC +for my $c (@constants) { + my $sub_name = lc($c =~ s{^.*?_}{}r); + $ccode .= "long CONST_${sub_name}() { return $c; }\n"; +} +$ccode.=<mask),0); + hv_store(event,"fd",2,newSViv(data->fd),0); + hv_store(event,"pid",3,newSViv(data->pid),0); + buffer = FAN_EVENT_NEXT(data,len); + } + + return ret; +} +EOC +} +use Inline C => $ccode; +use POSIX qw(); +use Data::Printer; + +my $fan_fd = perl_fanotify_init(0,0); + +warn "fan fd: $fan_fd $!"; +my $fan_fh;open($fan_fh,'<&=',$fan_fd); + +my $ret = perl_fanotify_mark($fan_fd, + CONST_mark_add | CONST_mark_mount, + CONST_open | CONST_close, 0, '/tmp'); +if ($ret < 0) { + die "WTF? $ret"; +} + +my $buffer;#=perl_memalign(4096,8192); + +sub program_for_pid { + my ($pid) = @_; + + my $ret = ""; + + open my $fh,'<',"/proc/$pid/cmdline" or return $ret; + + my $cmdline = do { local $/;<$fh> };chomp $cmdline; + + return $cmdline || $ret; +} + +sub print_event { + my ($ev) = @_; + + my $procname = program_for_pid($ev->{pid}); + my $filename = readlink "/proc/self/fd/".$ev->{fd}; + $filename ||= "{fd})>"; + my $mask = $ev->{mask}; + + print "$procname ($mask) $filename\n"; + POSIX::close($ev->{fd}); +} + +while (1) { + my $len = sysread($fan_fh,$buffer,8192,0); + my $ret = unpack_events($buffer); + + for my $ev (@$ret) { + print_event($ev); + } +} + +close $fan_fh; + -- cgit v1.2.3