1*cb5fe245SEnji Cooper /*
2*cb5fe245SEnji Cooper  * Copyright (c) 2009 Mark Heily <[email protected]>
3*cb5fe245SEnji Cooper  *
4*cb5fe245SEnji Cooper  * Permission to use, copy, modify, and distribute this software for any
5*cb5fe245SEnji Cooper  * purpose with or without fee is hereby granted, provided that the above
6*cb5fe245SEnji Cooper  * copyright notice and this permission notice appear in all copies.
7*cb5fe245SEnji Cooper  *
8*cb5fe245SEnji Cooper  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*cb5fe245SEnji Cooper  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*cb5fe245SEnji Cooper  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*cb5fe245SEnji Cooper  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*cb5fe245SEnji Cooper  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*cb5fe245SEnji Cooper  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*cb5fe245SEnji Cooper  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*cb5fe245SEnji Cooper  *
16*cb5fe245SEnji Cooper  * $FreeBSD$
17*cb5fe245SEnji Cooper  */
18*cb5fe245SEnji Cooper 
19*cb5fe245SEnji Cooper #include "common.h"
20*cb5fe245SEnji Cooper 
21*cb5fe245SEnji Cooper int kqfd;
22*cb5fe245SEnji Cooper int vnode_fd;
23*cb5fe245SEnji Cooper 
24*cb5fe245SEnji Cooper void
test_kevent_vnode_add(void)25*cb5fe245SEnji Cooper test_kevent_vnode_add(void)
26*cb5fe245SEnji Cooper {
27*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)";
28*cb5fe245SEnji Cooper     const char *testfile = "./kqueue-test.tmp";
29*cb5fe245SEnji Cooper     struct kevent kev;
30*cb5fe245SEnji Cooper 
31*cb5fe245SEnji Cooper     test_begin(test_id);
32*cb5fe245SEnji Cooper 
33*cb5fe245SEnji Cooper     system("touch ./kqueue-test.tmp");
34*cb5fe245SEnji Cooper     vnode_fd = open(testfile, O_RDONLY);
35*cb5fe245SEnji Cooper     if (vnode_fd < 0)
36*cb5fe245SEnji Cooper         err(1, "open of %s", testfile);
37*cb5fe245SEnji Cooper     else
38*cb5fe245SEnji Cooper         printf("vnode_fd = %d\n", vnode_fd);
39*cb5fe245SEnji Cooper 
40*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD,
41*cb5fe245SEnji Cooper             NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME | NOTE_DELETE, 0, NULL);
42*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
43*cb5fe245SEnji Cooper         err(1, "%s", test_id);
44*cb5fe245SEnji Cooper 
45*cb5fe245SEnji Cooper     success();
46*cb5fe245SEnji Cooper }
47*cb5fe245SEnji Cooper 
48*cb5fe245SEnji Cooper void
test_kevent_vnode_note_delete(void)49*cb5fe245SEnji Cooper test_kevent_vnode_note_delete(void)
50*cb5fe245SEnji Cooper {
51*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE)";
52*cb5fe245SEnji Cooper     struct kevent kev;
53*cb5fe245SEnji Cooper 
54*cb5fe245SEnji Cooper     test_begin(test_id);
55*cb5fe245SEnji Cooper 
56*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);
57*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
58*cb5fe245SEnji Cooper         err(1, "%s", test_id);
59*cb5fe245SEnji Cooper 
60*cb5fe245SEnji Cooper     if (unlink("./kqueue-test.tmp") < 0)
61*cb5fe245SEnji Cooper         err(1, "unlink");
62*cb5fe245SEnji Cooper 
63*cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
64*cb5fe245SEnji Cooper 
65*cb5fe245SEnji Cooper     success();
66*cb5fe245SEnji Cooper }
67*cb5fe245SEnji Cooper 
68*cb5fe245SEnji Cooper void
test_kevent_vnode_note_write(void)69*cb5fe245SEnji Cooper test_kevent_vnode_note_write(void)
70*cb5fe245SEnji Cooper {
71*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, NOTE_WRITE)";
72*cb5fe245SEnji Cooper     struct kevent kev;
73*cb5fe245SEnji Cooper 
74*cb5fe245SEnji Cooper     test_begin(test_id);
75*cb5fe245SEnji Cooper 
76*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_WRITE, 0, NULL);
77*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
78*cb5fe245SEnji Cooper         err(1, "%s", test_id);
79*cb5fe245SEnji Cooper 
80*cb5fe245SEnji Cooper     if (system("echo hello >> ./kqueue-test.tmp") < 0)
81*cb5fe245SEnji Cooper         err(1, "system");
82*cb5fe245SEnji Cooper 
83*cb5fe245SEnji Cooper     /* BSD kqueue adds NOTE_EXTEND even though it was not requested */
84*cb5fe245SEnji Cooper     /* BSD kqueue removes EV_ENABLE */
85*cb5fe245SEnji Cooper     kev.flags &= ~EV_ENABLE; // XXX-FIXME compatibility issue
86*cb5fe245SEnji Cooper     kev.fflags |= NOTE_EXTEND; // XXX-FIXME compatibility issue
87*cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
88*cb5fe245SEnji Cooper 
89*cb5fe245SEnji Cooper     success();
90*cb5fe245SEnji Cooper }
91*cb5fe245SEnji Cooper 
92*cb5fe245SEnji Cooper void
test_kevent_vnode_note_attrib(void)93*cb5fe245SEnji Cooper test_kevent_vnode_note_attrib(void)
94*cb5fe245SEnji Cooper {
95*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, NOTE_ATTRIB)";
96*cb5fe245SEnji Cooper     struct kevent kev;
97*cb5fe245SEnji Cooper     int nfds;
98*cb5fe245SEnji Cooper 
99*cb5fe245SEnji Cooper     test_begin(test_id);
100*cb5fe245SEnji Cooper 
101*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
102*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
103*cb5fe245SEnji Cooper         err(1, "%s", test_id);
104*cb5fe245SEnji Cooper 
105*cb5fe245SEnji Cooper     if (system("touch ./kqueue-test.tmp") < 0)
106*cb5fe245SEnji Cooper         err(1, "system");
107*cb5fe245SEnji Cooper 
108*cb5fe245SEnji Cooper     nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
109*cb5fe245SEnji Cooper     if (nfds < 1)
110*cb5fe245SEnji Cooper         err(1, "%s", test_id);
111*cb5fe245SEnji Cooper     if (kev.ident != vnode_fd ||
112*cb5fe245SEnji Cooper             kev.filter != EVFILT_VNODE ||
113*cb5fe245SEnji Cooper             kev.fflags != NOTE_ATTRIB)
114*cb5fe245SEnji Cooper         err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
115*cb5fe245SEnji Cooper                 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
116*cb5fe245SEnji Cooper 
117*cb5fe245SEnji Cooper     success();
118*cb5fe245SEnji Cooper }
119*cb5fe245SEnji Cooper 
120*cb5fe245SEnji Cooper void
test_kevent_vnode_note_rename(void)121*cb5fe245SEnji Cooper test_kevent_vnode_note_rename(void)
122*cb5fe245SEnji Cooper {
123*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, NOTE_RENAME)";
124*cb5fe245SEnji Cooper     struct kevent kev;
125*cb5fe245SEnji Cooper     int nfds;
126*cb5fe245SEnji Cooper 
127*cb5fe245SEnji Cooper     test_begin(test_id);
128*cb5fe245SEnji Cooper 
129*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_RENAME, 0, NULL);
130*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
131*cb5fe245SEnji Cooper         err(1, "%s", test_id);
132*cb5fe245SEnji Cooper 
133*cb5fe245SEnji Cooper     if (system("mv ./kqueue-test.tmp ./kqueue-test2.tmp") < 0)
134*cb5fe245SEnji Cooper         err(1, "system");
135*cb5fe245SEnji Cooper 
136*cb5fe245SEnji Cooper     nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
137*cb5fe245SEnji Cooper     if (nfds < 1)
138*cb5fe245SEnji Cooper         err(1, "%s", test_id);
139*cb5fe245SEnji Cooper     if (kev.ident != vnode_fd ||
140*cb5fe245SEnji Cooper             kev.filter != EVFILT_VNODE ||
141*cb5fe245SEnji Cooper             kev.fflags != NOTE_RENAME)
142*cb5fe245SEnji Cooper         err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
143*cb5fe245SEnji Cooper                 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
144*cb5fe245SEnji Cooper 
145*cb5fe245SEnji Cooper     if (system("mv ./kqueue-test2.tmp ./kqueue-test.tmp") < 0)
146*cb5fe245SEnji Cooper         err(1, "system");
147*cb5fe245SEnji Cooper 
148*cb5fe245SEnji Cooper     success();
149*cb5fe245SEnji Cooper }
150*cb5fe245SEnji Cooper 
151*cb5fe245SEnji Cooper void
test_kevent_vnode_del(void)152*cb5fe245SEnji Cooper test_kevent_vnode_del(void)
153*cb5fe245SEnji Cooper {
154*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, EV_DELETE)";
155*cb5fe245SEnji Cooper     struct kevent kev;
156*cb5fe245SEnji Cooper 
157*cb5fe245SEnji Cooper     test_begin(test_id);
158*cb5fe245SEnji Cooper 
159*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
160*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
161*cb5fe245SEnji Cooper         err(1, "%s", test_id);
162*cb5fe245SEnji Cooper 
163*cb5fe245SEnji Cooper     success();
164*cb5fe245SEnji Cooper }
165*cb5fe245SEnji Cooper 
166*cb5fe245SEnji Cooper void
test_kevent_vnode_disable_and_enable(void)167*cb5fe245SEnji Cooper test_kevent_vnode_disable_and_enable(void)
168*cb5fe245SEnji Cooper {
169*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)";
170*cb5fe245SEnji Cooper     struct kevent kev;
171*cb5fe245SEnji Cooper     int nfds;
172*cb5fe245SEnji Cooper 
173*cb5fe245SEnji Cooper     test_begin(test_id);
174*cb5fe245SEnji Cooper 
175*cb5fe245SEnji Cooper     test_no_kevents();
176*cb5fe245SEnji Cooper 
177*cb5fe245SEnji Cooper     /* Add the watch and immediately disable it */
178*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
179*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
180*cb5fe245SEnji Cooper         err(1, "%s", test_id);
181*cb5fe245SEnji Cooper     kev.flags = EV_DISABLE;
182*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
183*cb5fe245SEnji Cooper         err(1, "%s", test_id);
184*cb5fe245SEnji Cooper 
185*cb5fe245SEnji Cooper     /* Confirm that the watch is disabled */
186*cb5fe245SEnji Cooper     if (system("touch ./kqueue-test.tmp") < 0)
187*cb5fe245SEnji Cooper         err(1, "system");
188*cb5fe245SEnji Cooper     test_no_kevents();
189*cb5fe245SEnji Cooper 
190*cb5fe245SEnji Cooper     /* Re-enable and check again */
191*cb5fe245SEnji Cooper     kev.flags = EV_ENABLE;
192*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
193*cb5fe245SEnji Cooper         err(1, "%s", test_id);
194*cb5fe245SEnji Cooper     if (system("touch ./kqueue-test.tmp") < 0)
195*cb5fe245SEnji Cooper         err(1, "system");
196*cb5fe245SEnji Cooper     nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
197*cb5fe245SEnji Cooper     if (nfds < 1)
198*cb5fe245SEnji Cooper         err(1, "%s", test_id);
199*cb5fe245SEnji Cooper     if (kev.ident != vnode_fd ||
200*cb5fe245SEnji Cooper             kev.filter != EVFILT_VNODE ||
201*cb5fe245SEnji Cooper             kev.fflags != NOTE_ATTRIB)
202*cb5fe245SEnji Cooper         err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
203*cb5fe245SEnji Cooper                 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
204*cb5fe245SEnji Cooper 
205*cb5fe245SEnji Cooper     success();
206*cb5fe245SEnji Cooper }
207*cb5fe245SEnji Cooper 
208*cb5fe245SEnji Cooper #if HAVE_EV_DISPATCH
209*cb5fe245SEnji Cooper void
test_kevent_vnode_dispatch(void)210*cb5fe245SEnji Cooper test_kevent_vnode_dispatch(void)
211*cb5fe245SEnji Cooper {
212*cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)";
213*cb5fe245SEnji Cooper     struct kevent kev;
214*cb5fe245SEnji Cooper     int nfds;
215*cb5fe245SEnji Cooper 
216*cb5fe245SEnji Cooper     test_begin(test_id);
217*cb5fe245SEnji Cooper 
218*cb5fe245SEnji Cooper     test_no_kevents();
219*cb5fe245SEnji Cooper 
220*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL);
221*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
222*cb5fe245SEnji Cooper         err(1, "%s", test_id);
223*cb5fe245SEnji Cooper 
224*cb5fe245SEnji Cooper     if (system("touch ./kqueue-test.tmp") < 0)
225*cb5fe245SEnji Cooper         err(1, "system");
226*cb5fe245SEnji Cooper 
227*cb5fe245SEnji Cooper     nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
228*cb5fe245SEnji Cooper     if (nfds < 1)
229*cb5fe245SEnji Cooper         err(1, "%s", test_id);
230*cb5fe245SEnji Cooper     if (kev.ident != vnode_fd ||
231*cb5fe245SEnji Cooper             kev.filter != EVFILT_VNODE ||
232*cb5fe245SEnji Cooper             kev.fflags != NOTE_ATTRIB)
233*cb5fe245SEnji Cooper         err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
234*cb5fe245SEnji Cooper                 test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
235*cb5fe245SEnji Cooper 
236*cb5fe245SEnji Cooper     /* Confirm that the watch is disabled automatically */
237*cb5fe245SEnji Cooper     puts("-- checking that watch is disabled");
238*cb5fe245SEnji Cooper     if (system("touch ./kqueue-test.tmp") < 0)
239*cb5fe245SEnji Cooper         err(1, "system");
240*cb5fe245SEnji Cooper     test_no_kevents();
241*cb5fe245SEnji Cooper 
242*cb5fe245SEnji Cooper     /* Delete the watch */
243*cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL);
244*cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
245*cb5fe245SEnji Cooper         err(1, "remove watch failed: %s", test_id);
246*cb5fe245SEnji Cooper 
247*cb5fe245SEnji Cooper     success();
248*cb5fe245SEnji Cooper }
249*cb5fe245SEnji Cooper #endif 	/* HAVE_EV_DISPATCH */
250*cb5fe245SEnji Cooper 
251*cb5fe245SEnji Cooper void
test_evfilt_vnode()252*cb5fe245SEnji Cooper test_evfilt_vnode()
253*cb5fe245SEnji Cooper {
254*cb5fe245SEnji Cooper     kqfd = kqueue();
255*cb5fe245SEnji Cooper     test_kevent_vnode_add();
256*cb5fe245SEnji Cooper     test_kevent_vnode_del();
257*cb5fe245SEnji Cooper     test_kevent_vnode_disable_and_enable();
258*cb5fe245SEnji Cooper #if HAVE_EV_DISPATCH
259*cb5fe245SEnji Cooper     test_kevent_vnode_dispatch();
260*cb5fe245SEnji Cooper #endif
261*cb5fe245SEnji Cooper     test_kevent_vnode_note_write();
262*cb5fe245SEnji Cooper     test_kevent_vnode_note_attrib();
263*cb5fe245SEnji Cooper     test_kevent_vnode_note_rename();
264*cb5fe245SEnji Cooper     test_kevent_vnode_note_delete();
265*cb5fe245SEnji Cooper     close(kqfd);
266*cb5fe245SEnji Cooper }
267