signal.c revision 200483
1239922Sgonzo/*
2239922Sgonzo * Copyright (c) 2009 Mark Heily <mark@heily.com>
3239922Sgonzo *
4239922Sgonzo * Permission to use, copy, modify, and distribute this software for any
5239922Sgonzo * purpose with or without fee is hereby granted, provided that the above
6239922Sgonzo * copyright notice and this permission notice appear in all copies.
7239922Sgonzo *
8239922Sgonzo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9239922Sgonzo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10239922Sgonzo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11239922Sgonzo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12239922Sgonzo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13239922Sgonzo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14239922Sgonzo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15239922Sgonzo *
16239922Sgonzo * $FreeBSD: head/tools/regression/kqueue/signal.c 200483 2009-12-13 20:27:46Z rwatson $
17239922Sgonzo */
18239922Sgonzo
19239922Sgonzo#include "common.h"
20239922Sgonzo
21239922Sgonzoint kqfd;
22239922Sgonzo
23239922Sgonzovoid
24239922Sgonzotest_kevent_signal_add(void)
25239922Sgonzo{
26239922Sgonzo    const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)";
27239922Sgonzo    struct kevent kev;
28239922Sgonzo
29239922Sgonzo    test_begin(test_id);
30239922Sgonzo
31239922Sgonzo    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
32239922Sgonzo    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
33239922Sgonzo        err(1, "%s", test_id);
34239922Sgonzo
35239922Sgonzo    success();
36239922Sgonzo}
37247204Sgonzo
38239922Sgonzovoid
39239922Sgonzotest_kevent_signal_get(void)
40322724Smarius{
41322724Smarius    const char *test_id = "kevent(EVFILT_SIGNAL, wait)";
42322724Smarius    struct kevent kev;
43322724Smarius
44247204Sgonzo    test_begin(test_id);
45322724Smarius
46322724Smarius    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
47322724Smarius    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
48247204Sgonzo        err(1, "%s", test_id);
49239922Sgonzo
50239922Sgonzo    /* Block SIGUSR1, then send it to ourselves */
51239922Sgonzo    sigset_t mask;
52239922Sgonzo    sigemptyset(&mask);
53322724Smarius    sigaddset(&mask, SIGUSR1);
54239922Sgonzo    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
55247204Sgonzo        err(1, "sigprocmask");
56247204Sgonzo    if (kill(getpid(), SIGUSR1) < 0)
57247204Sgonzo        err(1, "kill");
58247204Sgonzo
59239922Sgonzo    kev.flags |= EV_CLEAR;
60247204Sgonzo    kev.data = 1;
61247204Sgonzo    kevent_cmp(&kev, kevent_get(kqfd));
62247204Sgonzo
63247204Sgonzo    success();
64247204Sgonzo}
65247204Sgonzo
66239922Sgonzovoid
67239922Sgonzotest_kevent_signal_disable(void)
68239922Sgonzo{
69239922Sgonzo    const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
70322724Smarius    struct kevent kev;
71239922Sgonzo
72239922Sgonzo    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
92void
93test_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
129void
130test_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
155void
156test_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
188void
189test_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