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 )