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 17#include "common.h" 18 19static int __thread kqfd; 20 21void 22test_kevent_signal_add(void) 23{ 24 struct kevent kev; 25 26 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 27} 28 29void 30test_kevent_signal_get(void) 31{ 32 struct kevent kev; 33 34 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 35 36 if (kill(getpid(), SIGUSR1) < 0) 37 die("kill"); 38 39 kev.flags |= EV_CLEAR; 40 kev.data = 1; 41 kevent_cmp(&kev, kevent_get(kqfd)); 42} 43 44void 45test_kevent_signal_disable(void) 46{ 47 struct kevent kev; 48 49 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL); 50 51 if (kill(getpid(), SIGUSR1) < 0) 52 die("kill"); 53 54 test_no_kevents(kqfd); 55} 56 57void 58test_kevent_signal_enable(void) 59{ 60 struct kevent kev; 61 62 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL); 63 64 if (kill(getpid(), SIGUSR1) < 0) 65 die("kill"); 66 67 kev.flags = EV_ADD | EV_CLEAR; 68#if LIBKQUEUE 69 kev.data = 1; /* WORKAROUND */ 70#else 71 kev.data = 2; // one extra time from test_kevent_signal_disable() 72#endif 73 kevent_cmp(&kev, kevent_get(kqfd)); 74 75 /* Delete the watch */ 76 kev.flags = EV_DELETE; 77 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 78 die("kevent"); 79} 80 81void 82test_kevent_signal_del(void) 83{ 84 struct kevent kev; 85 86 /* Delete the kevent */ 87 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); 88 89 signal(SIGUSR1, SIG_IGN); 90 if (kill(getpid(), SIGUSR1) < 0) 91 die("kill"); 92 93 test_no_kevents(kqfd); 94} 95 96void 97test_kevent_signal_oneshot(void) 98{ 99 struct kevent kev; 100 101 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL); 102 103 if (kill(getpid(), SIGUSR1) < 0) 104 die("kill"); 105 106 kev.flags |= EV_CLEAR; 107 kev.data = 1; 108 kevent_cmp(&kev, kevent_get(kqfd)); 109 110 /* Send another one and make sure we get no events */ 111 test_no_kevents(kqfd); 112 if (kill(getpid(), SIGUSR1) < 0) 113 die("kill"); 114 test_no_kevents(kqfd); 115} 116 117void 118test_kevent_signal_modify(void) 119{ 120 struct kevent kev; 121 122 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 123 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, ((void *)-1)); 124 125 if (kill(getpid(), SIGUSR1) < 0) 126 die("kill"); 127 128 kev.flags |= EV_CLEAR; 129 kev.data = 1; 130 kevent_cmp(&kev, kevent_get(kqfd)); 131} 132 133#if HAVE_EV_DISPATCH 134void 135test_kevent_signal_dispatch(void) 136{ 137 struct kevent kev; 138 139 test_no_kevents(kqfd); 140 141 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_CLEAR | EV_DISPATCH, 0, 0, NULL); 142 143 /* Get one event */ 144 if (kill(getpid(), SIGUSR1) < 0) 145 die("kill"); 146 kev.data = 1; 147 kevent_cmp(&kev, kevent_get(kqfd)); 148 149 /* Confirm that the knote is disabled */ 150 if (kill(getpid(), SIGUSR1) < 0) 151 die("kill"); 152 test_no_kevents(kqfd); 153 154 /* Enable the knote and make sure no events are pending */ 155 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE | EV_DISPATCH, 0, 0, NULL); 156 test_no_kevents(kqfd); 157 158 /* Get the next event */ 159 if (kill(getpid(), SIGUSR1) < 0) 160 die("kill"); 161 kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; 162 kev.data = 1; 163 kevent_cmp(&kev, kevent_get(kqfd)); 164 165 /* Remove the knote and ensure the event no longer fires */ 166 kevent_add(kqfd, &kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); 167 if (kill(getpid(), SIGUSR1) < 0) 168 die("kill"); 169 test_no_kevents(kqfd); 170} 171#endif /* HAVE_EV_DISPATCH */ 172 173void 174test_evfilt_signal(int _kqfd) 175{ 176 signal(SIGUSR1, SIG_IGN); 177 178 kqfd = _kqfd; 179 test(kevent_signal_add); 180 test(kevent_signal_del); 181 test(kevent_signal_get); 182 test(kevent_signal_disable); 183 test(kevent_signal_enable); 184 test(kevent_signal_oneshot); 185 test(kevent_signal_modify); 186#if HAVE_EV_DISPATCH 187 test(kevent_signal_dispatch); 188#endif 189} 190