xref: /freebsd/tests/sys/kqueue/kqueue_peek_signal.c (revision d7d962ead0b6e5e8a39202d0590022082bf5bfb6)
1*d7d962eaSAlex Richardson /*-
2*d7d962eaSAlex Richardson  * SPDX-License-Identifier: BSD-2-Clause
3*d7d962eaSAlex Richardson  *
4*d7d962eaSAlex Richardson  * Copyright 2021 Jan Kokemüller
5*d7d962eaSAlex Richardson  * Copyright 2021 Alex Richardson <arichardson@FreeBSD.org>
6*d7d962eaSAlex Richardson  *
7*d7d962eaSAlex Richardson  * This work was supported by Innovate UK project 105694, "Digital Security by
8*d7d962eaSAlex Richardson  * Design (DSbD) Technology Platform Prototype".
9*d7d962eaSAlex Richardson  *
10*d7d962eaSAlex Richardson  * Redistribution and use in source and binary forms, with or without
11*d7d962eaSAlex Richardson  * modification, are permitted provided that the following conditions
12*d7d962eaSAlex Richardson  * are met:
13*d7d962eaSAlex Richardson  * 1. Redistributions of source code must retain the above copyright
14*d7d962eaSAlex Richardson  *    notice, this list of conditions and the following disclaimer.
15*d7d962eaSAlex Richardson  * 2. Redistributions in binary form must reproduce the above copyright
16*d7d962eaSAlex Richardson  *    notice, this list of conditions and the following disclaimer in the
17*d7d962eaSAlex Richardson  *    documentation and/or other materials provided with the distribution.
18*d7d962eaSAlex Richardson  *
19*d7d962eaSAlex Richardson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20*d7d962eaSAlex Richardson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*d7d962eaSAlex Richardson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*d7d962eaSAlex Richardson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23*d7d962eaSAlex Richardson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*d7d962eaSAlex Richardson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*d7d962eaSAlex Richardson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*d7d962eaSAlex Richardson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*d7d962eaSAlex Richardson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*d7d962eaSAlex Richardson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*d7d962eaSAlex Richardson  * SUCH DAMAGE.
30*d7d962eaSAlex Richardson  */
31*d7d962eaSAlex Richardson #include <sys/cdefs.h>
32*d7d962eaSAlex Richardson #include <sys/event.h>
33*d7d962eaSAlex Richardson 
34*d7d962eaSAlex Richardson #include <atf-c.h>
35*d7d962eaSAlex Richardson #include <errno.h>
36*d7d962eaSAlex Richardson #include <signal.h>
37*d7d962eaSAlex Richardson 
38*d7d962eaSAlex Richardson ATF_TC_WITHOUT_HEAD(main);
39*d7d962eaSAlex Richardson 
ATF_TC_BODY(main,tc)40*d7d962eaSAlex Richardson ATF_TC_BODY(main, tc)
41*d7d962eaSAlex Richardson {
42*d7d962eaSAlex Richardson 	int rv;
43*d7d962eaSAlex Richardson 
44*d7d962eaSAlex Richardson 	sigset_t set;
45*d7d962eaSAlex Richardson 	rv = sigemptyset(&set);
46*d7d962eaSAlex Richardson 	ATF_REQUIRE_EQ(0, rv);
47*d7d962eaSAlex Richardson 	rv = sigaddset(&set, SIGUSR1);
48*d7d962eaSAlex Richardson 	ATF_REQUIRE_EQ(0, rv);
49*d7d962eaSAlex Richardson 	rv = sigprocmask(SIG_BLOCK, &set, NULL);
50*d7d962eaSAlex Richardson 	ATF_REQUIRE_EQ(0, rv);
51*d7d962eaSAlex Richardson 
52*d7d962eaSAlex Richardson 	int skq = kqueue();
53*d7d962eaSAlex Richardson 	ATF_REQUIRE(skq >= 0);
54*d7d962eaSAlex Richardson 
55*d7d962eaSAlex Richardson 	struct kevent kev;
56*d7d962eaSAlex Richardson 	EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
57*d7d962eaSAlex Richardson 	rv = kevent(skq, &kev, 1, NULL, 0, NULL);
58*d7d962eaSAlex Richardson 	ATF_REQUIRE_EQ(0, rv);
59*d7d962eaSAlex Richardson 
60*d7d962eaSAlex Richardson 	int kq = kqueue();
61*d7d962eaSAlex Richardson 	ATF_REQUIRE(kq >= 0);
62*d7d962eaSAlex Richardson 
63*d7d962eaSAlex Richardson 	EV_SET(&kev, skq, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0);
64*d7d962eaSAlex Richardson 	rv = kevent(kq, &kev, 1, NULL, 0, NULL);
65*d7d962eaSAlex Richardson 	ATF_REQUIRE_EQ(0, rv);
66*d7d962eaSAlex Richardson 
67*d7d962eaSAlex Richardson 	/*
68*d7d962eaSAlex Richardson 	 * It was previously not guaranteed that sending a signal to self would
69*d7d962eaSAlex Richardson 	 * be immediately visible in the nested kqueue activation with a zero
70*d7d962eaSAlex Richardson 	 * timeout. As of https://reviews.freebsd.org/D31858, the kqueue task
71*d7d962eaSAlex Richardson 	 * queue will be processed in this case, so we are guaranteed to see the
72*d7d962eaSAlex Richardson 	 * SIGUSR1 here even with a zero timeout. We run the code below in a
73*d7d962eaSAlex Richardson 	 * loop to make it more likely that older kernels without the fix fail
74*d7d962eaSAlex Richardson 	 * this test.
75*d7d962eaSAlex Richardson 	 */
76*d7d962eaSAlex Richardson 	for (int i = 0; i < 100; i++) {
77*d7d962eaSAlex Richardson 		rv = kill(getpid(), SIGUSR1);
78*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ(0, rv);
79*d7d962eaSAlex Richardson 
80*d7d962eaSAlex Richardson 		rv = kevent(kq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
81*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ_MSG(1, rv,
82*d7d962eaSAlex Richardson 		    "Unexpected result %d from kevent() after %d iterations",
83*d7d962eaSAlex Richardson 		    rv, i);
84*d7d962eaSAlex Richardson 		rv = kevent(kq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
85*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ(0, rv);
86*d7d962eaSAlex Richardson 
87*d7d962eaSAlex Richardson 		rv = kevent(skq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
88*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ(1, rv);
89*d7d962eaSAlex Richardson 		rv = kevent(skq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
90*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ(0, rv);
91*d7d962eaSAlex Richardson 
92*d7d962eaSAlex Richardson 		siginfo_t siginfo;
93*d7d962eaSAlex Richardson 		rv = sigtimedwait(&set, &siginfo, &(struct timespec) { 0, 0 });
94*d7d962eaSAlex Richardson 		ATF_REQUIRE_EQ(SIGUSR1, rv);
95*d7d962eaSAlex Richardson 
96*d7d962eaSAlex Richardson 		rv = sigtimedwait(&set, &siginfo, &(struct timespec) { 0, 0 });
97*d7d962eaSAlex Richardson 		ATF_REQUIRE_ERRNO(EAGAIN, rv < 0);
98*d7d962eaSAlex Richardson 	}
99*d7d962eaSAlex Richardson }
100*d7d962eaSAlex Richardson 
ATF_TP_ADD_TCS(tp)101*d7d962eaSAlex Richardson ATF_TP_ADD_TCS(tp)
102*d7d962eaSAlex Richardson {
103*d7d962eaSAlex Richardson 	ATF_TP_ADD_TC(tp, main);
104*d7d962eaSAlex Richardson 
105*d7d962eaSAlex Richardson 	return (atf_no_error());
106*d7d962eaSAlex Richardson }
107