#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <err.h>

/* example of errors with kqueue by Peter Werner <peterw@ifost.org.au> */
int
main(void)
{
	int kq, i, j;
	struct kevent ke_set[3], ke_retr[4];

	memset(ke_set, 0x00, sizeof(ke_set));
	memset(ke_retr, 0x00, sizeof(ke_retr));

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

	/* ignore the signals so we dont exit */
	signal(SIGINT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);

	EV_SET(&ke_set[0], SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);

	i = kevent(kq, &ke_set[0], 1, NULL, 0, NULL);
	if (i == -1)
		err(1, "set kevent for SIGINT");

	kill(getpid(), SIGINT);

	EV_SET(&ke_set[0], 42, -10, EV_ADD, 0, 0, NULL); 
	EV_SET(&ke_set[1], SIGHUP, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);

	i = kevent(kq, ke_set, 2, ke_retr, 4, NULL);
	if (i == -1)
		err(1, "kevent set sig!"); 

	printf("first invalid kevent call returned %d\n", i);

	for (j = 0; j < i; j++) { 
		if (ke_retr[j].flags & EV_ERROR) 
			printf("error! errno %d: %s\n", ke_retr[j].data,
			    strerror(ke_retr[j].data));
		else
			printf("received SIG%s %d times\n", 
			    sys_signame[ke_retr[j].ident], ke_retr[j].data);
	}
	
	EV_SET(&ke_set[0], 42, -10, EV_ADD, 0, 0, NULL); 
	EV_SET(&ke_set[1], SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);

	i = kevent(kq, ke_set, 2, NULL, 0, NULL);
	
	printf("second invalid call returned %d\n", i);

	EV_SET(&ke_set[0], SIGQUIT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
	EV_SET(&ke_set[1], 42, -10, EV_ADD, 0, 0, NULL); 

	i = kevent(kq, ke_set, 2, NULL, 0, NULL);
	
	printf("third invalid call returned %d\n", i);

	/* send signals again */
	kill(getpid(), SIGINT);
	kill(getpid(), SIGHUP);
	kill(getpid(), SIGTERM);
	kill(getpid(), SIGQUIT);

	memset(ke_retr, 0x00, sizeof(ke_retr));

	/* see whats waiting */
	i = kevent(kq, NULL, 0, ke_retr, 4, NULL);
	if (i == -1)
		err(1, "kevent second time!");

	printf("kevent retrieve call returned %d\n", i);

	for (j = 0; j < i; j++) 
		printf("received SIG%s %d times\n", 
		    sys_signame[ke_retr[j].ident], ke_retr[j].data);

	return(0);
}
	
	
