1200483Srwatson/*
2200483Srwatson * Copyright (c) 2009 Mark Heily <mark@heily.com>
3200483Srwatson *
4200483Srwatson * Permission to use, copy, modify, and distribute this software for any
5200483Srwatson * purpose with or without fee is hereby granted, provided that the above
6200483Srwatson * copyright notice and this permission notice appear in all copies.
7200483Srwatson *
8200483Srwatson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9200483Srwatson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10200483Srwatson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11200483Srwatson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12200483Srwatson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13200483Srwatson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14200483Srwatson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15200483Srwatson *
16200483Srwatson * $FreeBSD: releng/10.2/tests/sys/kqueue/signal.c 200483 2009-12-13 20:27:46Z rwatson $
17200483Srwatson */
18200483Srwatson
19200483Srwatson#include "common.h"
20200483Srwatson
21200483Srwatsonint kqfd;
22200483Srwatson
23200483Srwatsonvoid
24200483Srwatsontest_kevent_signal_add(void)
25200483Srwatson{
26200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)";
27200483Srwatson    struct kevent kev;
28200483Srwatson
29200483Srwatson    test_begin(test_id);
30200483Srwatson
31200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
32200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
33200483Srwatson        err(1, "%s", test_id);
34200483Srwatson
35200483Srwatson    success();
36200483Srwatson}
37200483Srwatson
38200483Srwatsonvoid
39200483Srwatsontest_kevent_signal_get(void)
40200483Srwatson{
41200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, wait)";
42200483Srwatson    struct kevent kev;
43200483Srwatson
44200483Srwatson    test_begin(test_id);
45200483Srwatson
46200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
47200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
48200483Srwatson        err(1, "%s", test_id);
49200483Srwatson
50200483Srwatson    /* Block SIGUSR1, then send it to ourselves */
51200483Srwatson    sigset_t mask;
52200483Srwatson    sigemptyset(&mask);
53200483Srwatson    sigaddset(&mask, SIGUSR1);
54200483Srwatson    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
55200483Srwatson        err(1, "sigprocmask");
56200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
57200483Srwatson        err(1, "kill");
58200483Srwatson
59200483Srwatson    kev.flags |= EV_CLEAR;
60200483Srwatson    kev.data = 1;
61200483Srwatson    kevent_cmp(&kev, kevent_get(kqfd));
62200483Srwatson
63200483Srwatson    success();
64200483Srwatson}
65200483Srwatson
66200483Srwatsonvoid
67200483Srwatsontest_kevent_signal_disable(void)
68200483Srwatson{
69200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
70200483Srwatson    struct kevent kev;
71200483Srwatson
72200483Srwatson    test_begin(test_id);
73200483Srwatson
74200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
75200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
76200483Srwatson        err(1, "%s", test_id);
77200483Srwatson
78200483Srwatson    /* Block SIGUSR1, then send it to ourselves */
79200483Srwatson    sigset_t mask;
80200483Srwatson    sigemptyset(&mask);
81200483Srwatson    sigaddset(&mask, SIGUSR1);
82200483Srwatson    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
83200483Srwatson        err(1, "sigprocmask");
84200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
85200483Srwatson        err(1, "kill");
86200483Srwatson
87200483Srwatson    test_no_kevents();
88200483Srwatson
89200483Srwatson    success();
90200483Srwatson}
91200483Srwatson
92200483Srwatsonvoid
93200483Srwatsontest_kevent_signal_enable(void)
94200483Srwatson{
95200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
96200483Srwatson    struct kevent kev;
97200483Srwatson
98200483Srwatson    test_begin(test_id);
99200483Srwatson
100200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
101200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
102200483Srwatson        err(1, "%s", test_id);
103200483Srwatson
104200483Srwatson    /* Block SIGUSR1, then send it to ourselves */
105200483Srwatson    sigset_t mask;
106200483Srwatson    sigemptyset(&mask);
107200483Srwatson    sigaddset(&mask, SIGUSR1);
108200483Srwatson    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
109200483Srwatson        err(1, "sigprocmask");
110200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
111200483Srwatson        err(1, "kill");
112200483Srwatson
113200483Srwatson    kev.flags = EV_ADD | EV_CLEAR;
114200483Srwatson#if LIBKQUEUE
115200483Srwatson    kev.data = 1; /* WORKAROUND */
116200483Srwatson#else
117200483Srwatson    kev.data = 2; // one extra time from test_kevent_signal_disable()
118200483Srwatson#endif
119200483Srwatson    kevent_cmp(&kev, kevent_get(kqfd));
120200483Srwatson
121200483Srwatson    /* Delete the watch */
122200483Srwatson    kev.flags = EV_DELETE;
123200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
124200483Srwatson        err(1, "%s", test_id);
125200483Srwatson
126200483Srwatson    success();
127200483Srwatson}
128200483Srwatson
129200483Srwatsonvoid
130200483Srwatsontest_kevent_signal_del(void)
131200483Srwatson{
132200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
133200483Srwatson    struct kevent kev;
134200483Srwatson
135200483Srwatson    test_begin(test_id);
136200483Srwatson
137200483Srwatson    /* Delete the kevent */
138200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
139200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
140200483Srwatson        err(1, "%s", test_id);
141200483Srwatson
142200483Srwatson    /* Block SIGUSR1, then send it to ourselves */
143200483Srwatson    sigset_t mask;
144200483Srwatson    sigemptyset(&mask);
145200483Srwatson    sigaddset(&mask, SIGUSR1);
146200483Srwatson    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
147200483Srwatson        err(1, "sigprocmask");
148200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
149200483Srwatson        err(1, "kill");
150200483Srwatson
151200483Srwatson    test_no_kevents();
152200483Srwatson    success();
153200483Srwatson}
154200483Srwatson
155200483Srwatsonvoid
156200483Srwatsontest_kevent_signal_oneshot(void)
157200483Srwatson{
158200483Srwatson    const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
159200483Srwatson    struct kevent kev;
160200483Srwatson
161200483Srwatson    test_begin(test_id);
162200483Srwatson
163200483Srwatson    EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
164200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
165200483Srwatson        err(1, "%s", test_id);
166200483Srwatson
167200483Srwatson    /* Block SIGUSR1, then send it to ourselves */
168200483Srwatson    sigset_t mask;
169200483Srwatson    sigemptyset(&mask);
170200483Srwatson    sigaddset(&mask, SIGUSR1);
171200483Srwatson    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
172200483Srwatson        err(1, "sigprocmask");
173200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
174200483Srwatson        err(1, "kill");
175200483Srwatson
176200483Srwatson    kev.flags |= EV_CLEAR;
177200483Srwatson    kev.data = 1;
178200483Srwatson    kevent_cmp(&kev, kevent_get(kqfd));
179200483Srwatson
180200483Srwatson    /* Send another one and make sure we get no events */
181200483Srwatson    if (kill(getpid(), SIGUSR1) < 0)
182200483Srwatson        err(1, "kill");
183200483Srwatson    test_no_kevents();
184200483Srwatson
185200483Srwatson    success();
186200483Srwatson}
187200483Srwatson
188200483Srwatsonvoid
189200483Srwatsontest_evfilt_signal()
190200483Srwatson{
191200483Srwatson	kqfd = kqueue();
192200483Srwatson        test_kevent_signal_add();
193200483Srwatson        test_kevent_signal_del();
194200483Srwatson        test_kevent_signal_get();
195200483Srwatson        test_kevent_signal_disable();
196200483Srwatson        test_kevent_signal_enable();
197200483Srwatson        test_kevent_signal_oneshot();
198200483Srwatson	close(kqfd);
199200483Srwatson}
200