Path: blob/main/tests/sys/kqueue/libkqueue/vnode.c
39566 views
/*1* Copyright (c) 2009 Mark Heily <[email protected]>2*3* Permission to use, copy, modify, and distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES8* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF9* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR10* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES11* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN12* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF13* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.14*/1516#include "common.h"1718int vnode_fd;1920static void21test_kevent_vnode_add(void)22{23const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)";24const char *testfile = "./kqueue-test.tmp";25struct kevent kev;2627test_begin(test_id);2829system("touch ./kqueue-test.tmp");30vnode_fd = open(testfile, O_RDONLY);31if (vnode_fd < 0)32err(1, "open of %s", testfile);33else34printf("vnode_fd = %d\n", vnode_fd);3536EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD,37NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME | NOTE_DELETE, 0, NULL);38if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)39err(1, "%s", test_id);4041success();42}4344static void45test_kevent_vnode_note_delete(void)46{47const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE)";48struct kevent kev;4950test_begin(test_id);5152EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);53if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)54err(1, "%s", test_id);5556if (unlink("./kqueue-test.tmp") < 0)57err(1, "unlink");5859kevent_cmp(&kev, kevent_get(kqfd));6061success();62}6364static void65test_kevent_vnode_note_delete_fifo(void)66{67const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE, FIFO)";68const char *fifo_path = "./kqueue-fifo.tmp";69struct kevent kev;70int fd;71pid_t pid;7273test_begin(test_id);7475if (mkfifo(fifo_path, 0600) != 0)76err(1, "mkfifo");7778pid = fork();79if (pid == -1)80err(1, "fork");8182if (pid == 0) {83char buf[4];8485fd = open(fifo_path, O_RDONLY);86if (fd == -1)87_exit(1);8889while (read(fd, buf, sizeof(buf)) != 0) {90}9192_exit(0);93}9495sleep(1);96if (waitpid(pid, NULL, WNOHANG) == pid) {97unlink(fifo_path);98err(1, "open");99}100101fd = open(fifo_path, O_WRONLY);102if (fd < 0) {103unlink(fifo_path);104err(1, "open");105}106107EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);108if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) {109unlink(fifo_path);110err(1, "%s", test_id);111}112113if (unlink(fifo_path) < 0)114err(1, "unlink");115116kevent_cmp(&kev, kevent_get(kqfd));117close(fd);118119success();120}121122static void123test_kevent_vnode_note_write(void)124{125const char *test_id = "kevent(EVFILT_VNODE, NOTE_WRITE)";126struct kevent kev;127128test_begin(test_id);129130EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_WRITE, 0, NULL);131if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)132err(1, "%s", test_id);133134if (system("echo hello >> ./kqueue-test.tmp") < 0)135err(1, "system");136137/* BSD kqueue adds NOTE_EXTEND even though it was not requested */138/* BSD kqueue removes EV_ENABLE */139kev.flags &= ~EV_ENABLE; // XXX-FIXME compatibility issue140kev.fflags |= NOTE_EXTEND; // XXX-FIXME compatibility issue141kevent_cmp(&kev, kevent_get(kqfd));142143success();144}145146static void147test_kevent_vnode_note_attrib(void)148{149const char *test_id = "kevent(EVFILT_VNODE, NOTE_ATTRIB)";150struct kevent kev;151int nfds;152153test_begin(test_id);154155EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);156if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)157err(1, "%s", test_id);158159if (system("touch ./kqueue-test.tmp") < 0)160err(1, "system");161162nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);163if (nfds < 1)164err(1, "%s", test_id);165if (kev.ident != (uintptr_t)vnode_fd ||166kev.filter != EVFILT_VNODE ||167kev.fflags != NOTE_ATTRIB)168err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",169test_id, (unsigned int)kev.ident, kev.filter, kev.flags);170171success();172}173174static void175test_kevent_vnode_note_rename(void)176{177const char *test_id = "kevent(EVFILT_VNODE, NOTE_RENAME)";178struct kevent kev;179int nfds;180181test_begin(test_id);182183EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_RENAME, 0, NULL);184if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)185err(1, "%s", test_id);186187if (system("mv ./kqueue-test.tmp ./kqueue-test2.tmp") < 0)188err(1, "system");189190nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);191if (nfds < 1)192err(1, "%s", test_id);193if (kev.ident != (uintptr_t)vnode_fd ||194kev.filter != EVFILT_VNODE ||195kev.fflags != NOTE_RENAME)196err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",197test_id, (unsigned int)kev.ident, kev.filter, kev.flags);198199if (system("mv ./kqueue-test2.tmp ./kqueue-test.tmp") < 0)200err(1, "system");201202success();203}204205static void206test_kevent_vnode_del(void)207{208const char *test_id = "kevent(EVFILT_VNODE, EV_DELETE)";209struct kevent kev;210211test_begin(test_id);212213EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);214if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)215err(1, "%s", test_id);216217success();218}219220static void221test_kevent_vnode_disable_and_enable(void)222{223const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)";224struct kevent kev;225int nfds;226227test_begin(test_id);228229test_no_kevents();230231/* Add the watch and immediately disable it */232EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);233if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)234err(1, "%s", test_id);235kev.flags = EV_DISABLE;236if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)237err(1, "%s", test_id);238239/* Confirm that the watch is disabled */240if (system("touch ./kqueue-test.tmp") < 0)241err(1, "system");242test_no_kevents();243244/* Re-enable and check again */245kev.flags = EV_ENABLE;246if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)247err(1, "%s", test_id);248if (system("touch ./kqueue-test.tmp") < 0)249err(1, "system");250nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);251if (nfds < 1)252err(1, "%s", test_id);253if (kev.ident != (uintptr_t)vnode_fd ||254kev.filter != EVFILT_VNODE ||255kev.fflags != NOTE_ATTRIB)256err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",257test_id, (unsigned int)kev.ident, kev.filter, kev.flags);258259success();260}261262#if HAVE_EV_DISPATCH263static void264test_kevent_vnode_dispatch(void)265{266const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)";267struct kevent kev;268int nfds;269270test_begin(test_id);271272test_no_kevents();273274EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL);275if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)276err(1, "%s", test_id);277278if (system("touch ./kqueue-test.tmp") < 0)279err(1, "system");280281nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);282if (nfds < 1)283err(1, "%s", test_id);284if (kev.ident != (uintptr_t)vnode_fd ||285kev.filter != EVFILT_VNODE ||286kev.fflags != NOTE_ATTRIB)287err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",288test_id, (unsigned int)kev.ident, kev.filter, kev.flags);289290/* Confirm that the watch is disabled automatically */291puts("-- checking that watch is disabled");292if (system("touch ./kqueue-test.tmp") < 0)293err(1, "system");294test_no_kevents();295296/* Delete the watch */297EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL);298if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)299err(1, "remove watch failed: %s", test_id);300301success();302}303#endif /* HAVE_EV_DISPATCH */304305void306test_evfilt_vnode(void)307{308kqfd = kqueue();309test_kevent_vnode_add();310test_kevent_vnode_del();311test_kevent_vnode_disable_and_enable();312#if HAVE_EV_DISPATCH313test_kevent_vnode_dispatch();314#endif315test_kevent_vnode_note_write();316test_kevent_vnode_note_attrib();317test_kevent_vnode_note_rename();318test_kevent_vnode_note_delete();319test_kevent_vnode_note_delete_fifo();320close(kqfd);321}322323324