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 int kqfd; 22 23 void 24 test_kevent_signal_add(void) 25 { 26 const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)"; 27 struct kevent kev; 28 29 test_begin(test_id); 30 31 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 32 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 33 err(1, "%s", test_id); 34 35 success(); 36 } 37 38 void 39 test_kevent_signal_get(void) 40 { 41 const char *test_id = "kevent(EVFILT_SIGNAL, wait)"; 42 struct kevent kev; 43 44 test_begin(test_id); 45 46 EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 47 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 48 err(1, "%s", test_id); 49 50 /* Block SIGUSR1, then send it to ourselves */ 51 sigset_t mask; 52 sigemptyset(&mask); 53 sigaddset(&mask, SIGUSR1); 54 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) 55 err(1, "sigprocmask"); 56 if (kill(getpid(), SIGUSR1) < 0) 57 err(1, "kill"); 58 59 kev.flags |= EV_CLEAR; 60 kev.data = 1; 61 kevent_cmp(&kev, kevent_get(kqfd)); 62 63 success(); 64 } 65 66 void 67 test_kevent_signal_disable(void) 68 { 69 const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)"; 70 struct kevent kev; 71 72 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 92 void 93 test_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 129 void 130 test_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 155 void 156 test_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 188 void 189 test_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