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