]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/regression/kqueue/proc.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / regression / kqueue / proc.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 <sys/stat.h>
20
21 #include <err.h>
22
23 #include "config.h"
24 #include "common.h"
25
26 static int sigusr1_caught = 0;
27
28 int kqfd;
29
30 static void
31 sig_handler(int signum)
32 {
33     sigusr1_caught = 1;
34 }
35
36 static void
37 add_and_delete(void)
38 {
39     struct kevent kev;
40     pid_t pid;
41
42     /* Create a child that waits to be killed and then exits */
43     pid = fork();
44     if (pid == 0) {
45         struct stat s;
46         if (fstat(kqfd, &s) != -1)
47             errx(1, "kqueue inherited across fork! (%s() at %s:%d)",
48                 __func__, __FILE__, __LINE__);
49
50         pause();
51         exit(2);
52     }
53     printf(" -- child created (pid %d)\n", (int) pid);
54
55     test_begin("kevent(EVFILT_PROC, EV_ADD)");
56
57     test_no_kevents();
58     kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL);
59     test_no_kevents();
60
61     success();
62
63     test_begin("kevent(EVFILT_PROC, EV_DELETE)");
64
65     sleep(1);
66     test_no_kevents();
67     kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_DELETE, 0, 0, NULL);
68     if (kill(pid, SIGKILL) < 0)
69         err(1, "kill");
70     sleep(1);
71     test_no_kevents();
72
73     success();
74
75 }
76
77 #ifdef TODO
78 static void
79 event_trigger(void)
80 {
81     struct kevent kev;
82     pid_t pid;
83
84     test_begin("kevent(EVFILT_PROC, wait)");
85
86     /* Create a child that waits to be killed and then exits */
87     pid = fork();
88     if (pid == 0) {
89         pause();
90         printf(" -- child caught signal, exiting\n");
91         exit(2);
92     }
93     printf(" -- child created (pid %d)\n", (int) pid);
94
95     test_no_kevents();
96     kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL);
97
98     /* Cause the child to exit, then retrieve the event */
99     printf(" -- killing process %d\n", (int) pid);
100     if (kill(pid, SIGUSR1) < 0)
101         err(1, "kill");
102     kevent_cmp(&kev, kevent_get(kqfd));
103     test_no_kevents();
104
105     success();
106 }
107
108 void
109 test_kevent_signal_disable(void)
110 {
111     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
112     struct kevent kev;
113
114     test_begin(test_id);
115
116     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
117     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
118         err(1, "%s", test_id);
119
120     /* Block SIGUSR1, then send it to ourselves */
121     sigset_t mask;
122     sigemptyset(&mask);
123     sigaddset(&mask, SIGUSR1);
124     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
125         err(1, "sigprocmask");
126     if (kill(getpid(), SIGKILL) < 0)
127         err(1, "kill");
128
129     test_no_kevents();
130
131     success();
132 }
133
134 void
135 test_kevent_signal_enable(void)
136 {
137     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
138     struct kevent kev;
139
140     test_begin(test_id);
141
142     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
143     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
144         err(1, "%s", test_id);
145
146     /* Block SIGUSR1, then send it to ourselves */
147     sigset_t mask;
148     sigemptyset(&mask);
149     sigaddset(&mask, SIGUSR1);
150     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
151         err(1, "sigprocmask");
152     if (kill(getpid(), SIGUSR1) < 0)
153         err(1, "kill");
154
155     kev.flags = EV_ADD | EV_CLEAR;
156 #if LIBKQUEUE
157     kev.data = 1; /* WORKAROUND */
158 #else
159     kev.data = 2; // one extra time from test_kevent_signal_disable()
160 #endif
161     kevent_cmp(&kev, kevent_get(kqfd));
162
163     /* Delete the watch */
164     kev.flags = EV_DELETE;
165     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
166         err(1, "%s", test_id);
167
168     success();
169 }
170
171 void
172 test_kevent_signal_del(void)
173 {
174     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
175     struct kevent kev;
176
177     test_begin(test_id);
178
179     /* Delete the kevent */
180     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
181     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
182         err(1, "%s", test_id);
183
184     /* Block SIGUSR1, then send it to ourselves */
185     sigset_t mask;
186     sigemptyset(&mask);
187     sigaddset(&mask, SIGUSR1);
188     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
189         err(1, "sigprocmask");
190     if (kill(getpid(), SIGUSR1) < 0)
191         err(1, "kill");
192
193     test_no_kevents();
194     success();
195 }
196
197 void
198 test_kevent_signal_oneshot(void)
199 {
200     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
201     struct kevent kev;
202
203     test_begin(test_id);
204
205     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
206     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
207         err(1, "%s", test_id);
208
209     /* Block SIGUSR1, then send it to ourselves */
210     sigset_t mask;
211     sigemptyset(&mask);
212     sigaddset(&mask, SIGUSR1);
213     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
214         err(1, "sigprocmask");
215     if (kill(getpid(), SIGUSR1) < 0)
216         err(1, "kill");
217
218     kev.flags |= EV_CLEAR;
219     kev.data = 1;
220     kevent_cmp(&kev, kevent_get(kqfd));
221
222     /* Send another one and make sure we get no events */
223     if (kill(getpid(), SIGUSR1) < 0)
224         err(1, "kill");
225     test_no_kevents();
226
227     success();
228 }
229 #endif
230
231 void
232 test_evfilt_proc()
233 {
234     kqfd = kqueue();
235
236     signal(SIGUSR1, sig_handler);
237
238     add_and_delete();
239
240 #if TODO
241     event_trigger();
242 #endif
243
244     signal(SIGUSR1, SIG_DFL);
245
246 #if TODO
247     test_kevent_signal_add();
248     test_kevent_signal_del();
249     test_kevent_signal_get();
250     test_kevent_signal_disable();
251     test_kevent_signal_enable();
252     test_kevent_signal_oneshot();
253 #endif
254     close(kqfd);
255 }