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