summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-08 12:31:04 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-08 12:31:04 +0000
commit78d04e54e4b4d3157fca1697775b7abf1fb24bfb (patch)
tree1fb0796a4d31bf73b0e640f0ddfdde47ed9fd9c5
parent25bdd431bb109306c3be375df54b1a641b2bdd01 (diff)
Add a test for kevent(EV_DELETE) screwing with POSIX file locks
-rw-r--r--regress/sys/kern/kqueue/Makefile9
-rw-r--r--regress/sys/kern/kqueue/kqueue-flock.c91
-rw-r--r--regress/sys/kern/kqueue/main.c8
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;