static void disable_and_enable(void) { const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)"; struct kevent kev; test_begin(test_id); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL); /* Trigger the event, but since it is disabled, nothing will happen. */ kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL); kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_CLEAR; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_cmp(&kev, kevent_get(kqfd)); success(); }
void test_kevent_socket_clear(void) { const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)"; struct kevent kev; test_begin(test_id); test_no_kevents(); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kevent_socket_fill(); kevent_socket_fill(); kev.data = 2; kevent_cmp(&kev, kevent_get(kqfd)); /* We filled twice, but drain once. Edge-triggered would not generate additional events. */ kevent_socket_drain(); test_no_kevents(); kevent_socket_drain(); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); success(); }
void test_kevent_socket_lowat(void) { const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)"; struct kevent kev; test_begin(test_id); /* Re-add the watch and make sure no events are pending */ puts("-- re-adding knote, setting low watermark to 2 bytes"); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); test_no_kevents(); puts("-- checking that one byte does not trigger an event.."); kevent_socket_fill(); test_no_kevents(); puts("-- checking that two bytes triggers an event.."); kevent_socket_fill(); if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1) err(1, "%s", test_id); KEV_CMP(kev, sockfd[0], EVFILT_READ, 0); test_no_kevents(); kevent_socket_drain(); kevent_socket_drain(); success(); }
void test_kevent_socket_dispatch(void) { const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)"; test_begin(test_id); struct kevent kev; /* Re-add the watch and make sure no events are pending */ puts("-- re-adding knote"); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); test_no_kevents(); /* The event will occur only once, even though EV_CLEAR is not specified. */ kevent_socket_fill(); kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); test_no_kevents(); /* Since the knote is disabled, the EV_DELETE operation succeeds. */ EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kevent_socket_drain(); success(); }
void test_kqueue_descriptor_is_pollable(void) { int kq, rv; struct kevent kev; fd_set fds; struct timeval tv; if ((kq = kqueue()) < 0) die("kqueue()"); test_no_kevents(kq); kevent_add(kq, &kev, 2, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 1000, NULL); test_no_kevents(kq); FD_ZERO(&fds); FD_SET(kq, &fds); tv.tv_sec = 5; tv.tv_usec = 0; rv = select(1, &fds, NULL, NULL, &tv); if (rv < 0) die("select() error"); if (rv == 0) die("select() no events"); if (!FD_ISSET(kq, &fds)) { die("descriptor is not ready for reading"); } close(kq); }
void test_kevent_socket_lowat(struct test_context *ctx) { struct kevent kev; test_begin(test_id); /* Re-add the watch and make sure no events are pending */ puts("-- re-adding knote, setting low watermark to 2 bytes"); EV_SET(&kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &ctx->client_fd); if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("%s", test_id); test_no_kevents(); puts("-- checking that one byte does not trigger an event.."); kevent_socket_fill(ctx); test_no_kevents(); puts("-- checking that two bytes triggers an event.."); kevent_socket_fill(ctx); if (kevent(ctx->kqfd, NULL, 0, &kev, 1, NULL) != 1) die("%s", test_id); KEV_CMP(kev, ctx->client_fd, EVFILT_READ, 0); test_no_kevents(); kevent_socket_drain(ctx); kevent_socket_drain(ctx); }
void test_kevent_timer_dispatch(void) { struct kevent kev; test_no_kevents(kqfd); kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ADD | EV_DISPATCH, 0, 800, NULL); /* Get one event */ kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Confirm that the knote is disabled */ sleep(1); test_no_kevents(kqfd); /* Enable the knote and make sure no events are pending */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ENABLE | EV_DISPATCH, 0, 800, NULL); test_no_kevents(kqfd); /* Get the next event */ sleep(1); kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Remove the knote and ensure the event no longer fires */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); sleep(1); test_no_kevents(kqfd); }
void test_kevent_socket_oneshot(void) { const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)"; struct kevent kev; test_begin(test_id); /* Re-add the watch and make sure no events are pending */ puts("-- re-adding knote"); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); test_no_kevents(); puts("-- getting one event"); kevent_socket_fill(); kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); puts("-- checking knote disabled"); test_no_kevents(); /* Try to delete the knote, it should already be deleted */ EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0) err(1, "%s", test_id); kevent_socket_drain(); success(); }
void test_kevent_socket_dispatch(struct test_context *ctx) { struct kevent kev, ret; /* Re-add the watch and make sure no events are pending */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &ctx->client_fd); test_no_kevents(ctx->kqfd); /* The event will occur only once, even though EV_CLEAR is not specified. */ kevent_socket_fill(ctx); kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Re-enable the kevent */ /* FIXME- is EV_DISPATCH needed when rearming ? */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ENABLE | EV_DISPATCH, 0, 0, &ctx->client_fd); kev.data = 1; kev.flags = EV_ADD | EV_DISPATCH; /* FIXME: may not be portable */ kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Since the knote is disabled, the EV_DELETE operation succeeds. */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_DELETE, 0, 0, &ctx->client_fd); kevent_socket_drain(ctx); }
void test_kevent_socket_oneshot(struct test_context *ctx) { struct kevent kev, ret; /* Re-add the watch and make sure no events are pending */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &ctx->client_fd); test_no_kevents(ctx->kqfd); kevent_socket_fill(ctx); kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Verify that the kernel watch has been deleted */ kevent_socket_fill(ctx); test_no_kevents(ctx->kqfd); kevent_socket_drain(ctx); /* Verify that the kevent structure does not exist. */ kev.flags = EV_DELETE; if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) == 0) die("kevent() should have failed"); }
void test_kevent_socket_clear(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); kevent_socket_drain(ctx); EV_SET(&kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &ctx->client_fd); if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent1"); kevent_socket_fill(ctx); kevent_socket_fill(ctx); /* Solaris does not offer a way to get the amount of data pending */ #if defined(__sun__) kev.data = 1; #else kev.data = 2; #endif kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); /* We filled twice, but drain once. Edge-triggered would not generate additional events. */ kevent_socket_drain(ctx); test_no_kevents(ctx->kqfd); kevent_socket_drain(ctx); EV_SET(&kev, ctx->client_fd, EVFILT_READ, EV_DELETE, 0, 0, &ctx->client_fd); if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent2"); }
static void event_trigger(void) { struct kevent kev; pid_t pid; test_begin("kevent(EVFILT_PROC, wait)"); /* Create a child that waits to be killed and then exits */ pid = fork(); if (pid == 0) { pause(); printf(" -- child caught signal, exiting\n"); exit(2); } printf(" -- child created (pid %d)\n", (int) pid); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL); /* Cause the child to exit, then retrieve the event */ printf(" -- killing process %d\n", (int) pid); if (kill(pid, SIGUSR1) < 0) err(1, "kill"); kevent_cmp(&kev, kevent_get(kqfd)); test_no_kevents(); success(); }
static void test_kevent_user_add_and_delete(struct test_context *ctx) { struct kevent kev; kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); test_no_kevents(ctx->kqfd); }
void test_kevent_signal_del(void) { const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)"; struct kevent kev; test_begin(test_id); /* Delete the kevent */ EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); /* Block SIGUSR1, then send it to ourselves */ sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGUSR1); if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) err(1, "sigprocmask"); if (kill(getpid(), SIGUSR1) < 0) err(1, "kill"); test_no_kevents(); success(); }
void test_kevent_socket_eof(void) { const char *test_id = "kevent(EVFILT_READ, EV_EOF)"; struct kevent kev; test_begin(test_id); /* Re-add the watch and make sure no events are pending */ EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); test_no_kevents(); if (close(sockfd[1]) < 0) err(1, "close(2)"); kev.flags |= EV_EOF; kevent_cmp(&kev, kevent_get(kqfd)); /* Delete the watch */ EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); success(); }
static void add_and_delete(void) { const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)"; struct kevent kev; test_begin(test_id); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); test_no_kevents(); success(); }
void test_kevent_socket_disable_and_enable(struct test_context *ctx) { struct kevent kev, ret; /* Add an event, then disable it. */ EV_SET(&kev, ctx->client_fd, EVFILT_READ, EV_ADD, 0, 0, &ctx->client_fd); if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent"); EV_SET(&kev, ctx->client_fd, EVFILT_READ, EV_DISABLE, 0, 0, &ctx->client_fd); if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent"); kevent_socket_fill(ctx); test_no_kevents(ctx->kqfd); /* Re-enable the knote, then see if an event is generated */ kev.flags = EV_ENABLE; if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent"); kev.flags = EV_ADD; kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); kevent_socket_drain(ctx); kev.flags = EV_DELETE; if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) < 0) die("kevent"); }
void test_kevent_signal_oneshot(void) { const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)"; struct kevent kev; test_begin(test_id); EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); /* Block SIGUSR1, then send it to ourselves */ sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGUSR1); if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) err(1, "sigprocmask"); if (kill(getpid(), SIGUSR1) < 0) err(1, "kill"); kev.flags |= EV_CLEAR; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Send another one and make sure we get no events */ if (kill(getpid(), SIGUSR1) < 0) err(1, "kill"); test_no_kevents(); success(); }
void test_kevent_socket_disable_and_enable(void) { const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)"; struct kevent kev; test_begin(test_id); /* Add an event, then disable it. */ EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DISABLE, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kevent_socket_fill(); test_no_kevents(); /* Re-enable the knote, then see if an event is generated */ kev.flags = EV_ENABLE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kev.flags = EV_ADD; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); kevent_socket_drain(); kev.flags = EV_DELETE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); success(); }
void test_kevent_socket_get(void) { const char *test_id = "kevent(EVFILT_READ) wait"; struct kevent kev; test_begin(test_id); EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kevent_socket_fill(); kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); kevent_socket_drain(); test_no_kevents(); kev.flags = EV_DELETE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); success(); }
/* * Test if the data field returns 1 when a listen(2) socket has * a pending connection. */ void test_kevent_socket_listen_backlog(struct test_context *ctx) { struct kevent kev, ret; struct sockaddr_in sain; socklen_t sa_len = sizeof(sain); int one = 1; short port; int clnt, srvr; port = 14973 + ctx->iteration; /* Create a passive socket */ memset(&sain, 0, sizeof(sain)); sain.sin_family = AF_INET; sain.sin_port = htons(port); if ((srvr = socket(PF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket()"); if (setsockopt(srvr, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) != 0) err(1, "setsockopt()"); if (bind(srvr, (struct sockaddr *) &sain, sa_len) < 0) err(1, "bind-2", port); if (listen(srvr, 100) < 0) err(1, "listen()"); /* Watch for events on the socket */ test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, srvr, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL); test_no_kevents(ctx->kqfd); /* Simulate a client connecting to the server */ sain.sin_family = AF_INET; sain.sin_port = htons(port); sain.sin_addr.s_addr = inet_addr("127.0.0.1"); if ((clnt = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket()"); if (connect(clnt, (struct sockaddr *) &sain, sa_len) < 0) err(1, "connect()"); /* Verify that data=1 */ kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
void test_kevent_timer_del(void) { struct kevent kev; kevent_add(kqfd, &kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); test_no_kevents(kqfd); }
static void test_kevent_timer_oneshot(void) { struct kevent kev; test_no_kevents(kqfd); kevent_add(kqfd, &kev, 2, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500,NULL); /* Retrieve the event */ kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Check if the event occurs again */ sleep(3); test_no_kevents(kqfd); }
void test_kqueue(void) { test_begin("kqueue()"); if ((kqfd = kqueue()) < 0) err(1, "kqueue()"); test_no_kevents(); success(); }
static void test_kevent_user_get_hires(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); /* Add the event, and then trigger it */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kev.flags = EV_CLEAR; kevent_get(&ret, ctx->kqfd); //FIXME: Shouldn't this be kevent_get_hires() ? kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
static void test_kevent_user_oneshot(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL); puts(" -- event 1"); kevent_add(ctx->kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_ONESHOT; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
void test_kevent_vnode_disable_and_enable(void) { const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)"; struct kevent kev; int nfds; test_begin(test_id); test_no_kevents(); /* Add the watch and immediately disable it */ EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); kev.flags = EV_DISABLE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); /* Confirm that the watch is disabled */ if (system("touch /tmp/kqueue-test.tmp") < 0) err(1, "system"); test_no_kevents(); /* Re-enable and check again */ kev.flags = EV_ENABLE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); if (system("touch /tmp/kqueue-test.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); if (nfds < 1) err(1, "%s", test_id); if (kev.ident != vnode_fd || kev.filter != EVFILT_VNODE || kev.fflags != NOTE_ATTRIB) err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)", test_id, (unsigned int)kev.ident, kev.filter, kev.flags); success(); }
static void test_kevent_timer_disable_and_enable(void) { struct kevent kev; test_no_kevents(kqfd); /* Add the watch and immediately disable it */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 2000,NULL); kev.flags = EV_DISABLE; kevent_update(kqfd, &kev); test_no_kevents(kqfd); /* Re-enable and check again */ kev.flags = EV_ENABLE; kevent_update(kqfd, &kev); kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); }
void test_kevent_vnode_dispatch(void) { const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)"; struct kevent kev; int nfds; test_begin(test_id); test_no_kevents(); EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); if (system("touch /tmp/kqueue-test.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); if (nfds < 1) err(1, "%s", test_id); if (kev.ident != vnode_fd || kev.filter != EVFILT_VNODE || kev.fflags != NOTE_ATTRIB) err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)", test_id, (unsigned int)kev.ident, kev.filter, kev.flags); /* Confirm that the watch is disabled automatically */ puts("-- checking that watch is disabled"); if (system("touch /tmp/kqueue-test.tmp") < 0) err(1, "system"); test_no_kevents(); /* Delete the watch */ EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL); if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "remove watch failed: %s", test_id); success(); }
static void add_and_delete(void) { struct kevent kev; pid_t pid; /* Create a child that waits to be killed and then exits */ pid = fork(); if (pid == 0) { struct stat s; if (fstat(kqfd, &s) != -1) errx(1, "kqueue inherited across fork! (%s() at %s:%d)", __func__, __FILE__, __LINE__); pause(); exit(2); } printf(" -- child created (pid %d)\n", (int) pid); test_begin("kevent(EVFILT_PROC, EV_ADD)"); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL); test_no_kevents(); success(); test_begin("kevent(EVFILT_PROC, EV_DELETE)"); sleep(1); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_DELETE, 0, 0, NULL); if (kill(pid, SIGKILL) < 0) err(1, "kill"); sleep(1); test_no_kevents(); success(); }