#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
/* example of kqueue signal usage, by Peter Werner <peterw@ifost.org.au> */
int caught = 0;

void
sigquit(int sig)
{
#define str "in sig handler\n"
	write(STDOUT_FILENO, str, sizeof(str));
#undef str
	caught = 1;
}

int
main(void)
{
	int kq, i, nloops = 0;
	struct kevent ke[2];
	struct timespec timeout;

	/* set the handler and ignore SIGINT */
	signal(SIGQUIT, sigquit);
	signal(SIGINT, SIG_IGN);

	kq = kqueue();
	if (kq == -1)
		err(1, "kq!");

	/* set the kevent, can only receive signals for this process */
	EV_SET(&ke[0], SIGQUIT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
	EV_SET(&ke[1], SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
	i = kevent(kq, ke, 2, NULL, 0, NULL);
	if (i == -1)
		err(1, "kevent add!");

	while (1) {
		 
		if (nloops++ == 10) {
			printf("exiting\n");
			break;	
		}
	
		memset(&ke, 0x00, sizeof(ke));
		timeout.tv_sec = 2;
		timeout.tv_nsec = 0;

		i = kevent(kq, NULL, 0, ke, 1, &timeout);
		if (i == -1) 
			if (errno == EINTR) 
				continue; 
			else
				err(1, "kevent!");
		else if (i == 0)
			printf("timeout, caught = %d!\n", caught);
		else {
			if (ke[0].ident == SIGQUIT) {
				printf("SIGQUIT sent, caught = %d\n", caught);
				caught = 0;
			} else if (ke[0].ident == SIGINT) 
				printf("SIGINT sent\n");
			else
				printf("strange signal %d\n", ke[0].ident);
		}

		fflush(stdout);
	}

	return(0);
}
