xref: /freebsd/tests/sys/kqueue/libkqueue/signal.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
1cb5fe245SEnji Cooper /*
2cb5fe245SEnji Cooper  * Copyright (c) 2009 Mark Heily <mark@heily.com>
3cb5fe245SEnji Cooper  *
4cb5fe245SEnji Cooper  * Permission to use, copy, modify, and distribute this software for any
5cb5fe245SEnji Cooper  * purpose with or without fee is hereby granted, provided that the above
6cb5fe245SEnji Cooper  * copyright notice and this permission notice appear in all copies.
7cb5fe245SEnji Cooper  *
8cb5fe245SEnji Cooper  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9cb5fe245SEnji Cooper  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10cb5fe245SEnji Cooper  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11cb5fe245SEnji Cooper  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12cb5fe245SEnji Cooper  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13cb5fe245SEnji Cooper  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14cb5fe245SEnji Cooper  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15cb5fe245SEnji Cooper  */
16cb5fe245SEnji Cooper 
17cb5fe245SEnji Cooper #include "common.h"
18cb5fe245SEnji Cooper 
19cb5fe245SEnji Cooper 
20*c9c283bdSAlex Richardson static void
test_kevent_signal_add(void)21cb5fe245SEnji Cooper test_kevent_signal_add(void)
22cb5fe245SEnji Cooper {
23cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)";
24cb5fe245SEnji Cooper     struct kevent kev;
25cb5fe245SEnji Cooper 
26cb5fe245SEnji Cooper     test_begin(test_id);
27cb5fe245SEnji Cooper 
28cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
29cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
30cb5fe245SEnji Cooper         err(1, "%s", test_id);
31cb5fe245SEnji Cooper 
32cb5fe245SEnji Cooper     success();
33cb5fe245SEnji Cooper }
34cb5fe245SEnji Cooper 
35*c9c283bdSAlex Richardson static void
test_kevent_signal_get(void)36cb5fe245SEnji Cooper test_kevent_signal_get(void)
37cb5fe245SEnji Cooper {
38cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, wait)";
39cb5fe245SEnji Cooper     struct kevent kev;
40cb5fe245SEnji Cooper 
41cb5fe245SEnji Cooper     test_begin(test_id);
42cb5fe245SEnji Cooper 
43cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
44cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
45cb5fe245SEnji Cooper         err(1, "%s", test_id);
46cb5fe245SEnji Cooper 
47cb5fe245SEnji Cooper     /* Block SIGUSR1, then send it to ourselves */
48cb5fe245SEnji Cooper     sigset_t mask;
49cb5fe245SEnji Cooper     sigemptyset(&mask);
50cb5fe245SEnji Cooper     sigaddset(&mask, SIGUSR1);
51cb5fe245SEnji Cooper     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
52cb5fe245SEnji Cooper         err(1, "sigprocmask");
53cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
54cb5fe245SEnji Cooper         err(1, "kill");
55cb5fe245SEnji Cooper 
56cb5fe245SEnji Cooper     kev.flags |= EV_CLEAR;
57cb5fe245SEnji Cooper     kev.data = 1;
58cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
59cb5fe245SEnji Cooper 
60cb5fe245SEnji Cooper     success();
61cb5fe245SEnji Cooper }
62cb5fe245SEnji Cooper 
63*c9c283bdSAlex Richardson static void
test_kevent_signal_disable(void)64cb5fe245SEnji Cooper test_kevent_signal_disable(void)
65cb5fe245SEnji Cooper {
66cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
67cb5fe245SEnji Cooper     struct kevent kev;
68cb5fe245SEnji Cooper 
69cb5fe245SEnji Cooper     test_begin(test_id);
70cb5fe245SEnji Cooper 
71cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
72cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
73cb5fe245SEnji Cooper         err(1, "%s", test_id);
74cb5fe245SEnji Cooper 
75cb5fe245SEnji Cooper     /* Block SIGUSR1, then send it to ourselves */
76cb5fe245SEnji Cooper     sigset_t mask;
77cb5fe245SEnji Cooper     sigemptyset(&mask);
78cb5fe245SEnji Cooper     sigaddset(&mask, SIGUSR1);
79cb5fe245SEnji Cooper     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
80cb5fe245SEnji Cooper         err(1, "sigprocmask");
81cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
82cb5fe245SEnji Cooper         err(1, "kill");
83cb5fe245SEnji Cooper 
84cb5fe245SEnji Cooper     test_no_kevents();
85cb5fe245SEnji Cooper 
86cb5fe245SEnji Cooper     success();
87cb5fe245SEnji Cooper }
88cb5fe245SEnji Cooper 
89*c9c283bdSAlex Richardson static void
test_kevent_signal_enable(void)90cb5fe245SEnji Cooper test_kevent_signal_enable(void)
91cb5fe245SEnji Cooper {
92cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
93cb5fe245SEnji Cooper     struct kevent kev;
94cb5fe245SEnji Cooper 
95cb5fe245SEnji Cooper     test_begin(test_id);
96cb5fe245SEnji Cooper 
97cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
98cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
99cb5fe245SEnji Cooper         err(1, "%s", test_id);
100cb5fe245SEnji Cooper 
101cb5fe245SEnji Cooper     /* Block SIGUSR1, then send it to ourselves */
102cb5fe245SEnji Cooper     sigset_t mask;
103cb5fe245SEnji Cooper     sigemptyset(&mask);
104cb5fe245SEnji Cooper     sigaddset(&mask, SIGUSR1);
105cb5fe245SEnji Cooper     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
106cb5fe245SEnji Cooper         err(1, "sigprocmask");
107cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
108cb5fe245SEnji Cooper         err(1, "kill");
109cb5fe245SEnji Cooper 
110cb5fe245SEnji Cooper     kev.flags = EV_ADD | EV_CLEAR;
111cb5fe245SEnji Cooper #if LIBKQUEUE
112cb5fe245SEnji Cooper     kev.data = 1; /* WORKAROUND */
113cb5fe245SEnji Cooper #else
114cb5fe245SEnji Cooper     kev.data = 2; // one extra time from test_kevent_signal_disable()
115cb5fe245SEnji Cooper #endif
116cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
117cb5fe245SEnji Cooper 
118cb5fe245SEnji Cooper     /* Delete the watch */
119cb5fe245SEnji Cooper     kev.flags = EV_DELETE;
120cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
121cb5fe245SEnji Cooper         err(1, "%s", test_id);
122cb5fe245SEnji Cooper 
123cb5fe245SEnji Cooper     success();
124cb5fe245SEnji Cooper }
125cb5fe245SEnji Cooper 
126*c9c283bdSAlex Richardson static void
test_kevent_signal_del(void)127cb5fe245SEnji Cooper test_kevent_signal_del(void)
128cb5fe245SEnji Cooper {
129cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
130cb5fe245SEnji Cooper     struct kevent kev;
131cb5fe245SEnji Cooper 
132cb5fe245SEnji Cooper     test_begin(test_id);
133cb5fe245SEnji Cooper 
134cb5fe245SEnji Cooper     /* Delete the kevent */
135cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
136cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
137cb5fe245SEnji Cooper         err(1, "%s", test_id);
138cb5fe245SEnji Cooper 
139cb5fe245SEnji Cooper     /* Block SIGUSR1, then send it to ourselves */
140cb5fe245SEnji Cooper     sigset_t mask;
141cb5fe245SEnji Cooper     sigemptyset(&mask);
142cb5fe245SEnji Cooper     sigaddset(&mask, SIGUSR1);
143cb5fe245SEnji Cooper     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
144cb5fe245SEnji Cooper         err(1, "sigprocmask");
145cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
146cb5fe245SEnji Cooper         err(1, "kill");
147cb5fe245SEnji Cooper 
148cb5fe245SEnji Cooper     test_no_kevents();
149cb5fe245SEnji Cooper     success();
150cb5fe245SEnji Cooper }
151cb5fe245SEnji Cooper 
152*c9c283bdSAlex Richardson static void
test_kevent_signal_oneshot(void)153cb5fe245SEnji Cooper test_kevent_signal_oneshot(void)
154cb5fe245SEnji Cooper {
155cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
156cb5fe245SEnji Cooper     struct kevent kev;
157cb5fe245SEnji Cooper 
158cb5fe245SEnji Cooper     test_begin(test_id);
159cb5fe245SEnji Cooper 
160cb5fe245SEnji Cooper     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
161cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
162cb5fe245SEnji Cooper         err(1, "%s", test_id);
163cb5fe245SEnji Cooper 
164cb5fe245SEnji Cooper     /* Block SIGUSR1, then send it to ourselves */
165cb5fe245SEnji Cooper     sigset_t mask;
166cb5fe245SEnji Cooper     sigemptyset(&mask);
167cb5fe245SEnji Cooper     sigaddset(&mask, SIGUSR1);
168cb5fe245SEnji Cooper     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
169cb5fe245SEnji Cooper         err(1, "sigprocmask");
170cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
171cb5fe245SEnji Cooper         err(1, "kill");
172cb5fe245SEnji Cooper 
173cb5fe245SEnji Cooper     kev.flags |= EV_CLEAR;
174cb5fe245SEnji Cooper     kev.data = 1;
175cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
176cb5fe245SEnji Cooper 
177cb5fe245SEnji Cooper     /* Send another one and make sure we get no events */
178cb5fe245SEnji Cooper     if (kill(getpid(), SIGUSR1) < 0)
179cb5fe245SEnji Cooper         err(1, "kill");
180cb5fe245SEnji Cooper     test_no_kevents();
181cb5fe245SEnji Cooper 
182cb5fe245SEnji Cooper     success();
183cb5fe245SEnji Cooper }
184cb5fe245SEnji Cooper 
185cb5fe245SEnji Cooper void
test_evfilt_signal(void)186*c9c283bdSAlex Richardson test_evfilt_signal(void)
187cb5fe245SEnji Cooper {
188cb5fe245SEnji Cooper     kqfd = kqueue();
189cb5fe245SEnji Cooper     test_kevent_signal_add();
190cb5fe245SEnji Cooper     test_kevent_signal_del();
191cb5fe245SEnji Cooper     test_kevent_signal_get();
192cb5fe245SEnji Cooper     test_kevent_signal_disable();
193cb5fe245SEnji Cooper     test_kevent_signal_enable();
194cb5fe245SEnji Cooper     test_kevent_signal_oneshot();
195cb5fe245SEnji Cooper     close(kqfd);
196cb5fe245SEnji Cooper }
197