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.
19 #include <sys/types.h>
25 char *cur_test_id = NULL;
28 extern void test_evfilt_read();
29 extern void test_evfilt_signal();
30 extern void test_evfilt_vnode();
31 extern void test_evfilt_timer();
32 extern void test_evfilt_proc();
34 extern void test_evfilt_user();
37 /* Checks if any events are pending, which is an error. */
42 struct timespec timeo;
45 puts("confirming that there are no events pending");
46 memset(&timeo, 0, sizeof(timeo));
47 nfds = kevent(kqfd, NULL, 0, &kev, 1, &timeo);
49 puts("\nUnexpected event:");
50 puts(kevent_to_str(&kev));
51 errx(1, "%d event(s) pending, but none expected:", nfds);
55 /* Checks if any events are pending, which is an error. Do not print
56 * out anything unless events are found.
59 test_no_kevents_quietly(void)
62 struct timespec timeo;
65 memset(&timeo, 0, sizeof(timeo));
66 nfds = kevent(kqfd, NULL, 0, &kev, 1, &timeo);
68 puts("\nUnexpected event:");
69 puts(kevent_to_str(&kev));
70 errx(1, "%d event(s) pending, but none expected:", nfds);
74 /* Retrieve a single kevent */
81 if ((kev = calloc(1, sizeof(*kev))) == NULL)
82 err(1, "out of memory");
84 nfds = kevent(kqfd, NULL, 0, kev, 1, NULL);
91 /* Retrieve a single kevent, specifying a maximum time to wait for it. */
93 kevent_get_timeout(int kqfd, int seconds)
97 struct timespec timeout = {seconds, 0};
99 if ((kev = calloc(1, sizeof(*kev))) == NULL)
100 err(1, "out of memory");
102 nfds = kevent(kqfd, NULL, 0, kev, 1, &timeout);
105 } else if (nfds == 0) {
114 kevent_fflags_dump(struct kevent *kev)
118 #define KEVFFL_DUMP(attrib) \
119 if (kev->fflags & attrib) \
120 strncat(buf, #attrib" ", 64);
122 if ((buf = calloc(1, 1024)) == NULL)
125 /* Not every filter has meaningful fflags */
126 if (kev->filter == EVFILT_PROC) {
127 snprintf(buf, 1024, "fflags = %x (", kev->fflags);
128 KEVFFL_DUMP(NOTE_EXIT);
129 KEVFFL_DUMP(NOTE_FORK);
130 KEVFFL_DUMP(NOTE_EXEC);
131 KEVFFL_DUMP(NOTE_CHILD);
132 KEVFFL_DUMP(NOTE_TRACKERR);
133 KEVFFL_DUMP(NOTE_TRACK);
134 buf[strlen(buf) - 1] = ')';
135 } else if (kev->filter == EVFILT_PROCDESC) {
136 snprintf(buf, 1024, "fflags = %x (", kev->fflags);
137 KEVFFL_DUMP(NOTE_EXIT);
138 KEVFFL_DUMP(NOTE_FORK);
139 KEVFFL_DUMP(NOTE_EXEC);
140 buf[strlen(buf) - 1] = ')';
141 } else if (kev->filter == EVFILT_VNODE) {
142 snprintf(buf, 1024, "fflags = %x (", kev->fflags);
143 KEVFFL_DUMP(NOTE_DELETE);
144 KEVFFL_DUMP(NOTE_WRITE);
145 KEVFFL_DUMP(NOTE_EXTEND);
146 #if HAVE_NOTE_TRUNCATE
147 KEVFFL_DUMP(NOTE_TRUNCATE);
149 KEVFFL_DUMP(NOTE_ATTRIB);
150 KEVFFL_DUMP(NOTE_LINK);
151 KEVFFL_DUMP(NOTE_RENAME);
153 KEVFFL_DUMP(NOTE_REVOKE);
155 buf[strlen(buf) - 1] = ')';
157 snprintf(buf, 1024, "fflags = %x", kev->fflags);
164 kevent_flags_dump(struct kevent *kev)
168 #define KEVFL_DUMP(attrib) \
169 if (kev->flags & attrib) \
170 strncat(buf, #attrib" ", 64);
172 if ((buf = calloc(1, 1024)) == NULL)
175 snprintf(buf, 1024, "flags = %d (", kev->flags);
177 KEVFL_DUMP(EV_ENABLE);
178 KEVFL_DUMP(EV_DISABLE);
179 KEVFL_DUMP(EV_DELETE);
180 KEVFL_DUMP(EV_ONESHOT);
181 KEVFL_DUMP(EV_CLEAR);
183 KEVFL_DUMP(EV_ERROR);
185 KEVFL_DUMP(EV_DISPATCH);
188 KEVFL_DUMP(EV_RECEIPT);
190 buf[strlen(buf) - 1] = ')';
195 /* Copied from ../kevent.c kevent_dump() and improved */
197 kevent_to_str(struct kevent *kev)
201 snprintf(&buf[0], sizeof(buf),
202 "[ident=%d, filter=%d, %s, %s, data=%d, udata=%p]",
205 kevent_flags_dump(kev),
206 kevent_fflags_dump(kev),
210 return (strdup(buf));
214 kevent_add(int kqfd, struct kevent *kev,
222 EV_SET(kev, ident, filter, flags, fflags, data, NULL);
223 if (kevent(kqfd, kev, 1, NULL, 0, NULL) < 0) {
224 printf("Unable to add the following kevent:\n%s\n",
226 err(1, "kevent(): %s", strerror(errno));
231 kevent_cmp(struct kevent *k1, struct kevent *k2)
234 Workaround for inconsistent implementation of kevent(2)
237 if (k1->flags & EV_ADD)
240 if (memcmp(k1, k2, sizeof(*k1)) != 0) {
241 printf("kevent_cmp: mismatch:\n %s !=\n %s\n",
242 kevent_to_str(k1), kevent_to_str(k2));
248 test_begin(const char *func)
252 cur_test_id = strdup(func);
254 err(1, "strdup failed");
256 printf("\n\nTest %d: %s\n", testnum++, func);
262 printf("%-70s %s\n", cur_test_id, "passed");
270 test_begin("kqueue()");
271 if ((kqfd = kqueue()) < 0)
278 test_kqueue_close(void)
280 test_begin("close(kq)");
287 main(int argc, char **argv)
297 /* XXX-FIXME temporary */
302 if (strcmp(argv[0], "--no-proc") == 0)
304 if (strcmp(argv[0], "--no-socket") == 0)
306 if (strcmp(argv[0], "--no-timer") == 0)
308 if (strcmp(argv[0], "--no-signal") == 0)
310 if (strcmp(argv[0], "--no-vnode") == 0)
312 if (strcmp(argv[0], "--no-user") == 0)
319 * Some tests fork. If output is fully buffered,
320 * the children inherit some buffered data and flush
321 * it when they exit, causing some data to be printed twice.
322 * Use line buffering to avoid this problem.
333 test_evfilt_signal();
346 "+OK All %d tests completed.\n", testnum - 1);