xref: /src/tests/sys/kqueue/libkqueue/signal.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
160a396a4SRobert Watson /*
260a396a4SRobert Watson  * Copyright (c) 2009 Mark Heily <mark@heily.com>
360a396a4SRobert Watson  *
460a396a4SRobert Watson  * Permission to use, copy, modify, and distribute this software for any
560a396a4SRobert Watson  * purpose with or without fee is hereby granted, provided that the above
660a396a4SRobert Watson  * copyright notice and this permission notice appear in all copies.
760a396a4SRobert Watson  *
860a396a4SRobert Watson  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
960a396a4SRobert Watson  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1060a396a4SRobert Watson  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1160a396a4SRobert Watson  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1260a396a4SRobert Watson  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1360a396a4SRobert Watson  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1460a396a4SRobert Watson  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1560a396a4SRobert Watson  */
1660a396a4SRobert Watson 
1760a396a4SRobert Watson #include "common.h"
1860a396a4SRobert Watson 
1960a396a4SRobert Watson 
20c9c283bdSAlex Richardson static void
test_kevent_signal_add(void)2160a396a4SRobert Watson test_kevent_signal_add(void)
2260a396a4SRobert Watson {
2360a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)";
2460a396a4SRobert Watson     struct kevent kev;
2560a396a4SRobert Watson 
2660a396a4SRobert Watson     test_begin(test_id);
2760a396a4SRobert Watson 
2860a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
2960a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
3060a396a4SRobert Watson         err(1, "%s", test_id);
3160a396a4SRobert Watson 
3260a396a4SRobert Watson     success();
3360a396a4SRobert Watson }
3460a396a4SRobert Watson 
35c9c283bdSAlex Richardson static void
test_kevent_signal_get(void)3660a396a4SRobert Watson test_kevent_signal_get(void)
3760a396a4SRobert Watson {
3860a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, wait)";
3960a396a4SRobert Watson     struct kevent kev;
4060a396a4SRobert Watson 
4160a396a4SRobert Watson     test_begin(test_id);
4260a396a4SRobert Watson 
4360a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
4460a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
4560a396a4SRobert Watson         err(1, "%s", test_id);
4660a396a4SRobert Watson 
4760a396a4SRobert Watson     /* Block SIGUSR1, then send it to ourselves */
4860a396a4SRobert Watson     sigset_t mask;
4960a396a4SRobert Watson     sigemptyset(&mask);
5060a396a4SRobert Watson     sigaddset(&mask, SIGUSR1);
5160a396a4SRobert Watson     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
5260a396a4SRobert Watson         err(1, "sigprocmask");
5360a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
5460a396a4SRobert Watson         err(1, "kill");
5560a396a4SRobert Watson 
5660a396a4SRobert Watson     kev.flags |= EV_CLEAR;
5760a396a4SRobert Watson     kev.data = 1;
5860a396a4SRobert Watson     kevent_cmp(&kev, kevent_get(kqfd));
5960a396a4SRobert Watson 
6060a396a4SRobert Watson     success();
6160a396a4SRobert Watson }
6260a396a4SRobert Watson 
63c9c283bdSAlex Richardson static void
test_kevent_signal_disable(void)6460a396a4SRobert Watson test_kevent_signal_disable(void)
6560a396a4SRobert Watson {
6660a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
6760a396a4SRobert Watson     struct kevent kev;
6860a396a4SRobert Watson 
6960a396a4SRobert Watson     test_begin(test_id);
7060a396a4SRobert Watson 
7160a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
7260a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
7360a396a4SRobert Watson         err(1, "%s", test_id);
7460a396a4SRobert Watson 
7560a396a4SRobert Watson     /* Block SIGUSR1, then send it to ourselves */
7660a396a4SRobert Watson     sigset_t mask;
7760a396a4SRobert Watson     sigemptyset(&mask);
7860a396a4SRobert Watson     sigaddset(&mask, SIGUSR1);
7960a396a4SRobert Watson     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
8060a396a4SRobert Watson         err(1, "sigprocmask");
8160a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
8260a396a4SRobert Watson         err(1, "kill");
8360a396a4SRobert Watson 
8460a396a4SRobert Watson     test_no_kevents();
8560a396a4SRobert Watson 
8660a396a4SRobert Watson     success();
8760a396a4SRobert Watson }
8860a396a4SRobert Watson 
89c9c283bdSAlex Richardson static void
test_kevent_signal_enable(void)9060a396a4SRobert Watson test_kevent_signal_enable(void)
9160a396a4SRobert Watson {
9260a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
9360a396a4SRobert Watson     struct kevent kev;
9460a396a4SRobert Watson 
9560a396a4SRobert Watson     test_begin(test_id);
9660a396a4SRobert Watson 
9760a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
9860a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
9960a396a4SRobert Watson         err(1, "%s", test_id);
10060a396a4SRobert Watson 
10160a396a4SRobert Watson     /* Block SIGUSR1, then send it to ourselves */
10260a396a4SRobert Watson     sigset_t mask;
10360a396a4SRobert Watson     sigemptyset(&mask);
10460a396a4SRobert Watson     sigaddset(&mask, SIGUSR1);
10560a396a4SRobert Watson     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
10660a396a4SRobert Watson         err(1, "sigprocmask");
10760a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
10860a396a4SRobert Watson         err(1, "kill");
10960a396a4SRobert Watson 
11060a396a4SRobert Watson     kev.flags = EV_ADD | EV_CLEAR;
11160a396a4SRobert Watson #if LIBKQUEUE
11260a396a4SRobert Watson     kev.data = 1; /* WORKAROUND */
11360a396a4SRobert Watson #else
11460a396a4SRobert Watson     kev.data = 2; // one extra time from test_kevent_signal_disable()
11560a396a4SRobert Watson #endif
11660a396a4SRobert Watson     kevent_cmp(&kev, kevent_get(kqfd));
11760a396a4SRobert Watson 
11860a396a4SRobert Watson     /* Delete the watch */
11960a396a4SRobert Watson     kev.flags = EV_DELETE;
12060a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
12160a396a4SRobert Watson         err(1, "%s", test_id);
12260a396a4SRobert Watson 
12360a396a4SRobert Watson     success();
12460a396a4SRobert Watson }
12560a396a4SRobert Watson 
126c9c283bdSAlex Richardson static void
test_kevent_signal_del(void)12760a396a4SRobert Watson test_kevent_signal_del(void)
12860a396a4SRobert Watson {
12960a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
13060a396a4SRobert Watson     struct kevent kev;
13160a396a4SRobert Watson 
13260a396a4SRobert Watson     test_begin(test_id);
13360a396a4SRobert Watson 
13460a396a4SRobert Watson     /* Delete the kevent */
13560a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
13660a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
13760a396a4SRobert Watson         err(1, "%s", test_id);
13860a396a4SRobert Watson 
13960a396a4SRobert Watson     /* Block SIGUSR1, then send it to ourselves */
14060a396a4SRobert Watson     sigset_t mask;
14160a396a4SRobert Watson     sigemptyset(&mask);
14260a396a4SRobert Watson     sigaddset(&mask, SIGUSR1);
14360a396a4SRobert Watson     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
14460a396a4SRobert Watson         err(1, "sigprocmask");
14560a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
14660a396a4SRobert Watson         err(1, "kill");
14760a396a4SRobert Watson 
14860a396a4SRobert Watson     test_no_kevents();
14960a396a4SRobert Watson     success();
15060a396a4SRobert Watson }
15160a396a4SRobert Watson 
152c9c283bdSAlex Richardson static void
test_kevent_signal_oneshot(void)15360a396a4SRobert Watson test_kevent_signal_oneshot(void)
15460a396a4SRobert Watson {
15560a396a4SRobert Watson     const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
15660a396a4SRobert Watson     struct kevent kev;
15760a396a4SRobert Watson 
15860a396a4SRobert Watson     test_begin(test_id);
15960a396a4SRobert Watson 
16060a396a4SRobert Watson     EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
16160a396a4SRobert Watson     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
16260a396a4SRobert Watson         err(1, "%s", test_id);
16360a396a4SRobert Watson 
16460a396a4SRobert Watson     /* Block SIGUSR1, then send it to ourselves */
16560a396a4SRobert Watson     sigset_t mask;
16660a396a4SRobert Watson     sigemptyset(&mask);
16760a396a4SRobert Watson     sigaddset(&mask, SIGUSR1);
16860a396a4SRobert Watson     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
16960a396a4SRobert Watson         err(1, "sigprocmask");
17060a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
17160a396a4SRobert Watson         err(1, "kill");
17260a396a4SRobert Watson 
17360a396a4SRobert Watson     kev.flags |= EV_CLEAR;
17460a396a4SRobert Watson     kev.data = 1;
17560a396a4SRobert Watson     kevent_cmp(&kev, kevent_get(kqfd));
17660a396a4SRobert Watson 
17760a396a4SRobert Watson     /* Send another one and make sure we get no events */
17860a396a4SRobert Watson     if (kill(getpid(), SIGUSR1) < 0)
17960a396a4SRobert Watson         err(1, "kill");
18060a396a4SRobert Watson     test_no_kevents();
18160a396a4SRobert Watson 
18260a396a4SRobert Watson     success();
18360a396a4SRobert Watson }
18460a396a4SRobert Watson 
18560a396a4SRobert Watson void
test_evfilt_signal(void)186c9c283bdSAlex Richardson test_evfilt_signal(void)
18760a396a4SRobert Watson {
18860a396a4SRobert Watson     kqfd = kqueue();
18960a396a4SRobert Watson     test_kevent_signal_add();
19060a396a4SRobert Watson     test_kevent_signal_del();
19160a396a4SRobert Watson     test_kevent_signal_get();
19260a396a4SRobert Watson     test_kevent_signal_disable();
19360a396a4SRobert Watson     test_kevent_signal_enable();
19460a396a4SRobert Watson     test_kevent_signal_oneshot();
19560a396a4SRobert Watson     close(kqfd);
19660a396a4SRobert Watson }
197