Linux-Fanotify
view release on metacpan or search on metacpan
Fanotify.xs view on Meta::CPAN
CODE:
fd = fanotify_init(flags, event_f_flags);
if (fd == -1) {
XSRETURN_UNDEF;
}
notgrp = newSV(0);
sv_setref_iv(notgrp, PERLCLASS_NOTGRP, fd);
SvREADONLY_on(SvRV(notgrp));
RETVAL = notgrp;
OUTPUT:
RETVAL
#
#
#
int
fanotify_mark(notgrp, flags, mask = 0, dirfd = 0, pathname = NULL)
SV *notgrp
unsigned int flags
uint64_t mask
int dirfd
const char *pathname
INIT:
int ret;
int fd = -1;
CODE:
if (!notgrp2fd(notgrp, &fd)) {
Perl_croak(aTHX_ "Invalid fanotify_fd");
} else {
ret = fanotify_mark(fd, flags, mask, dirfd, pathname);
if (ret == -1) {
XSRETURN_UNDEF;
}
}
RETVAL = 1;
OUTPUT:
RETVAL
#
#
#
void
fanotify_read(notgrp, max = 0)
SV *notgrp
int max
INIT:
struct fanotify_event_metadata *buf;
const struct fanotify_event_metadata *metadata;
struct fanotify_bundle *bundle;
ssize_t len;
int size;
int fd;
SV *event;
SV *eventref;
PPCODE:
/*
* Check arguments and allocate read buffer
*/
if (max < 1) {
max = 170; // Results in a buffer slightly smaller than 4k
}
if (max > 4096) { // 4096 results in an almost 100k buffer. Don't allow more.
Perl_croak(aTHX_ "Maximum buffer size exceeded (max = 4096)");
}
if (!notgrp2fd(notgrp, &fd)) {
Perl_croak(aTHX_ "Invalid notification group object");
}
size = max * sizeof(struct fanotify_event_metadata);
buf = (struct fanotify_event_metadata *)malloc(size + (sizeof(struct fanotify_bundle) - sizeof(struct fanotify_event_metadata)));
if (!buf) {
Perl_croak(aTHX_ "Could not allocate memory");
}
/*
* Read from fanotify queue
*/
len = read(fd, (void *)buf, size);
if (len == -1) {
/* Read error. errno is already set, we simply return an empty list and expect the user to check errno */
free(buf);
XSRETURN_EMPTY;
}
// printf("Number of event structures: %d\n",
// len/sizeof(struct fanotify_event_metadata));
metadata = buf;
while (FAN_EVENT_OK(metadata, len)) {
if (metadata->vers != FANOTIFY_METADATA_VERSION) {
Perl_croak(aTHX_ "Mismatch of fanotify metadata version.");
}
event = newSVpvn((const char *)metadata, sizeof(struct fanotify_bundle));
sv_2mortal(event);
bundle = (struct fanotify_bundle *)SvPV_nolen(event);
bundle->fd = fd;
if (metadata->mask & (FAN_ACCESS_PERM | FAN_OPEN_PERM)) {
bundle->needs_response = 1;
} else {
bundle->needs_response = 0;
}
eventref = newRV_inc(event);
sv_bless(eventref, gv_stashpv(PERLCLASS_EVENT, GV_ADD | SVf_UTF8));
SvREADONLY_on(eventref);
sv_2mortal(eventref);
XPUSHs(eventref);
( run in 1.457 second using v1.01-cache-2.11-cpan-5511b514fd6 )