t_sig.c revision 313478
1132718Skan/* $NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $ */
2117395Skan
318334Speter/*-
418334Speter * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
518334Speter * All rights reserved.
6132718Skan *
718334Speter * This code is derived from software contributed to The NetBSD Foundation
8132718Skan * by Luke Mewburn and Jaromir Dolecek.
918334Speter *
1018334Speter * Redistribution and use in source and binary forms, with or without
1118334Speter * modification, are permitted provided that the following conditions
1218334Speter * are met:
13132718Skan * 1. Redistributions of source code must retain the above copyright
1418334Speter *    notice, this list of conditions and the following disclaimer.
1518334Speter * 2. Redistributions in binary form must reproduce the above copyright
1618334Speter *    notice, this list of conditions and the following disclaimer in the
1718334Speter *    documentation and/or other materials provided with the distribution.
1818334Speter *
19132718Skan * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20169689Skan * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21169689Skan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2218334Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2318334Speter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2418334Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2518334Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2618334Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2718334Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2818334Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2918334Speter * POSSIBILITY OF SUCH DAMAGE.
3018334Speter */
3190075Sobrien
3290075Sobrien#include <sys/cdefs.h>
3318334Speter__COPYRIGHT("@(#) Copyright (c) 2008\
3418334Speter The NetBSD Foundation, inc. All rights reserved.");
3518334Speter__RCSID("$NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $");
3618334Speter
37132718Skan#include <sys/event.h>
38132718Skan#include <sys/ioctl.h>
39132718Skan#include <sys/param.h>
4018334Speter#include <sys/time.h>
4118334Speter#include <sys/wait.h>
4290075Sobrien
4318334Speter#include <inttypes.h>
4418334Speter#include <signal.h>
4518334Speter#include <stdio.h>
4618334Speter#include <stdlib.h>
4718334Speter#include <unistd.h>
4818334Speter
4918334Speter#include <atf-c.h>
5018334Speter
5118334Speter#include "../../h_macros.h"
5218334Speter
5318334Speter#define NSIGNALS 5
5418334Speter
55132718SkanATF_TC(sig);
5690075SobrienATF_TC_HEAD(sig, tc)
57132718Skan{
58132718Skan	atf_tc_set_md_var(tc, "descr", "Checks EVFILT_SIGNAL");
5918334Speter}
6018334SpeterATF_TC_BODY(sig, tc)
61132718Skan{
6218334Speter	struct timespec	timeout;
6318334Speter	struct kfilter_mapping km;
6418334Speter	struct kevent event[1];
6518334Speter	char namebuf[32];
6618334Speter	pid_t pid, child;
6718334Speter	int kq, n, num, status;
6818334Speter
6990075Sobrien	pid = getpid();
7018334Speter	(void)printf("my pid: %d\n", pid);
7118334Speter
7218334Speter	/* fork a child to send signals */
7318334Speter	RL(child = fork());
7418334Speter	if (child == 0) {
7518334Speter		int i;
7618334Speter		(void)sleep(2);
7718334Speter		for(i = 0; i < NSIGNALS; ++i) {
7818334Speter			(void)kill(pid, SIGUSR1);
7918334Speter			(void)sleep(2);
8018334Speter		}
8118334Speter		_exit(0);
8218334Speter		/* NOTREACHED */
8318334Speter	}
8418334Speter
8518334Speter	RL(kq = kqueue());
8618334Speter
8718334Speter	(void)strlcpy(namebuf, "EVFILT_SIGNAL", sizeof(namebuf));
8818334Speter	km.name = namebuf;
8918334Speter	RL(ioctl(kq, KFILTER_BYNAME, &km));
9018334Speter	(void)printf("got %d as filter number for `%s'.\n", km.filter, km.name);
9118334Speter
9218334Speter	/* ignore the signal to avoid taking it for real */
9318334Speter	REQUIRE_LIBC(signal(SIGUSR1, SIG_IGN), SIG_ERR);
9450397Sobrien
9550397Sobrien	event[0].ident = SIGUSR1;
9650397Sobrien	event[0].filter = km.filter;
9750397Sobrien	event[0].flags = EV_ADD | EV_ENABLE;
9850397Sobrien
9950397Sobrien	RL(kevent(kq, event, 1, NULL, 0, NULL));
10050397Sobrien
10190075Sobrien	(void)sleep(1);
10290075Sobrien
10390075Sobrien	timeout.tv_sec = 1;
10490075Sobrien	timeout.tv_nsec = 0;
10590075Sobrien
10690075Sobrien	for (num = 0; num < NSIGNALS; num += n) {
10790075Sobrien		struct timeval then, now, diff;
10890075Sobrien
10990075Sobrien		RL(gettimeofday(&then, NULL));
11090075Sobrien		RL(n = kevent(kq, NULL, 0, event, 1, &timeout));
11190075Sobrien		RL(gettimeofday(&now, NULL));
11290075Sobrien		timersub(&now, &then, &diff);
11390075Sobrien
11490075Sobrien		(void)printf("sig: kevent returned %d in %lld.%06ld\n",
11590075Sobrien		    n, (long long)diff.tv_sec, (long)diff.tv_usec);
11690075Sobrien
11790075Sobrien		if (n == 0)
11890075Sobrien			continue;
11990075Sobrien
12090075Sobrien#ifdef __FreeBSD__
12190075Sobrien		(void)printf("sig: kevent flags: 0x%x, data: %" PRIdPTR " (# "
12290075Sobrien#else
12390075Sobrien		(void)printf("sig: kevent flags: 0x%x, data: %" PRId64 " (# "
12490075Sobrien#endif
12590075Sobrien		    "times signal posted)\n", event[0].flags, event[0].data);
12690075Sobrien	}
12790075Sobrien
12890075Sobrien	(void)waitpid(child, &status, 0);
12990075Sobrien	(void)printf("sig: finished successfully\n");
13090075Sobrien}
13190075Sobrien
13290075SobrienATF_TP_ADD_TCS(tp)
13390075Sobrien{
134	ATF_TP_ADD_TC(tp, sig);
135
136	return atf_no_error();
137}
138