Page MenuHomeFreeBSD

D56223.id174807.diff
No OneTemporary

D56223.id174807.diff

diff --git a/tests/sys/kqueue/kqueue_fork.c b/tests/sys/kqueue/kqueue_fork.c
--- a/tests/sys/kqueue/kqueue_fork.c
+++ b/tests/sys/kqueue/kqueue_fork.c
@@ -27,9 +27,13 @@
*/
#include <sys/event.h>
+#include <sys/procdesc.h>
+#include <sys/stat.h>
+#include <sys/user.h>
#include <sys/wait.h>
#include <err.h>
+#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
@@ -81,9 +85,94 @@
ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
}
+ATF_TC_WITHOUT_HEAD(cponfork_notes);
+ATF_TC_BODY(cponfork_notes, tc)
+{
+ struct kevent ev;
+ int error, dfd, kq, pdfd, status;
+ pid_t pid;
+
+ kq = kqueuex(KQUEUE_CPONFORK);
+ ATF_REQUIRE(kq >= 0);
+
+ dfd = open(".", O_DIRECTORY);
+ ATF_REQUIRE(dfd >= 0);
+
+ /*
+ * Every event we setup here we should expect to observe in the child,
+ * though maybe we can find a use for some sort of negative tests in the
+ * future.
+ */
+ EV_SET(&ev, dfd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+ NOTE_WRITE, 0, NULL);
+ error = kevent(kq, &ev, 1, NULL, 0, NULL);
+
+ EV_SET(&ev, 0, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT,
+ NOTE_SECONDS, 3, NULL);
+ error = kevent(kq, &ev, 1, NULL, 0, NULL);
+ ATF_REQUIRE(error != -1);
+
+ /*
+ * We're only using pdfork here for the kill-on-exit semantics, in case
+ * the parent fails to setup some context needed for one of our events
+ * to fire.
+ */
+ pid = pdfork(&pdfd, 0);
+ ATF_REQUIRE(pid != -1);
+ if (pid == 0) {
+ struct kinfo_file kf = {};
+ struct timespec ts = { .tv_sec = 3 };
+ int received = 0;
+#define RECV_TIMER 0x01
+#define RECV_VNODE 0x02
+#define RECV_ERROR 0x80
+#define RECV_ALL (RECV_TIMER | RECV_VNODE)
+
+ kf.kf_structsize = sizeof(kf);
+ if (fcntl(kq, F_KINFO, &kf) != 0)
+ err(RECV_ERROR, "fcntl");
+ else if (kf.kf_type != KF_TYPE_KQUEUE)
+ err(RECV_ERROR, "Not a kqueue");
+
+ while (received != RECV_ALL) {
+ error = kevent(kq, NULL, 0, &ev, 1, &ts);
+ if (error < 0)
+ err(RECV_ERROR, "kevent");
+ else if (error == 0)
+ break;
+
+ switch (ev.filter) {
+ case EVFILT_TIMER:
+ received |= RECV_TIMER;
+ break;
+ case EVFILT_VNODE:
+ received |= RECV_VNODE;
+ break;
+ }
+ }
+
+ _exit(received);
+ }
+
+ close(kq);
+
+ /* Setup anything we need to fire off any events above. */
+ error = mkdir("canary", 0755);
+ ATF_REQUIRE(error == 0);
+
+ /* Wait for the child to timeout or observe the timer. */
+ _Static_assert(RECV_ALL <= UCHAR_MAX,
+ "Too many events to observe -- switch from waitpid -> waitid");
+ error = waitpid(pid, &status, 0);
+ ATF_REQUIRE(error != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(WEXITSTATUS(status), RECV_ALL);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, shared_table_filt_sig);
+ ATF_TP_ADD_TC(tp, cponfork_notes);
return (atf_no_error());
}

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 2:58 AM (13 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30760450
Default Alt Text
D56223.id174807.diff (2 KB)

Event Timeline