2 * Copyright (c) 2009 Mark Heily <mark@heily.com>
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.
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.
22 test_kevent_vnode_add(void)
24 const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)";
25 const char *testfile = "./kqueue-test.tmp";
30 system("touch ./kqueue-test.tmp");
31 vnode_fd = open(testfile, O_RDONLY);
33 err(1, "open of %s", testfile);
35 printf("vnode_fd = %d\n", vnode_fd);
37 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD,
38 NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME | NOTE_DELETE, 0, NULL);
39 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
40 err(1, "%s", test_id);
46 test_kevent_vnode_note_delete(void)
48 const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE)";
53 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);
54 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
55 err(1, "%s", test_id);
57 if (unlink("./kqueue-test.tmp") < 0)
60 kevent_cmp(&kev, kevent_get(kqfd));
66 test_kevent_vnode_note_delete_fifo(void)
68 const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE, FIFO)";
69 const char *fifo_path = "./kqueue-fifo.tmp";
76 if (mkfifo(fifo_path, 0600) != 0)
86 fd = open(fifo_path, O_RDONLY);
90 while (read(fd, buf, sizeof(buf)) != 0) {
97 if (waitpid(pid, NULL, WNOHANG) == pid) {
102 fd = open(fifo_path, O_WRONLY);
108 EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);
109 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) {
111 err(1, "%s", test_id);
114 if (unlink(fifo_path) < 0)
117 kevent_cmp(&kev, kevent_get(kqfd));
124 test_kevent_vnode_note_write(void)
126 const char *test_id = "kevent(EVFILT_VNODE, NOTE_WRITE)";
131 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_WRITE, 0, NULL);
132 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
133 err(1, "%s", test_id);
135 if (system("echo hello >> ./kqueue-test.tmp") < 0)
138 /* BSD kqueue adds NOTE_EXTEND even though it was not requested */
139 /* BSD kqueue removes EV_ENABLE */
140 kev.flags &= ~EV_ENABLE; // XXX-FIXME compatibility issue
141 kev.fflags |= NOTE_EXTEND; // XXX-FIXME compatibility issue
142 kevent_cmp(&kev, kevent_get(kqfd));
148 test_kevent_vnode_note_attrib(void)
150 const char *test_id = "kevent(EVFILT_VNODE, NOTE_ATTRIB)";
156 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
157 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
158 err(1, "%s", test_id);
160 if (system("touch ./kqueue-test.tmp") < 0)
163 nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
165 err(1, "%s", test_id);
166 if (kev.ident != (uintptr_t)vnode_fd ||
167 kev.filter != EVFILT_VNODE ||
168 kev.fflags != NOTE_ATTRIB)
169 err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
170 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
176 test_kevent_vnode_note_rename(void)
178 const char *test_id = "kevent(EVFILT_VNODE, NOTE_RENAME)";
184 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_RENAME, 0, NULL);
185 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
186 err(1, "%s", test_id);
188 if (system("mv ./kqueue-test.tmp ./kqueue-test2.tmp") < 0)
191 nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
193 err(1, "%s", test_id);
194 if (kev.ident != (uintptr_t)vnode_fd ||
195 kev.filter != EVFILT_VNODE ||
196 kev.fflags != NOTE_RENAME)
197 err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
198 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
200 if (system("mv ./kqueue-test2.tmp ./kqueue-test.tmp") < 0)
207 test_kevent_vnode_del(void)
209 const char *test_id = "kevent(EVFILT_VNODE, EV_DELETE)";
214 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
215 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
216 err(1, "%s", test_id);
222 test_kevent_vnode_disable_and_enable(void)
224 const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)";
232 /* Add the watch and immediately disable it */
233 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
234 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
235 err(1, "%s", test_id);
236 kev.flags = EV_DISABLE;
237 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
238 err(1, "%s", test_id);
240 /* Confirm that the watch is disabled */
241 if (system("touch ./kqueue-test.tmp") < 0)
245 /* Re-enable and check again */
246 kev.flags = EV_ENABLE;
247 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
248 err(1, "%s", test_id);
249 if (system("touch ./kqueue-test.tmp") < 0)
251 nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
253 err(1, "%s", test_id);
254 if (kev.ident != (uintptr_t)vnode_fd ||
255 kev.filter != EVFILT_VNODE ||
256 kev.fflags != NOTE_ATTRIB)
257 err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
258 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
265 test_kevent_vnode_dispatch(void)
267 const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)";
275 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL);
276 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
277 err(1, "%s", test_id);
279 if (system("touch ./kqueue-test.tmp") < 0)
282 nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
284 err(1, "%s", test_id);
285 if (kev.ident != (uintptr_t)vnode_fd ||
286 kev.filter != EVFILT_VNODE ||
287 kev.fflags != NOTE_ATTRIB)
288 err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
289 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
291 /* Confirm that the watch is disabled automatically */
292 puts("-- checking that watch is disabled");
293 if (system("touch ./kqueue-test.tmp") < 0)
297 /* Delete the watch */
298 EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL);
299 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
300 err(1, "remove watch failed: %s", test_id);
304 #endif /* HAVE_EV_DISPATCH */
307 test_evfilt_vnode(void)
310 test_kevent_vnode_add();
311 test_kevent_vnode_del();
312 test_kevent_vnode_disable_and_enable();
314 test_kevent_vnode_dispatch();
316 test_kevent_vnode_note_write();
317 test_kevent_vnode_note_attrib();
318 test_kevent_vnode_note_rename();
319 test_kevent_vnode_note_delete();
320 test_kevent_vnode_note_delete_fifo();