diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Linux/FANotify.pm | 104 | ||||
-rw-r--r-- | lib/Linux/FANotify/LowLevel.pm | 111 |
2 files changed, 117 insertions, 98 deletions
diff --git a/lib/Linux/FANotify.pm b/lib/Linux/FANotify.pm index cf30ba0..a839574 100644 --- a/lib/Linux/FANotify.pm +++ b/lib/Linux/FANotify.pm @@ -1,101 +1,7 @@ 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=<<EOC; -#include <sys/fanotify.h> -#include <stdlib.h> -#include <string.h> -EOC -for my $c (@constants) { - my $sub_name = lc($c =~ s{^.*?_}{}r); - $ccode .= "long CONST_${sub_name}() { return $c; }\n"; -} -$ccode.=<<EOC; -int perl_fanotify_init(unsigned int flags, unsigned int event_f_flags) { - return fanotify_init(flags,event_f_flags); -} - -int perl_fanotify_mark(int fanotify_fd, unsigned int flags, - unsigned long mask, int dfd, const char *pathname) { - return fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); -} - -SV* perl_memalign(size_t alignment, size_t size) { - void* buffer=NULL; - int err; - err = posix_memalign(&buffer, alignment, size); - if (err != 0 || buffer == NULL) { - SV* bang = get_sv("!", 0); - sv_setiv(bang, (IV)err); - sv_setpvf(bang, "%s", strerror(err)); /* let Perl copy the string */ - SvIOK_on(bang); - return &PL_sv_undef; - } - return sv_2mortal(newSVpvn(buffer,size)); -} -AV* unpack_events(SV* svbuffer) { - STRLEN len; - void * buffer = SvPV(svbuffer,len); - AV* ret = newAV(); - HV* event; - struct fanotify_event_metadata *data; - data = (struct fanotify_event_metadata *) buffer; - - while(FAN_EVENT_OK(data,len)) { - event = newHV(); - av_push(ret,newRV_noinc((SV*)event)); - hv_store(event,"mask",4,newSViv(data->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 Linux::FANotify::LowLevel ':constants',':functions'; use POSIX qw(); use Data::Printer; @@ -104,9 +10,11 @@ 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'); +my $ret = perl_fanotify_mark( + $fan_fd, + CONST_mark_add,# | CONST_mark_mount, + CONST_open | CONST_close | CONST_event_on_child, + 0, '/tmp'); if ($ret < 0) { die "WTF? $ret"; } diff --git a/lib/Linux/FANotify/LowLevel.pm b/lib/Linux/FANotify/LowLevel.pm new file mode 100644 index 0000000..90d8568 --- /dev/null +++ b/lib/Linux/FANotify/LowLevel.pm @@ -0,0 +1,111 @@ +package Linux::FANotify::LowLevel; +use 5.014; +use strict; +use warnings; +my $ccode;my @exports; +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=<<EOC; +#include <sys/fanotify.h> +#include <stdlib.h> +#include <string.h> +EOC +for my $c (@constants) { + my $sub_name = lc($c =~ s{^.*?_}{}r); + $ccode .= "long CONST_${sub_name}() { return $c; }\n"; + push @exports,"CONST_${sub_name}"; +} +$ccode.=<<EOC; +int perl_fanotify_init(unsigned int flags, unsigned int event_f_flags) { + return fanotify_init(flags,event_f_flags); +} + +int perl_fanotify_mark(int fanotify_fd, unsigned int flags, + unsigned long mask, int dfd, const char *pathname) { + return fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); +} + +SV* perl_memalign(size_t alignment, size_t size) { + void* buffer=NULL; + int err; + err = posix_memalign(&buffer, alignment, size); + if (err != 0 || buffer == NULL) { + SV* bang = get_sv("!", 0); + sv_setiv(bang, (IV)err); + sv_setpvf(bang, "%s", strerror(err)); /* let Perl copy the string */ + SvIOK_on(bang); + return &PL_sv_undef; + } + return sv_2mortal(newSVpvn(buffer,size)); +} +AV* unpack_events(SV* svbuffer) { + STRLEN len; + void * buffer = SvPV(svbuffer,len); + AV* ret = newAV(); + HV* event; + struct fanotify_event_metadata *data; + data = (struct fanotify_event_metadata *) buffer; + + while(FAN_EVENT_OK(data,len)) { + event = newHV(); + av_push(ret,newRV_noinc((SV*)event)); + hv_store(event,"mask",4,newSViv(data->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 Sub::Exporter -setup => { + exports => [ + @exports, + qw(perl_fanotify_init perl_fanotify_mark perl_memalign unpack_events) + ], + groups => { + constants => \@exports, + functions => [qw(perl_fanotify_init perl_fanotify_mark unpack_events)], + }, +}; + +1; |