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 * $FreeBSD: stable/11/tests/sys/kqueue/libkqueue/user.c 359754 2020-04-09 20:38:36Z kevans $
17 */
18
19#include "common.h"
20
21
22static void
23add_and_delete(void)
24{
25    const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)";
26    struct kevent kev;
27
28    test_begin(test_id);
29
30    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
31    test_no_kevents();
32
33    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL);
34    test_no_kevents();
35
36    success();
37}
38
39static void
40event_wait(void)
41{
42    const char *test_id = "kevent(EVFILT_USER, wait)";
43    struct kevent kev;
44
45    test_begin(test_id);
46
47    test_no_kevents();
48
49    /* Add the event, and then trigger it */
50    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL);
51    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
52
53    kev.fflags &= ~NOTE_FFCTRLMASK;
54    kev.fflags &= ~NOTE_TRIGGER;
55    kev.flags = EV_CLEAR;
56    kevent_cmp(&kev, kevent_get(kqfd));
57
58    test_no_kevents();
59
60    success();
61}
62
63static void
64disable_and_enable(void)
65{
66    const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)";
67    struct kevent kev;
68
69    test_begin(test_id);
70
71    test_no_kevents();
72
73    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
74    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL);
75
76    /* Trigger the event, but since it is disabled, nothing will happen. */
77    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
78    test_no_kevents();
79
80    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL);
81    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
82
83    kev.flags = EV_CLEAR;
84    kev.fflags &= ~NOTE_FFCTRLMASK;
85    kev.fflags &= ~NOTE_TRIGGER;
86    kevent_cmp(&kev, kevent_get(kqfd));
87
88    success();
89}
90
91static void
92oneshot(void)
93{
94    const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)";
95    struct kevent kev;
96
97    test_begin(test_id);
98
99    test_no_kevents();
100
101    kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL);
102
103    puts("  -- event 1");
104    kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
105
106    kev.flags = EV_ONESHOT;
107    kev.fflags &= ~NOTE_FFCTRLMASK;
108    kev.fflags &= ~NOTE_TRIGGER;
109    kevent_cmp(&kev, kevent_get(kqfd));
110
111    test_no_kevents();
112
113    success();
114}
115
116void
117test_evfilt_user()
118{
119    kqfd = kqueue();
120
121    add_and_delete();
122    event_wait();
123    disable_and_enable();
124    oneshot();
125    /* TODO: try different fflags operations */
126
127    close(kqfd);
128}
129