1276479Sdim/* 2249259Sdim * Copyright (c) 2009 Mark Heily <mark@heily.com> 3249259Sdim * 4249259Sdim * Permission to use, copy, modify, and distribute this software for any 5249259Sdim * purpose with or without fee is hereby granted, provided that the above 6249259Sdim * copyright notice and this permission notice appear in all copies. 7249259Sdim * 8249259Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9249259Sdim * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10276479Sdim * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11249259Sdim * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12249259Sdim * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13249259Sdim * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14276479Sdim * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15280031Sdim * 16249259Sdim * $FreeBSD: stable/10/tests/sys/kqueue/libkqueue/signal.c 305467 2016-09-06 08:45:29Z ngie $ 17276479Sdim */ 18276479Sdim 19249259Sdim#include "common.h" 20276479Sdim 21249259Sdimint kqfd; 22276479Sdim 23276479Sdimvoid 24276479Sdimtest_kevent_signal_add(void) 25276479Sdim{ 26276479Sdim const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)"; 27249259Sdim struct kevent kev; 28249259Sdim 29249259Sdim test_begin(test_id); 30276479Sdim 31276479Sdim EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 32276479Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 33249259Sdim err(1, "%s", test_id); 34296417Sdim 35296417Sdim success(); 36296417Sdim} 37296417Sdim 38296417Sdimvoid 39276479Sdimtest_kevent_signal_get(void) 40276479Sdim{ 41276479Sdim const char *test_id = "kevent(EVFILT_SIGNAL, wait)"; 42261991Sdim struct kevent kev; 43276479Sdim 44276479Sdim test_begin(test_id); 45249259Sdim 46276479Sdim EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 47276479Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 48249259Sdim err(1, "%s", test_id); 49249259Sdim 50288943Sdim /* Block SIGUSR1, then send it to ourselves */ 51280031Sdim sigset_t mask; 52280031Sdim sigemptyset(&mask); 53276479Sdim sigaddset(&mask, SIGUSR1); 54296417Sdim if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 55296417Sdim err(1, "sigprocmask"); 56296417Sdim if (kill(getpid(), SIGUSR1) < 0) 57296417Sdim err(1, "kill"); 58296417Sdim 59288943Sdim kev.flags |= EV_CLEAR; 60288943Sdim kev.data = 1; 61261991Sdim kevent_cmp(&kev, kevent_get(kqfd)); 62276479Sdim 63276479Sdim success(); 64276479Sdim} 65276479Sdim 66276479Sdimvoid 67288943Sdimtest_kevent_signal_disable(void) 68276479Sdim{ 69276479Sdim const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)"; 70276479Sdim struct kevent kev; 71276479Sdim 72276479Sdim test_begin(test_id); 73276479Sdim 74276479Sdim EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL); 75280031Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 76288943Sdim err(1, "%s", test_id); 77280031Sdim 78280031Sdim /* Block SIGUSR1, then send it to ourselves */ 79280031Sdim sigset_t mask; 80280031Sdim sigemptyset(&mask); 81280031Sdim sigaddset(&mask, SIGUSR1); 82280031Sdim if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 83276479Sdim err(1, "sigprocmask"); 84276479Sdim if (kill(getpid(), SIGUSR1) < 0) 85276479Sdim err(1, "kill"); 86276479Sdim 87276479Sdim test_no_kevents(); 88276479Sdim 89276479Sdim success(); 90276479Sdim} 91276479Sdim 92276479Sdimvoid 93276479Sdimtest_kevent_signal_enable(void) 94288943Sdim{ 95261991Sdim const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)"; 96276479Sdim struct kevent kev; 97276479Sdim 98261991Sdim test_begin(test_id); 99261991Sdim 100276479Sdim EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL); 101261991Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 102261991Sdim err(1, "%s", test_id); 103276479Sdim 104276479Sdim /* Block SIGUSR1, then send it to ourselves */ 105276479Sdim sigset_t mask; 106276479Sdim sigemptyset(&mask); 107276479Sdim sigaddset(&mask, SIGUSR1); 108276479Sdim if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 109276479Sdim err(1, "sigprocmask"); 110276479Sdim if (kill(getpid(), SIGUSR1) < 0) 111276479Sdim err(1, "kill"); 112249259Sdim 113276479Sdim kev.flags = EV_ADD | EV_CLEAR; 114249259Sdim#if LIBKQUEUE 115276479Sdim kev.data = 1; /* WORKAROUND */ 116276479Sdim#else 117276479Sdim kev.data = 2; // one extra time from test_kevent_signal_disable() 118276479Sdim#endif 119276479Sdim kevent_cmp(&kev, kevent_get(kqfd)); 120276479Sdim 121276479Sdim /* Delete the watch */ 122276479Sdim kev.flags = EV_DELETE; 123296417Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 124296417Sdim err(1, "%s", test_id); 125296417Sdim 126296417Sdim success(); 127296417Sdim} 128276479Sdim 129276479Sdimvoid 130276479Sdimtest_kevent_signal_del(void) 131276479Sdim{ 132276479Sdim const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)"; 133280031Sdim struct kevent kev; 134296417Sdim 135296417Sdim test_begin(test_id); 136296417Sdim 137296417Sdim /* Delete the kevent */ 138296417Sdim EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); 139296417Sdim if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 140296417Sdim err(1, "%s", test_id); 141296417Sdim 142296417Sdim /* Block SIGUSR1, then send it to ourselves */ 143296417Sdim sigset_t mask; 144296417Sdim sigemptyset(&mask); 145296417Sdim sigaddset(&mask, SIGUSR1); 146296417Sdim if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 147280031Sdim err(1, "sigprocmask"); 148280031Sdim if (kill(getpid(), SIGUSR1) < 0) 149280031Sdim err(1, "kill"); 150280031Sdim 151280031Sdim test_no_kevents(); 152280031Sdim success(); 153280031Sdim} 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