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 19 20 static void 21 add_and_delete(void) 22 { 23 const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)"; 24 struct kevent kev; 25 26 test_begin(test_id); 27 28 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); 29 test_no_kevents(); 30 31 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); 32 test_no_kevents(); 33 34 success(); 35 } 36 37 static void 38 event_wait(void) 39 { 40 const char *test_id = "kevent(EVFILT_USER, wait)"; 41 struct kevent kev; 42 43 test_begin(test_id); 44 45 test_no_kevents(); 46 47 /* Add the event, and then trigger it */ 48 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL); 49 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 50 51 kev.fflags &= ~NOTE_FFCTRLMASK; 52 kev.fflags &= ~NOTE_TRIGGER; 53 kev.flags = EV_CLEAR; 54 kevent_cmp(&kev, kevent_get(kqfd)); 55 56 test_no_kevents(); 57 58 success(); 59 } 60 61 static void 62 event_wait_keepudata(void) 63 { 64 const char *test_id = "kevent(EVFILT_USER, wait w/ EV_KEEPUDATA)"; 65 struct kevent kev; 66 67 test_begin(test_id); 68 69 test_no_kevents(); 70 71 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, &kev); 72 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, 73 NULL); 74 75 kev.fflags &= ~NOTE_FFCTRLMASK; 76 kev.fflags &= ~NOTE_TRIGGER; 77 kev.flags = EV_CLEAR; 78 kev.udata = &kev; 79 kevent_cmp(&kev, kevent_get(kqfd)); 80 81 test_no_kevents(); 82 83 success(); 84 } 85 86 87 static void 88 disable_and_enable(void) 89 { 90 const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)"; 91 struct kevent kev; 92 93 test_begin(test_id); 94 95 test_no_kevents(); 96 97 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); 98 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL); 99 100 /* Trigger the event, but since it is disabled, nothing will happen. */ 101 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 102 test_no_kevents(); 103 104 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL); 105 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 106 107 kev.flags = EV_CLEAR; 108 kev.fflags &= ~NOTE_FFCTRLMASK; 109 kev.fflags &= ~NOTE_TRIGGER; 110 kevent_cmp(&kev, kevent_get(kqfd)); 111 112 success(); 113 } 114 115 static void 116 disable_and_enable_keepudata(void) 117 { 118 const char *test_id = 119 "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE w/ EV_KEEPUDATA)"; 120 struct kevent kev; 121 122 test_begin(test_id); 123 124 test_no_kevents(); 125 126 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, &kev); 127 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE | EV_KEEPUDATA, 0, 0, 128 NULL); 129 130 /* Trigger the event, but since it is disabled, nothing will happen. */ 131 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL); 132 test_no_kevents(); 133 134 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE | EV_KEEPUDATA, 0, 0, 135 NULL); 136 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL); 137 138 kev.flags = EV_CLEAR; 139 kev.fflags &= ~NOTE_FFCTRLMASK; 140 kev.fflags &= ~NOTE_TRIGGER; 141 kev.udata = &kev; 142 kevent_cmp(&kev, kevent_get(kqfd)); 143 144 success(); 145 } 146 147 static void 148 oneshot(void) 149 { 150 const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)"; 151 struct kevent kev; 152 153 test_begin(test_id); 154 155 test_no_kevents(); 156 157 kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL); 158 159 puts(" -- event 1"); 160 kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 161 162 kev.flags = EV_ONESHOT; 163 kev.fflags &= ~NOTE_FFCTRLMASK; 164 kev.fflags &= ~NOTE_TRIGGER; 165 kevent_cmp(&kev, kevent_get(kqfd)); 166 167 test_no_kevents(); 168 169 success(); 170 } 171 172 void 173 test_evfilt_user(void) 174 { 175 kqfd = kqueue(); 176 177 add_and_delete(); 178 event_wait(); 179 event_wait_keepudata(); 180 disable_and_enable(); 181 disable_and_enable_keepudata(); 182 oneshot(); 183 /* TODO: try different fflags operations */ 184 185 close(kqfd); 186 } 187