/* Silly example program to demonstrate that kqueue can be kqueued
 * (C)2006 Henrik Nordstrom <hno@squid-cache.org>
 */
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

int kqfd_in = -1;

int kqfd_main = -1;
const struct timespec zero_timespec = {0,0};

typedef void callback_t (int fd, short filter, intptr_t filter_data);

callback_t handle_stdin;
callback_t handle_kqfd;

void handle_events(int kqfd, const struct timespec *timeout)
{
	struct kevent kev[3];

	int n = kevent(kqfd, NULL, 0, kev, 3, timeout);
	int i;
	for (i = 0; i < n; i++) {
		callback_t *cb = kev[i].udata;
		cb(kev[i].ident, kev[i].filter, kev[i].data);
	}
}

void handle_stdin(int fd, short filter, intptr_t filter_data)
{
	char buf[256];
	int n;
	printf("handle_stdin: fd=%d data=%ld\n", fd, (long int)filter_data);

	n = read(fd, buf, (long int)filter_data);
	if (n > 0)
		buf[n] = '\0';
	else if (n == 0) 
		exit(0);
	else {
		perror("read");
		exit(1);
	}
	printf("Got %d '%s'\n", n, buf);
}

void handle_kqfd(int fd, short filter, intptr_t filter_data)
{
	handle_events(fd, &zero_timespec);
}

int main(int argc, char **argv)
{
	struct kevent kev[1];

	kqfd_in = kqueue();

	EV_SET(&kev[0], 0, EVFILT_READ, EV_ADD, 0, 0, handle_stdin);
	kevent(kqfd_in, kev, 1, NULL, 0, &zero_timespec);

	kqfd_main = kqueue();

	EV_SET(&kev[0], kqfd_in, EVFILT_READ, EV_ADD, 0, 0, handle_kqfd);
	kevent(kqfd_main, kev, 1, NULL, 0, &zero_timespec);

	while (1) {
		handle_events(kqfd_main, NULL);
	}
}

