diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-07-08 12:31:04 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-07-08 12:31:04 +0000 |
commit | 78d04e54e4b4d3157fca1697775b7abf1fb24bfb (patch) | |
tree | 1fb0796a4d31bf73b0e640f0ddfdde47ed9fd9c5 | |
parent | 25bdd431bb109306c3be375df54b1a641b2bdd01 (diff) |
Add a test for kevent(EV_DELETE) screwing with POSIX file locks
-rw-r--r-- | regress/sys/kern/kqueue/Makefile | 9 | ||||
-rw-r--r-- | regress/sys/kern/kqueue/kqueue-flock.c | 91 | ||||
-rw-r--r-- | regress/sys/kern/kqueue/main.c | 8 |
3 files changed, 103 insertions, 5 deletions
diff --git a/regress/sys/kern/kqueue/Makefile b/regress/sys/kern/kqueue/Makefile index b1ea724f570..035cbd91c6d 100644 --- a/regress/sys/kern/kqueue/Makefile +++ b/regress/sys/kern/kqueue/Makefile @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile,v 1.15 2011/07/07 02:00:51 guenther Exp $ +# $OpenBSD: Makefile,v 1.16 2012/07/08 12:31:03 guenther Exp $ PROG= kqueue-test CFLAGS+=-Wall SRCS= kqueue-pipe.c kqueue-fork.c main.c kqueue-process.c kqueue-random.c \ - kqueue-pty.c kqueue-tun.c kqueue-signal.c kqueue-fdpass.c + kqueue-pty.c kqueue-tun.c kqueue-signal.c kqueue-fdpass.c \ + kqueue-flock.c LDADD= -levent -lutil DPADD= ${LIBEVENT} ${LIBUTIL} @@ -27,9 +28,11 @@ kq-signal: ${PROG} ./${PROG} -s kq-fdpass: ${PROG} ./${PROG} -F +kq-flock: ${PROG} + ./${PROG} -l REGRESS_TARGETS=kq-pipe kq-fork kq-process kq-random kq-tun kq-pty kq-signal \ - kq-fdpass + kq-fdpass kq-flock REGRESS_ROOT_TARGETS=${REGRESS_TARGETS} .PHONY: ${REGRESS_TARGETS} diff --git a/regress/sys/kern/kqueue/kqueue-flock.c b/regress/sys/kern/kqueue/kqueue-flock.c new file mode 100644 index 00000000000..68a14f5f56f --- /dev/null +++ b/regress/sys/kern/kqueue/kqueue-flock.c @@ -0,0 +1,91 @@ +/* $OpenBSD: kqueue-flock.c,v 1.1 2012/07/08 12:31:03 guenther Exp $ */ +/* + * Written by Philip Guenther <guenther@openbsd.org> 2012 Public Domain + */ + +#include <sys/types.h> +#include <sys/event.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#define FILE "lock.test" + +int do_flock(void); + +static void +check_lock(int fd, const char *msg) +{ + pid_t pid = fork(); + int status; + + if (pid == -1) + err(1, "fork"); + if (pid == 0) { + struct flock fl; + + memset(&fl, 0, sizeof fl); + fl.l_type = F_WRLCK; + if (fcntl(fd, F_SETLK, &fl) == 0) { + printf("lock succeeded %s\n", msg); + _exit(1); + } + if (errno != EAGAIN) + err(1, "fcntl(SETLK)"); + if (fcntl(fd, F_GETLK, &fl)) + err(1, "fcntl(GETLK)"); + if (fl.l_type != F_WRLCK) { + printf("lock not found %s\n"); + _exit(1); + } + _exit(0); + } + + waitpid(pid, &status, 0); + if (! WIFEXITED(status) || WEXITSTATUS(status) != 0) + exit(1); +} + +int +do_flock(void) +{ + int fd, kq; + struct kevent kev; + struct flock fl; + + fd = open(FILE, O_CREAT|O_RDWR, 0666); + if (fd < 0) + err(1, "open"); + memset(&fl, 0, sizeof fl); + fl.l_type = F_WRLCK; + if (fcntl(fd, F_SETLK, &fl)) + err(1, "fcntl(SETLK)"); + + check_lock(fd, "before"); + + kq = kqueue(); + EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD, NOTE_LINK, 0, NULL); + if (kevent(kq, &kev, 1, NULL, 0, NULL)) + err(1, "kevent"); + + check_lock(fd, "after add"); + + EV_SET(&kev, fd, EVFILT_VNODE, EV_DELETE, NOTE_LINK, 0, NULL); + if (kevent(kq, &kev, 1, NULL, 0, NULL)) + err(1, "kevent"); + + check_lock(fd, "after delete"); + + close(kq); + + check_lock(fd, "after kq close"); + + close(fd); + unlink(FILE); + return (0); +} diff --git a/regress/sys/kern/kqueue/main.c b/regress/sys/kern/kqueue/main.c index 26f1d50a2c1..d99507932ef 100644 --- a/regress/sys/kern/kqueue/main.c +++ b/regress/sys/kern/kqueue/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.6 2011/07/07 02:00:51 guenther Exp $ */ +/* $OpenBSD: main.c,v 1.7 2012/07/08 12:31:03 guenther Exp $ */ /* * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain */ @@ -15,6 +15,7 @@ int do_random(void); int do_pty(void); int do_tun(void); int do_fdpass(void); +int do_flock(void); int main(int argc, char **argv) @@ -23,7 +24,7 @@ main(int argc, char **argv) int ret, c; ret = 0; - while ((c = getopt(argc, argv, "fFpPrstT")) != -1) { + while ((c = getopt(argc, argv, "fFlpPrstT")) != -1) { switch (c) { case 'f': ret |= check_inheritance(); @@ -31,6 +32,9 @@ main(int argc, char **argv) case 'F': ret |= do_fdpass(); break; + case 'l': + ret |= do_flock(); + break; case 'p': ret |= do_pipe(); break; |