signal.c revision 200483
1239922Sgonzo/* 2239922Sgonzo * Copyright (c) 2009 Mark Heily <mark@heily.com> 3239922Sgonzo * 4239922Sgonzo * Permission to use, copy, modify, and distribute this software for any 5239922Sgonzo * purpose with or without fee is hereby granted, provided that the above 6239922Sgonzo * copyright notice and this permission notice appear in all copies. 7239922Sgonzo * 8239922Sgonzo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9239922Sgonzo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10239922Sgonzo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11239922Sgonzo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12239922Sgonzo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13239922Sgonzo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14239922Sgonzo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15239922Sgonzo * 16239922Sgonzo * $FreeBSD: head/tools/regression/kqueue/signal.c 200483 2009-12-13 20:27:46Z rwatson $ 17239922Sgonzo */ 18239922Sgonzo 19239922Sgonzo#include "common.h" 20239922Sgonzo 21239922Sgonzoint kqfd; 22239922Sgonzo 23239922Sgonzovoid 24239922Sgonzotest_kevent_signal_add(void) 25239922Sgonzo{ 26239922Sgonzo const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)"; 27239922Sgonzo struct kevent kev; 28239922Sgonzo 29239922Sgonzo test_begin(test_id); 30239922Sgonzo 31239922Sgonzo EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 32239922Sgonzo if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 33239922Sgonzo err(1, "%s", test_id); 34239922Sgonzo 35239922Sgonzo success(); 36239922Sgonzo} 37247204Sgonzo 38239922Sgonzovoid 39239922Sgonzotest_kevent_signal_get(void) 40322724Smarius{ 41322724Smarius const char *test_id = "kevent(EVFILT_SIGNAL, wait)"; 42322724Smarius struct kevent kev; 43322724Smarius 44247204Sgonzo test_begin(test_id); 45322724Smarius 46322724Smarius EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 47322724Smarius if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 48247204Sgonzo err(1, "%s", test_id); 49239922Sgonzo 50239922Sgonzo /* Block SIGUSR1, then send it to ourselves */ 51239922Sgonzo sigset_t mask; 52239922Sgonzo sigemptyset(&mask); 53322724Smarius sigaddset(&mask, SIGUSR1); 54239922Sgonzo if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 55247204Sgonzo err(1, "sigprocmask"); 56247204Sgonzo if (kill(getpid(), SIGUSR1) < 0) 57247204Sgonzo err(1, "kill"); 58247204Sgonzo 59239922Sgonzo kev.flags |= EV_CLEAR; 60247204Sgonzo kev.data = 1; 61247204Sgonzo kevent_cmp(&kev, kevent_get(kqfd)); 62247204Sgonzo 63247204Sgonzo success(); 64247204Sgonzo} 65247204Sgonzo 66239922Sgonzovoid 67239922Sgonzotest_kevent_signal_disable(void) 68239922Sgonzo{ 69239922Sgonzo const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)"; 70322724Smarius struct kevent kev; 71239922Sgonzo 72239922Sgonzo test_begin(test_id); 73 74 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL); 75 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 76 err(1, "%s", test_id); 77 78 /* Block SIGUSR1, then send it to ourselves */ 79 sigset_t mask; 80 sigemptyset(&mask); 81 sigaddset(&mask, SIGUSR1); 82 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 83 err(1, "sigprocmask"); 84 if (kill(getpid(), SIGUSR1) < 0) 85 err(1, "kill"); 86 87 test_no_kevents(); 88 89 success(); 90} 91 92void 93test_kevent_signal_enable(void) 94{ 95 const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)"; 96 struct kevent kev; 97 98 test_begin(test_id); 99 100 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL); 101 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 102 err(1, "%s", test_id); 103 104 /* Block SIGUSR1, then send it to ourselves */ 105 sigset_t mask; 106 sigemptyset(&mask); 107 sigaddset(&mask, SIGUSR1); 108 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 109 err(1, "sigprocmask"); 110 if (kill(getpid(), SIGUSR1) < 0) 111 err(1, "kill"); 112 113 kev.flags = EV_ADD | EV_CLEAR; 114#if LIBKQUEUE 115 kev.data = 1; /* WORKAROUND */ 116#else 117 kev.data = 2; // one extra time from test_kevent_signal_disable() 118#endif 119 kevent_cmp(&kev, kevent_get(kqfd)); 120 121 /* Delete the watch */ 122 kev.flags = EV_DELETE; 123 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 124 err(1, "%s", test_id); 125 126 success(); 127} 128 129void 130test_kevent_signal_del(void) 131{ 132 const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)"; 133 struct kevent kev; 134 135 test_begin(test_id); 136 137 /* Delete the kevent */ 138 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); 139 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 140 err(1, "%s", test_id); 141 142 /* Block SIGUSR1, then send it to ourselves */ 143 sigset_t mask; 144 sigemptyset(&mask); 145 sigaddset(&mask, SIGUSR1); 146 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 147 err(1, "sigprocmask"); 148 if (kill(getpid(), SIGUSR1) < 0) 149 err(1, "kill"); 150 151 test_no_kevents(); 152 success(); 153} 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