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 "common.h" 20 21 22 static void 23 test_kevent_signal_add(void) 24 { 25 const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)"; 26 struct kevent kev; 27 28 test_begin(test_id); 29 30 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 31 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 32 err(1, "%s", test_id); 33 34 success(); 35 } 36 37 static void 38 test_kevent_signal_get(void) 39 { 40 const char *test_id = "kevent(EVFILT_SIGNAL, wait)"; 41 struct kevent kev; 42 43 test_begin(test_id); 44 45 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 46 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 47 err(1, "%s", test_id); 48 49 /* Block SIGUSR1, then send it to ourselves */ 50 sigset_t mask; 51 sigemptyset(&mask); 52 sigaddset(&mask, SIGUSR1); 53 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 54 err(1, "sigprocmask"); 55 if (kill(getpid(), SIGUSR1) < 0) 56 err(1, "kill"); 57 58 kev.flags |= EV_CLEAR; 59 kev.data = 1; 60 kevent_cmp(&kev, kevent_get(kqfd)); 61 62 success(); 63 } 64 65 static void 66 test_kevent_signal_disable(void) 67 { 68 const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)"; 69 struct kevent kev; 70 71 test_begin(test_id); 72 73 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL); 74 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 75 err(1, "%s", test_id); 76 77 /* Block SIGUSR1, then send it to ourselves */ 78 sigset_t mask; 79 sigemptyset(&mask); 80 sigaddset(&mask, SIGUSR1); 81 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 82 err(1, "sigprocmask"); 83 if (kill(getpid(), SIGUSR1) < 0) 84 err(1, "kill"); 85 86 test_no_kevents(); 87 88 success(); 89 } 90 91 static void 92 test_kevent_signal_enable(void) 93 { 94 const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)"; 95 struct kevent kev; 96 97 test_begin(test_id); 98 99 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL); 100 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 101 err(1, "%s", test_id); 102 103 /* Block SIGUSR1, then send it to ourselves */ 104 sigset_t mask; 105 sigemptyset(&mask); 106 sigaddset(&mask, SIGUSR1); 107 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 108 err(1, "sigprocmask"); 109 if (kill(getpid(), SIGUSR1) < 0) 110 err(1, "kill"); 111 112 kev.flags = EV_ADD | EV_CLEAR; 113 #if LIBKQUEUE 114 kev.data = 1; /* WORKAROUND */ 115 #else 116 kev.data = 2; // one extra time from test_kevent_signal_disable() 117 #endif 118 kevent_cmp(&kev, kevent_get(kqfd)); 119 120 /* Delete the watch */ 121 kev.flags = EV_DELETE; 122 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 123 err(1, "%s", test_id); 124 125 success(); 126 } 127 128 static void 129 test_kevent_signal_del(void) 130 { 131 const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)"; 132 struct kevent kev; 133 134 test_begin(test_id); 135 136 /* Delete the kevent */ 137 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); 138 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 139 err(1, "%s", test_id); 140 141 /* Block SIGUSR1, then send it to ourselves */ 142 sigset_t mask; 143 sigemptyset(&mask); 144 sigaddset(&mask, SIGUSR1); 145 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 146 err(1, "sigprocmask"); 147 if (kill(getpid(), SIGUSR1) < 0) 148 err(1, "kill"); 149 150 test_no_kevents(); 151 success(); 152 } 153 154 static void 155 test_kevent_signal_oneshot(void) 156 { 157 const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)"; 158 struct kevent kev; 159 160 test_begin(test_id); 161 162 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL); 163 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 164 err(1, "%s", test_id); 165 166 /* Block SIGUSR1, then send it to ourselves */ 167 sigset_t mask; 168 sigemptyset(&mask); 169 sigaddset(&mask, SIGUSR1); 170 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 171 err(1, "sigprocmask"); 172 if (kill(getpid(), SIGUSR1) < 0) 173 err(1, "kill"); 174 175 kev.flags |= EV_CLEAR; 176 kev.data = 1; 177 kevent_cmp(&kev, kevent_get(kqfd)); 178 179 /* Send another one and make sure we get no events */ 180 if (kill(getpid(), SIGUSR1) < 0) 181 err(1, "kill"); 182 test_no_kevents(); 183 184 success(); 185 } 186 187 void 188 test_evfilt_signal(void) 189 { 190 kqfd = kqueue(); 191 test_kevent_signal_add(); 192 test_kevent_signal_del(); 193 test_kevent_signal_get(); 194 test_kevent_signal_disable(); 195 test_kevent_signal_enable(); 196 test_kevent_signal_oneshot(); 197 close(kqfd); 198 } 199