Add initial regress tests for kqueue1(2)
authorvisa <visa@openbsd.org>
Sun, 20 Aug 2023 15:19:34 +0000 (15:19 +0000)
committervisa <visa@openbsd.org>
Sun, 20 Aug 2023 15:19:34 +0000 (15:19 +0000)
regress/sys/kern/kqueue/Makefile
regress/sys/kern/kqueue/kqueue-exec.c [new file with mode: 0644]
regress/sys/kern/kqueue/main.c
regress/sys/kern/kqueue/main.h

index 9411ec9..d1a87a9 100644 (file)
@@ -1,13 +1,15 @@
-#      $OpenBSD: Makefile,v 1.31 2022/03/30 05:11:52 anton Exp $
+#      $OpenBSD: Makefile,v 1.32 2023/08/20 15:19:34 visa 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-flock.c kqueue-timer.c kqueue-regress.c
+       kqueue-exec.c kqueue-flock.c kqueue-timer.c kqueue-regress.c
 LDADD= -levent -lutil
 DPADD= ${LIBEVENT} ${LIBUTIL}
 
+kq-exec: ${PROG}
+       ./${PROG} -e
 kq-pipe: ${PROG}
        ./${PROG} -p
 kq-fork: ${PROG}
@@ -51,6 +53,7 @@ kq-regress-5: ${PROG}
 kq-regress-6: ${PROG}
        ./${PROG} -R6
 
+TESTS+=        kq-exec
 TESTS+=        kq-fdpass
 TESTS+=        kq-flock
 TESTS+=        kq-fork
diff --git a/regress/sys/kern/kqueue/kqueue-exec.c b/regress/sys/kern/kqueue/kqueue-exec.c
new file mode 100644 (file)
index 0000000..da328a1
--- /dev/null
@@ -0,0 +1,113 @@
+/*     $OpenBSD: kqueue-exec.c,v 1.1 2023/08/20 15:19:34 visa Exp $    */
+
+/*
+ * Copyright (c) 2023 Visa Hankala
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "main.h"
+
+static void    do_exec_child(void);
+static void    do_exec_parent(const char *, int);
+
+int
+do_exec(const char *argv0)
+{
+       do_exec_parent(argv0, 0);
+       do_exec_parent(argv0, 1);
+       return 0;
+}
+
+static void
+do_exec_parent(const char *argv0, int cloexec)
+{
+       char *args[] = {
+               (char *)argv0,
+               "-e",
+               NULL
+       };
+       char fdbuf[12];
+       pid_t pid;
+       int kq, status;
+
+       if (getenv("REGRESS_KQUEUE_FD") != NULL) {
+               do_exec_child();
+               _exit(0);
+       }
+
+       pid = fork();
+       if (pid == -1)
+               err(1, "fork");
+       if (pid == 0) {
+               kq = kqueue1(cloexec ? O_CLOEXEC : 0);
+               if (kq == -1)
+                       err(1, "kqueue1");
+               snprintf(fdbuf, sizeof(fdbuf), "%d", kq);
+               if (setenv("REGRESS_KQUEUE_FD", fdbuf, 1) == -1)
+                       err(1, "setenv");
+               if (setenv("REGRESS_KQUEUE_CLOEXEC",
+                   cloexec ? "1" : "0", 1) == -1)
+                       err(1, "setenv 2");
+               execv(argv0, args);
+               err(1, "execve");
+       }
+       if (waitpid(pid, &status, 0) == -1)
+               err(1, "waitpid");
+       if (status != 0)
+               errx(1, "child failed");
+}
+
+static void
+do_exec_child(void)
+{
+       char *arg;
+       int cloexec, fd;
+
+       arg = getenv("REGRESS_KQUEUE_FD");
+       if (arg == NULL)
+               errx(1, "fd arg is missing");
+       fd = atoi(arg);
+
+       arg = getenv("REGRESS_KQUEUE_CLOEXEC");
+       if (arg != NULL && strcmp(arg, "1") == 0)
+               cloexec = 1;
+       else
+               cloexec = 0;
+
+       if (cloexec) {
+               if (kevent(fd, NULL, 0, NULL, 0, 0) == -1) {
+                       if (errno != EBADF)
+                               err(1, "child after exec: kevent cloexec");
+               } else {
+                       errx(1, "child after exec: "
+                           "kqueue cloexec fd is not closed");
+               }
+       } else {
+               if (kevent(fd, NULL, 0, NULL, 0, 0) == -1) {
+                       err(1, "child after exec: kevent");
+               }
+       }
+}
index d5f3d0e..502edd6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.15 2021/06/12 13:30:14 visa Exp $  */
+/*     $OpenBSD: main.c,v 1.16 2023/08/20 15:19:34 visa Exp $  */
 /*
  *     Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain
  */
@@ -17,8 +17,11 @@ main(int argc, char **argv)
        int n, ret, c;
 
        ret = 0;
-       while ((c = getopt(argc, argv, "fFiIjlpPrR:stT:")) != -1) {
+       while ((c = getopt(argc, argv, "efFiIjlpPrR:stT:")) != -1) {
                switch (c) {
+               case 'e':
+                       ret |= do_exec(argv[0]);
+                       break;
                case 'f':
                        ret |= check_inheritance();
                        break;
index 9fad3c2..f2ee839 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.h,v 1.6 2021/06/12 13:30:14 visa Exp $   */
+/*     $OpenBSD: main.h,v 1.7 2023/08/20 15:19:34 visa Exp $   */
 /*
  *     Written by Alexaner Bluhm <bluhm@openbsd.org> 2016 Public Domain
  */
@@ -16,6 +16,7 @@
            __FILE__, __LINE__))
 
 int check_inheritance(void);
+int do_exec(const char *);
 int do_fdpass(void);
 int do_flock(void);
 int do_invalid_timer(void);