160a396a4SRobert Watson /*
260a396a4SRobert Watson * Copyright (c) 2009 Mark Heily <mark@heily.com>
360a396a4SRobert Watson *
460a396a4SRobert Watson * Permission to use, copy, modify, and distribute this software for any
560a396a4SRobert Watson * purpose with or without fee is hereby granted, provided that the above
660a396a4SRobert Watson * copyright notice and this permission notice appear in all copies.
760a396a4SRobert Watson *
860a396a4SRobert Watson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
960a396a4SRobert Watson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1060a396a4SRobert Watson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1160a396a4SRobert Watson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1260a396a4SRobert Watson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1360a396a4SRobert Watson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1460a396a4SRobert Watson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1560a396a4SRobert Watson */
1660a396a4SRobert Watson
1760a396a4SRobert Watson #include "common.h"
1860a396a4SRobert Watson
1960a396a4SRobert Watson
2060a396a4SRobert Watson static void
add_and_delete(void)2160a396a4SRobert Watson add_and_delete(void)
2260a396a4SRobert Watson {
2360a396a4SRobert Watson const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)";
2460a396a4SRobert Watson struct kevent kev;
2560a396a4SRobert Watson
2660a396a4SRobert Watson test_begin(test_id);
2760a396a4SRobert Watson
2860a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
2960a396a4SRobert Watson test_no_kevents();
3060a396a4SRobert Watson
3160a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL);
3260a396a4SRobert Watson test_no_kevents();
3360a396a4SRobert Watson
3460a396a4SRobert Watson success();
3560a396a4SRobert Watson }
3660a396a4SRobert Watson
3760a396a4SRobert Watson static void
event_wait(void)3860a396a4SRobert Watson event_wait(void)
3960a396a4SRobert Watson {
4060a396a4SRobert Watson const char *test_id = "kevent(EVFILT_USER, wait)";
4160a396a4SRobert Watson struct kevent kev;
4260a396a4SRobert Watson
4360a396a4SRobert Watson test_begin(test_id);
4460a396a4SRobert Watson
45407cf730SRobert Watson test_no_kevents();
46407cf730SRobert Watson
4760a396a4SRobert Watson /* Add the event, and then trigger it */
48407cf730SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL);
4960a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
5060a396a4SRobert Watson
5160a396a4SRobert Watson kev.fflags &= ~NOTE_FFCTRLMASK;
5260a396a4SRobert Watson kev.fflags &= ~NOTE_TRIGGER;
53407cf730SRobert Watson kev.flags = EV_CLEAR;
5460a396a4SRobert Watson kevent_cmp(&kev, kevent_get(kqfd));
5560a396a4SRobert Watson
5660a396a4SRobert Watson test_no_kevents();
5760a396a4SRobert Watson
5860a396a4SRobert Watson success();
5960a396a4SRobert Watson }
6060a396a4SRobert Watson
6160a396a4SRobert Watson static void
event_wait_keepudata(void)620321a799SNathaniel Wesley Filardo event_wait_keepudata(void)
630321a799SNathaniel Wesley Filardo {
640321a799SNathaniel Wesley Filardo const char *test_id = "kevent(EVFILT_USER, wait w/ EV_KEEPUDATA)";
650321a799SNathaniel Wesley Filardo struct kevent kev;
660321a799SNathaniel Wesley Filardo
670321a799SNathaniel Wesley Filardo test_begin(test_id);
680321a799SNathaniel Wesley Filardo
690321a799SNathaniel Wesley Filardo test_no_kevents();
700321a799SNathaniel Wesley Filardo
710321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, &kev);
720321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0,
730321a799SNathaniel Wesley Filardo NULL);
740321a799SNathaniel Wesley Filardo
750321a799SNathaniel Wesley Filardo kev.fflags &= ~NOTE_FFCTRLMASK;
760321a799SNathaniel Wesley Filardo kev.fflags &= ~NOTE_TRIGGER;
770321a799SNathaniel Wesley Filardo kev.flags = EV_CLEAR;
780321a799SNathaniel Wesley Filardo kev.udata = &kev;
790321a799SNathaniel Wesley Filardo kevent_cmp(&kev, kevent_get(kqfd));
800321a799SNathaniel Wesley Filardo
810321a799SNathaniel Wesley Filardo test_no_kevents();
820321a799SNathaniel Wesley Filardo
830321a799SNathaniel Wesley Filardo success();
840321a799SNathaniel Wesley Filardo }
850321a799SNathaniel Wesley Filardo
860321a799SNathaniel Wesley Filardo
870321a799SNathaniel Wesley Filardo static void
disable_and_enable(void)8860a396a4SRobert Watson disable_and_enable(void)
8960a396a4SRobert Watson {
9060a396a4SRobert Watson const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)";
9160a396a4SRobert Watson struct kevent kev;
9260a396a4SRobert Watson
9360a396a4SRobert Watson test_begin(test_id);
9460a396a4SRobert Watson
95407cf730SRobert Watson test_no_kevents();
96407cf730SRobert Watson
9760a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
9860a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL);
9960a396a4SRobert Watson
10060a396a4SRobert Watson /* Trigger the event, but since it is disabled, nothing will happen. */
10160a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
10260a396a4SRobert Watson test_no_kevents();
10360a396a4SRobert Watson
10460a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL);
10560a396a4SRobert Watson kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
10660a396a4SRobert Watson
107407cf730SRobert Watson kev.flags = EV_CLEAR;
10860a396a4SRobert Watson kev.fflags &= ~NOTE_FFCTRLMASK;
10960a396a4SRobert Watson kev.fflags &= ~NOTE_TRIGGER;
11060a396a4SRobert Watson kevent_cmp(&kev, kevent_get(kqfd));
11160a396a4SRobert Watson
11260a396a4SRobert Watson success();
11360a396a4SRobert Watson }
11460a396a4SRobert Watson
11560a396a4SRobert Watson static void
disable_and_enable_keepudata(void)1160321a799SNathaniel Wesley Filardo disable_and_enable_keepudata(void)
1170321a799SNathaniel Wesley Filardo {
1180321a799SNathaniel Wesley Filardo const char *test_id =
1190321a799SNathaniel Wesley Filardo "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE w/ EV_KEEPUDATA)";
1200321a799SNathaniel Wesley Filardo struct kevent kev;
1210321a799SNathaniel Wesley Filardo
1220321a799SNathaniel Wesley Filardo test_begin(test_id);
1230321a799SNathaniel Wesley Filardo
1240321a799SNathaniel Wesley Filardo test_no_kevents();
1250321a799SNathaniel Wesley Filardo
1260321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, &kev);
1270321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE | EV_KEEPUDATA, 0, 0,
1280321a799SNathaniel Wesley Filardo NULL);
1290321a799SNathaniel Wesley Filardo
1300321a799SNathaniel Wesley Filardo /* Trigger the event, but since it is disabled, nothing will happen. */
1310321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL);
1320321a799SNathaniel Wesley Filardo test_no_kevents();
1330321a799SNathaniel Wesley Filardo
1340321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE | EV_KEEPUDATA, 0, 0,
1350321a799SNathaniel Wesley Filardo NULL);
1360321a799SNathaniel Wesley Filardo kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL);
1370321a799SNathaniel Wesley Filardo
1380321a799SNathaniel Wesley Filardo kev.flags = EV_CLEAR;
1390321a799SNathaniel Wesley Filardo kev.fflags &= ~NOTE_FFCTRLMASK;
1400321a799SNathaniel Wesley Filardo kev.fflags &= ~NOTE_TRIGGER;
1410321a799SNathaniel Wesley Filardo kev.udata = &kev;
1420321a799SNathaniel Wesley Filardo kevent_cmp(&kev, kevent_get(kqfd));
1430321a799SNathaniel Wesley Filardo
1440321a799SNathaniel Wesley Filardo success();
1450321a799SNathaniel Wesley Filardo }
1460321a799SNathaniel Wesley Filardo
1470321a799SNathaniel Wesley Filardo static void
oneshot(void)14860a396a4SRobert Watson oneshot(void)
14960a396a4SRobert Watson {
15060a396a4SRobert Watson const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)";
15160a396a4SRobert Watson struct kevent kev;
15260a396a4SRobert Watson
15360a396a4SRobert Watson test_begin(test_id);
15460a396a4SRobert Watson
155407cf730SRobert Watson test_no_kevents();
156407cf730SRobert Watson
157407cf730SRobert Watson kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL);
15860a396a4SRobert Watson
15960a396a4SRobert Watson puts(" -- event 1");
160407cf730SRobert Watson kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
16160a396a4SRobert Watson
162407cf730SRobert Watson kev.flags = EV_ONESHOT;
16360a396a4SRobert Watson kev.fflags &= ~NOTE_FFCTRLMASK;
16460a396a4SRobert Watson kev.fflags &= ~NOTE_TRIGGER;
16560a396a4SRobert Watson kevent_cmp(&kev, kevent_get(kqfd));
16660a396a4SRobert Watson
16760a396a4SRobert Watson test_no_kevents();
16860a396a4SRobert Watson
16960a396a4SRobert Watson success();
17060a396a4SRobert Watson }
17160a396a4SRobert Watson
17260a396a4SRobert Watson void
test_evfilt_user(void)173c9c283bdSAlex Richardson test_evfilt_user(void)
17460a396a4SRobert Watson {
17560a396a4SRobert Watson kqfd = kqueue();
17660a396a4SRobert Watson
17760a396a4SRobert Watson add_and_delete();
17860a396a4SRobert Watson event_wait();
1790321a799SNathaniel Wesley Filardo event_wait_keepudata();
18060a396a4SRobert Watson disable_and_enable();
1810321a799SNathaniel Wesley Filardo disable_and_enable_keepudata();
18260a396a4SRobert Watson oneshot();
18360a396a4SRobert Watson /* TODO: try different fflags operations */
18460a396a4SRobert Watson
18560a396a4SRobert Watson close(kqfd);
18660a396a4SRobert Watson }
187