]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/regression/kqueue/signal.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / regression / kqueue / signal.c
1 /*
2  * Copyright (c) 2009 Mark Heily <mark@heily.com>
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
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
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
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
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
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
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
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 }