summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/kernel')
-rwxr-xr-xcontrib/netbsd-tests/kernel/gen_t_subr_prf134
-rw-r--r--contrib/netbsd-tests/kernel/h_ps_strings1.c74
-rw-r--r--contrib/netbsd-tests/kernel/h_ps_strings2.c69
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c98
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/read/t_file.c139
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/read/t_file2.c79
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c84
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c144
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/t_ioctl.c115
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/t_proc1.c154
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/t_proc2.c138
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/t_proc3.c99
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/t_sig.c133
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c102
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c147
-rw-r--r--contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c130
-rw-r--r--contrib/netbsd-tests/kernel/t_extattrctl.c28
-rw-r--r--contrib/netbsd-tests/kernel/t_extent.c385
-rw-r--r--contrib/netbsd-tests/kernel/t_filedesc.c108
-rw-r--r--contrib/netbsd-tests/kernel/t_kauth_pr_47598.c169
-rw-r--r--contrib/netbsd-tests/kernel/t_lock.c87
-rw-r--r--contrib/netbsd-tests/kernel/t_lockf.c262
-rw-r--r--contrib/netbsd-tests/kernel/t_mqueue.c137
-rwxr-xr-xcontrib/netbsd-tests/kernel/t_ps_strings.sh85
-rw-r--r--contrib/netbsd-tests/kernel/t_pty.c351
-rw-r--r--contrib/netbsd-tests/kernel/t_rnd.c95
-rw-r--r--contrib/netbsd-tests/kernel/t_sysctl.c74
-rw-r--r--contrib/netbsd-tests/kernel/t_sysv.c854
-rwxr-xr-xcontrib/netbsd-tests/kernel/t_umount.sh95
-rwxr-xr-xcontrib/netbsd-tests/kernel/t_umountstress.sh209
-rw-r--r--contrib/netbsd-tests/kernel/tty/t_pr.c186
31 files changed, 4964 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/kernel/gen_t_subr_prf b/contrib/netbsd-tests/kernel/gen_t_subr_prf
new file mode 100755
index 0000000..b58a6ba
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/gen_t_subr_prf
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+cat << _EOF > $2
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <sha2.h>
+
+#include <atf-c.h>
+
+/* Avoid SSP re-definitions */
+#undef snprintf
+#undef vsnprintf
+#undef sprintf
+#undef vsprintf
+
+#define KPRINTF_BUFSIZE 1024
+#undef putchar
+#define putchar xputchar
+
+static int putchar(char c, int foo, void *b)
+{
+ return fputc(c, stderr);
+}
+
+#define TOBUFONLY 1
+static const char HEXDIGITS[] = "0123456789ABCDEF";
+static const char hexdigits[] = "0123456789abcdef";
+
+typedef int device_t;
+
+#if 0
+static SHA512_CTX kprnd_sha;
+#endif
+
+#define timespec timeval
+#define nanotime(ts) gettimeofday(ts, NULL)
+
+#define device_xname(a) ""
+int kprintf(const char *, int, void *, char *, va_list) __printflike(1, 0);
+void device_printf(device_t, const char *, ...) __printflike(2, 3);
+
+static void
+empty(void)
+{
+}
+
+static void (*v_flush)(void) = empty;
+
+ATF_TC(snprintf_print);
+ATF_TC_HEAD(snprintf_print, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "checks snprintf print");
+}
+
+ATF_TC_BODY(snprintf_print, tc)
+{
+ char buf[10];
+ int i;
+
+ memset(buf, 'x', sizeof(buf));
+ i = snprintf(buf, sizeof(buf), "number %d", 10);
+ ATF_CHECK_EQ(i, 9);
+ ATF_CHECK_STREQ(buf, "number 10");
+}
+
+ATF_TC(snprintf_print_overflow);
+ATF_TC_HEAD(snprintf_print_overflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "checks snprintf print with overflow");
+}
+
+ATF_TC_BODY(snprintf_print_overflow, tc)
+{
+ char buf[10];
+ int i;
+
+ memset(buf, 'x', sizeof(buf));
+ i = snprintf(buf, sizeof(buf), "fjsdfsdjfsdf %d\n", 10);
+ ATF_CHECK_EQ(i, 16);
+ ATF_CHECK_STREQ(buf, "fjsdfsdjf");
+}
+
+ATF_TC(snprintf_count);
+ATF_TC_HEAD(snprintf_count, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "checks snprintf count");
+}
+
+ATF_TC_BODY(snprintf_count, tc)
+{
+ int i;
+
+ i = snprintf(NULL, 20, "number %d", 10);
+ ATF_CHECK_EQ(i, 9);
+}
+
+ATF_TC(snprintf_count_overflow);
+ATF_TC_HEAD(snprintf_count_overflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "checks snprintf count with overflow");
+}
+
+ATF_TC_BODY(snprintf_count_overflow, tc)
+{
+ int i;
+
+ i = snprintf(NULL, 10, "fjsdfsdjfsdf %d\n", 10);
+ ATF_CHECK_EQ(i, 16);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, snprintf_print);
+ ATF_TP_ADD_TC(tp, snprintf_print_overflow);
+ ATF_TP_ADD_TC(tp, snprintf_count);
+ ATF_TP_ADD_TC(tp, snprintf_count_overflow);
+
+ return atf_no_error();
+}
+_EOF
+
+awk '
+/^snprintf\(/ {
+ print prevline
+ out = 1
+}
+{
+ if (out) print
+ else prevline = $0
+}' $1 >>$2
diff --git a/contrib/netbsd-tests/kernel/h_ps_strings1.c b/contrib/netbsd-tests/kernel/h_ps_strings1.c
new file mode 100644
index 0000000..64d8c71
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/h_ps_strings1.c
@@ -0,0 +1,74 @@
+/* $NetBSD: h_ps_strings1.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/exec.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern struct ps_strings *__ps_strings;
+
+int
+main(int argc, char **argv, char **environ)
+{
+ int ret = 0;
+ int nenv;
+
+ if (__ps_strings->ps_nargvstr != argc) {
+ static const char nargv_err[] = "Wrong argc in ps_strings";
+ write(STDOUT_FILENO, nargv_err, sizeof(nargv_err));
+ ret = 1;
+ }
+
+ if (__ps_strings->ps_argvstr != argv) {
+ static const char argv_err[] = "Wrong argv in ps_strings";
+ write(STDOUT_FILENO, argv_err, sizeof(argv_err));
+ ret = 1;
+ }
+
+ if (__ps_strings->ps_envstr != environ) {
+ static const char env_err[] = "Wrong env in ps_strings";
+ write(STDOUT_FILENO, env_err, sizeof(env_err));
+ ret = 1;
+ }
+ nenv = 0;
+ while (environ[nenv])
+ ++nenv;
+ if (__ps_strings->ps_nenvstr != nenv) {
+ static const char nenv_err[] = "Wrong nenv in ps_strings";
+ write(STDOUT_FILENO, nenv_err, sizeof(nenv_err));
+ ret = 1;
+ }
+
+ return ret;
+}
diff --git a/contrib/netbsd-tests/kernel/h_ps_strings2.c b/contrib/netbsd-tests/kernel/h_ps_strings2.c
new file mode 100644
index 0000000..d9c1c24
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/h_ps_strings2.c
@@ -0,0 +1,69 @@
+/* $NetBSD: h_ps_strings2.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/exec.h>
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LEN 16384
+
+extern struct ps_strings *__ps_strings;
+
+int
+main(void)
+{
+ size_t i;
+ char buf[16];
+ char **argv;
+
+ if ((argv = calloc(LEN, sizeof(*argv))) == NULL)
+ errx(1, "calloc failed");
+ for (i = 0; i < LEN; ++i) {
+ snprintf(buf, sizeof(buf), "arg%04zx", i);
+ if ((argv[i] = strdup(buf)) == NULL)
+ errx(1, "strdup failed");
+ }
+ __ps_strings->ps_argvstr = argv;
+ __ps_strings->ps_nargvstr = LEN;
+
+ printf("Sleeping forever...\n");
+ do {
+ sleep(UINT_MAX);
+ } while /* CONSTCOND */ (1);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c
new file mode 100644
index 0000000..5908547
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c
@@ -0,0 +1,98 @@
+/* $NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+#define FIFONAME "fifo"
+
+ATF_TC(fifo);
+ATF_TC_HEAD(fifo, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on fifo");
+}
+ATF_TC_BODY(fifo, tc)
+{
+ int kq, n, fd;
+ struct kevent event[1];
+ char buffer[128];
+
+ RL(mkfifo(FIFONAME, 0644));
+ RL(fd = open(FIFONAME, O_RDWR, 0644));
+
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ /* make sure there is something in the fifo */
+ RL(write(fd, "foo", 3));
+ (void)printf("fifo: wrote 'foo'\n");
+
+ (void)memset(event, 0, sizeof(event));
+
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+
+ (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, "
+ "data: %" PRId64 "\n", n, event[0].filter, event[0].flags,
+ event[0].fflags, event[0].data);
+
+ ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ);
+
+ RL(n = read(fd, buffer, event[0].data));
+ buffer[n] = '\0';
+ (void)printf("fifo: read '%s'\n", buffer);
+
+ RL(close(fd));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, fifo);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c
new file mode 100644
index 0000000..2335172
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c
@@ -0,0 +1,139 @@
+/* $NetBSD: t_file.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_file.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $");
+
+#include <sys/param.h>
+#include <sys/event.h>
+#include <sys/mount.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 <inttypes.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+#define FILENAME "file"
+#define NLINES 5
+
+static void
+child(void)
+{
+ int i, n, fd;
+
+ (void)sleep(1);
+
+ for (i = 0; i < NLINES; ++i) {
+ fd = open(FILENAME, O_WRONLY|O_APPEND, 0644);
+ if (fd < 0)
+ err(EXIT_FAILURE, "open()");
+
+ n = write(fd, "foo\n", 4);
+ if (n < 0)
+ err(EXIT_FAILURE, "write()");
+
+ (void)close(fd);
+ (void)sleep(1);
+ }
+ _exit(0);
+}
+
+ATF_TC(file);
+ATF_TC_HEAD(file, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on regular file");
+}
+ATF_TC_BODY(file, tc)
+{
+ char buffer[128];
+ struct kevent event[1];
+ pid_t pid;
+ int fd, kq, n, num, status;
+
+ RL(pid = fork());
+ if (pid == 0) {
+ child();
+ /* NOTREACHED */
+ }
+
+ RL(fd = open(FILENAME, O_RDONLY|O_CREAT, 0644));
+
+#if 1 /* XXX: why was this disabled? */
+ RL(lseek(fd, 0, SEEK_END));
+#endif
+
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ for (num = 0; num < NLINES;) {
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+ num += n;
+
+ (void)printf("kevent num %d flags: %#x, fflags: %#x, data: "
+ "%" PRId64 "\n", n, event[0].flags, event[0].fflags,
+ event[0].data);
+
+ if (event[0].data < 0)
+#if 1 /* XXXLUKEM */
+ RL(lseek(fd, 0, SEEK_END));
+#else
+ RL(lseek(fd, event[0].data, SEEK_END));
+#endif
+
+ RL(n = read(fd, buffer, 128));
+ buffer[n] = '\0';
+ (void)printf("file(%d): %s", num, buffer);
+ }
+
+ (void)waitpid(pid, &status, 0);
+
+ (void)printf("read: successful end\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, file);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c
new file mode 100644
index 0000000..c77d283
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c
@@ -0,0 +1,79 @@
+/* $NetBSD: t_file2.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_file2.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $");
+
+#include <sys/event.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+ATF_TC(file2);
+ATF_TC_HEAD(file2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_READ for regular files. This test used to "
+ "trigger deadlock caused by problem fixed in revision 1.79.2.10 "
+ "of sys/kern/kern_descrip.c");
+}
+ATF_TC_BODY(file2, tc)
+{
+ int fd1, fd2, kq;
+ struct kevent event[1];
+
+ RL(fd1 = open("afile", O_RDONLY|O_CREAT, 0644));
+ RL(fd2 = open("bfile", O_RDONLY|O_CREAT, 0644));
+
+#if 1 /* XXX: why was this disabled? */
+ RL(lseek(fd1, 0, SEEK_END));
+#endif
+
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fd1, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ RL(dup2(fd2, fd1));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, file2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c
new file mode 100644
index 0000000..d8e05f2
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c
@@ -0,0 +1,84 @@
+/* $NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/event.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+ATF_TC(pipe);
+ATF_TC_HEAD(pipe, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for pipes");
+}
+ATF_TC_BODY(pipe, tc)
+{
+ struct kevent event[1];
+ char buffer[128];
+ int fds[2];
+ int kq, n;
+
+ RL(pipe(fds));
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fds[0], EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ /* make sure there is something in the pipe */
+ RL(write(fds[1], "foo", 3));
+ (void)printf("pipe: wrote 'foo' to pipe\n");
+
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+ (void)printf("kevent num %d flags: %#x, fflags: %#x, data: "
+ "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data);
+
+ RL(n = read(fds[0], buffer, event[0].data));
+ buffer[n] = '\0';
+
+ (void)printf("pipe: read '%s'\n", buffer);
+ (void)printf("pipe: successful end\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pipe);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c
new file mode 100644
index 0000000..3a42fd3
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c
@@ -0,0 +1,144 @@
+/* $NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/wait.h>
+
+#include <poll.h>
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <util.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+static void
+h_check(bool check_master)
+{
+ char slavetty[1024];
+ char buffer[128];
+ struct kevent event[1];
+ pid_t child;
+ int amaster, aslave, acurrent;
+ int kq, n, status;
+#if 0
+ int fl;
+#endif
+ struct pollfd pfd;
+ struct termios tio;
+
+ RL(openpty(&amaster, &aslave, slavetty, NULL, NULL));
+
+ (void)printf("tty: openpty master %d slave %d tty '%s'\n",
+ amaster, aslave, slavetty);
+ acurrent = check_master ? amaster : aslave;
+
+ RL(child = fork());
+ if (child == 0) {
+ sleep(1);
+
+ (void)printf("tty: child writing 'f00\\n'\n");
+ (void)write(check_master ? aslave : amaster, "f00\n", 4);
+
+ _exit(0);
+ }
+
+ /* switch ONLCR off, to not get confused by newline translation */
+ RL(tcgetattr(acurrent, &tio));
+ tio.c_oflag &= ~ONLCR;
+ RL(tcsetattr(acurrent, TCSADRAIN, &tio));
+
+ pfd.fd = acurrent;
+ pfd.events = POLLIN;
+ (void)printf("tty: polling ...\n");
+ RL(poll(&pfd, 1, INFTIM));
+ (void)printf("tty: returned from poll - %d\n", pfd.revents);
+
+#if 0
+ fl = 1;
+ if (ioctl(acurrent, TIOCPKT, &fl) < 0)
+ err(1, "ioctl");
+#endif
+
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], acurrent, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+
+ (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, "
+ "data: %" PRId64 "\n", n, event[0].filter, event[0].flags,
+ event[0].fflags, event[0].data);
+
+ ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ);
+
+ RL(n = read(acurrent, buffer, 128));
+ (void)printf("tty: read '%.*s' (n=%d)\n", n, buffer, n);
+
+ (void)waitpid(child, &status, 0);
+ (void)printf("tty: successful end\n");
+}
+
+ATF_TC(master);
+ATF_TC_HEAD(master, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for master tty");
+}
+ATF_TC_BODY(master, tc)
+{
+ h_check(true);
+}
+
+ATF_TC(slave);
+ATF_TC_HEAD(slave, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for slave tty");
+}
+ATF_TC_BODY(slave, tc)
+{
+ h_check(false);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, master);
+ ATF_TP_ADD_TC(tp, slave);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c
new file mode 100644
index 0000000..8ed5a79
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_ioctl.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ioctl.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/ioctl.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+
+ATF_TC(kfilter_byfilter);
+ATF_TC_HEAD(kfilter_byfilter, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYFILTER ioctl");
+}
+ATF_TC_BODY(kfilter_byfilter, tc)
+{
+ char buf[32];
+ struct kfilter_mapping km;
+ int i, kq;
+
+ RL(kq = kqueue());
+
+ km.name = buf;
+ km.len = sizeof(buf) - 1;
+
+ for (i = 0; i < 7; ++i) {
+ km.filter = i;
+ RL(ioctl(kq, KFILTER_BYFILTER, &km));
+ (void)printf(" map %d -> %s\n", km.filter, km.name);
+ }
+
+ km.filter = 7;
+ ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYFILTER, &km), -1);
+}
+
+ATF_TC(kfilter_byname);
+ATF_TC_HEAD(kfilter_byname, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYNAME ioctl");
+}
+ATF_TC_BODY(kfilter_byname, tc)
+{
+ const char *tests[] = {
+ "EVFILT_READ",
+ "EVFILT_WRITE",
+ "EVFILT_AIO",
+ "EVFILT_VNODE",
+ "EVFILT_PROC",
+ "EVFILT_SIGNAL",
+ "EVFILT_TIMER",
+ NULL
+ };
+ char buf[32];
+ struct kfilter_mapping km;
+ const char **test;
+ int kq;
+
+ RL(kq = kqueue());
+
+ km.name = buf;
+
+ for (test = &tests[0]; *test != NULL; ++test) {
+ (void)strlcpy(buf, *test, sizeof(buf));
+ RL(ioctl(kq, KFILTER_BYNAME, &km));
+ (void)printf(" map %s -> %d\n", km.name, km.filter);
+ }
+
+ (void)strlcpy(buf, "NOTREG_FILTER", sizeof(buf));
+ ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYNAME, &km), -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, kfilter_byfilter);
+ ATF_TP_ADD_TC(tp, kfilter_byname);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc1.c b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c
new file mode 100644
index 0000000..e755309
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c
@@ -0,0 +1,154 @@
+/* $NetBSD: t_proc1.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_proc1.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+/*
+ * this also used to trigger problem fixed in
+ * rev. 1.1.1.1.2.13 of sys/kern/kern_event.c
+ */
+
+#include <sys/param.h>
+#include <sys/event.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+
+static int
+child(void)
+{
+ pid_t ch;
+ int status;
+ char *argv[] = { NULL, NULL };
+ char *envp[] = { NULL, NULL };
+
+ if ((argv[0] = strdup("true")) == NULL)
+ err(EXIT_FAILURE, "strdup(\"true\")");
+
+ if ((envp[0] = strdup("FOO=BAZ")) == NULL)
+ err(EXIT_FAILURE, "strdup(\"FOO=BAZ\")");
+
+ /* Ensure parent is ready */
+ (void)sleep(2);
+
+ /* Do fork */
+ switch (ch = fork()) {
+ case -1:
+ return EXIT_FAILURE;
+ /* NOTREACHED */
+ case 0:
+ return EXIT_SUCCESS;
+ /* NOTREACHED */
+ default:
+ wait(&status);
+ break;
+ }
+
+ /* Exec */
+ execve("/usr/bin/true", argv, envp);
+
+ /* NOTREACHED */
+ return EXIT_FAILURE;
+}
+
+ATF_TC(proc1);
+ATF_TC_HEAD(proc1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_PROC");
+}
+ATF_TC_BODY(proc1, tc)
+{
+ struct kevent event[1];
+ pid_t pid;
+ int kq, want, status;
+
+ RL(kq = kqueue());
+
+ /* fork a child for doing the events */
+ RL(pid = fork());
+ if (pid == 0) {
+ _exit(child());
+ /* NOTREACHED */
+ }
+
+ (void)sleep(1); /* give child some time to come up */
+
+ event[0].ident = pid;
+ event[0].filter = EVFILT_PROC;
+ event[0].flags = EV_ADD | EV_ENABLE;
+ event[0].fflags = NOTE_EXIT | NOTE_FORK | NOTE_EXEC; /* | NOTE_TRACK;*/
+ want = NOTE_EXIT | NOTE_FORK | NOTE_EXEC;
+
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ /* wait until we get all events we want */
+ while (want) {
+ RL(kevent(kq, NULL, 0, event, 1, NULL));
+ printf("%ld:", (long)event[0].ident);
+
+ if (event[0].fflags & NOTE_EXIT) {
+ want &= ~NOTE_EXIT;
+ printf(" NOTE_EXIT");
+ }
+ if (event[0].fflags & NOTE_EXEC) {
+ want &= ~NOTE_EXEC;
+ printf(" NOTE_EXEC");
+ }
+ if (event[0].fflags & NOTE_FORK) {
+ want &= ~NOTE_FORK;
+ printf(" NOTE_FORK");
+ }
+ if (event[0].fflags & NOTE_CHILD)
+ printf(" NOTE_CHILD, parent = %" PRId64, event[0].data);
+
+ printf("\n");
+ }
+
+ (void)waitpid(pid, &status, 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, proc1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc2.c b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c
new file mode 100644
index 0000000..54769d6
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c
@@ -0,0 +1,138 @@
+/* $NetBSD: t_proc2.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Peter Werner <Peter.Werner@wgsn.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_proc2.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+
+static void
+child_two(void)
+{
+ _exit(EXIT_SUCCESS);
+}
+
+static void
+child_one(void)
+{
+ pid_t pid;
+ struct passwd *pwd;
+ const char *nam = "nobody";
+
+ pwd = getpwnam(nam);
+ if (pwd == NULL)
+ err(EXIT_FAILURE, "getpwnam(\"%s\")", nam);
+
+ if ((setuid(pwd->pw_uid)) == -1)
+ err(EXIT_FAILURE, "setuid(%d)", pwd->pw_uid);
+
+ pid = fork();
+ if (pid == -1)
+ err(EXIT_FAILURE, "fork()");
+
+ if (pid == 0)
+ child_two();
+
+ _exit(EXIT_SUCCESS);
+}
+
+ATF_TC(proc2);
+ATF_TC_HEAD(proc2, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_PROC for NOTE_FORK|NOTE_TRACK error path problem "
+ "fixed in rev. 1.1.1.1.2.17 of sys/kern/kern_event.c");
+}
+ATF_TC_BODY(proc2, tc)
+{
+ pid_t pid = 0;
+ int kq, status;
+ struct kevent ke;
+ struct timespec timeout;
+
+ RL(kq = kqueue());
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 0;
+
+ RL(pid = fork());
+ if (pid == 0) {
+ (void)sleep(1); /* let parent set kevent */
+ child_one();
+ /* NOTREACHED */
+ }
+
+ EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_FORK|NOTE_TRACK, 0, 0);
+
+ RL(kevent(kq, &ke, 1, NULL, 0, &timeout));
+
+ (void)sleep(2);
+
+ ke.ident = 0;
+ ke.fflags = 0;
+ ke.flags = EV_ENABLE;
+
+ RL(kevent(kq, NULL, 0, &ke, 1, &timeout));
+ RL(close(kq));
+
+ RL(waitpid(pid, &status, 0));
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS);
+
+ /*
+ * we are expecting an error here as we should not have
+ * been able to add a knote to child 2.
+ */
+ ATF_REQUIRE(ke.fflags & NOTE_TRACKERR);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, proc2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc3.c b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c
new file mode 100644
index 0000000..3cb9ae5
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c
@@ -0,0 +1,99 @@
+/* $NetBSD: t_proc3.c,v 1.1 2012/11/17 21:55:24 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_proc3.c,v 1.1 2012/11/17 21:55:24 joerg Exp $");
+
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+
+ATF_TC(proc3);
+ATF_TC_HEAD(proc3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_PROC for NOTE_TRACK on self bug ");
+}
+
+ATF_TC_BODY(proc3, tc)
+{
+ pid_t pid = 0;
+ int kq, status;
+ struct kevent ke;
+ struct timespec timeout;
+
+ RL(kq = kqueue());
+
+ EV_SET(&ke, getpid(), EVFILT_PROC, EV_ADD, NOTE_TRACK, 0, 0);
+
+ RL(kevent(kq, &ke, 1, NULL, 0, NULL));
+
+ RL(pid = fork());
+ if (pid == 0) {
+ _exit(EXIT_SUCCESS);
+ /* NOTREACHED */
+ }
+
+ RL(waitpid(pid, &status, 0));
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS);
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 0;
+ ke.ident = 0;
+ ke.fflags = 0;
+ ke.flags = EV_ENABLE;
+
+ RL(kevent(kq, NULL, 0, &ke, 1, &timeout));
+ RL(close(kq));
+
+ ATF_REQUIRE(ke.fflags & NOTE_CHILD);
+ ATF_REQUIRE((ke.fflags & NOTE_TRACKERR) == 0);
+ ATF_REQUIRE_EQ((pid_t)ke.ident, pid);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, proc3);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/t_sig.c b/contrib/netbsd-tests/kernel/kqueue/t_sig.c
new file mode 100644
index 0000000..4fc0758
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/t_sig.c
@@ -0,0 +1,133 @@
+/* $NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $");
+
+#include <sys/event.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+
+#define NSIGNALS 5
+
+ATF_TC(sig);
+ATF_TC_HEAD(sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_SIGNAL");
+}
+ATF_TC_BODY(sig, tc)
+{
+ struct timespec timeout;
+ struct kfilter_mapping km;
+ struct kevent event[1];
+ char namebuf[32];
+ pid_t pid, child;
+ int kq, n, num, status;
+
+ pid = getpid();
+ (void)printf("my pid: %d\n", pid);
+
+ /* fork a child to send signals */
+ RL(child = fork());
+ if (child == 0) {
+ int i;
+ (void)sleep(2);
+ for(i = 0; i < NSIGNALS; ++i) {
+ (void)kill(pid, SIGUSR1);
+ (void)sleep(2);
+ }
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ RL(kq = kqueue());
+
+ (void)strlcpy(namebuf, "EVFILT_SIGNAL", sizeof(namebuf));
+ km.name = namebuf;
+ RL(ioctl(kq, KFILTER_BYNAME, &km));
+ (void)printf("got %d as filter number for `%s'.\n", km.filter, km.name);
+
+ /* ignore the signal to avoid taking it for real */
+ REQUIRE_LIBC(signal(SIGUSR1, SIG_IGN), SIG_ERR);
+
+ event[0].ident = SIGUSR1;
+ event[0].filter = km.filter;
+ event[0].flags = EV_ADD | EV_ENABLE;
+
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ (void)sleep(1);
+
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ for (num = 0; num < NSIGNALS; num += n) {
+ struct timeval then, now, diff;
+
+ RL(gettimeofday(&then, NULL));
+ RL(n = kevent(kq, NULL, 0, event, 1, &timeout));
+ RL(gettimeofday(&now, NULL));
+ timersub(&now, &then, &diff);
+
+ (void)printf("sig: kevent returned %d in %lld.%06ld\n",
+ n, (long long)diff.tv_sec, (long)diff.tv_usec);
+
+ if (n == 0)
+ continue;
+
+ (void)printf("sig: kevent flags: 0x%x, data: %" PRId64 " (# "
+ "times signal posted)\n", event[0].flags, event[0].data);
+ }
+
+ (void)waitpid(child, &status, 0);
+ (void)printf("sig: finished successfully\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sig);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c
new file mode 100644
index 0000000..82b256c
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c
@@ -0,0 +1,102 @@
+/* $NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+#define FIFONAME "fifo"
+
+ATF_TC(fifo);
+ATF_TC_HEAD(fifo, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for fifo");
+}
+ATF_TC_BODY(fifo, tc)
+{
+ char buffer[128];
+ struct kevent event[1];
+ pid_t child;
+ int kq, n, fd, status;
+
+ RL(mkfifo(FIFONAME, 0644));
+ RL(fd = open(FIFONAME, O_RDWR, 0644));
+ RL(kq = kqueue());
+
+ /* spawn child reader */
+ RL(child = fork());
+ if (child == 0) {
+ int sz = read(fd, buffer, 128);
+ if (sz > 0)
+ (void)printf("fifo: child read '%.*s'\n", sz, buffer);
+ _exit(sz <= 0);
+ }
+
+ EV_SET(&event[0], fd, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ (void)memset(event, 0, sizeof(event));
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+
+ (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, "
+ "data: %" PRId64 "\n", n, event[0].filter, event[0].flags,
+ event[0].fflags, event[0].data);
+
+ ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE);
+
+ RL(write(fd, "foo", 3));
+ (void)printf("fifo: wrote 'foo'\n");
+ RL(close(fd));
+
+ (void)waitpid(child, &status, 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, fifo);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c
new file mode 100644
index 0000000..459a1f7
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c
@@ -0,0 +1,147 @@
+/* $NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+ATF_TC(pipe1);
+ATF_TC_HEAD(pipe1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_WRITE for pipes. This test used to trigger "
+ "problem fixed in rev. 1.5.2.7 of sys/kern/sys_pipe.c");
+}
+ATF_TC_BODY(pipe1, tc)
+{
+ struct kevent event[1];
+ int fds[2];
+ int kq, n;
+
+ RL(pipe(fds));
+ RL(kq = kqueue());
+ RL(close(fds[0]));
+
+ EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
+ ATF_REQUIRE_EQ_MSG((n = kevent(kq, event, 1, NULL, 0, NULL)),
+ -1, "got: %d", n);
+ ATF_REQUIRE_EQ_MSG(errno, EBADF, "got: %s", strerror(errno));
+}
+
+ATF_TC(pipe2);
+ATF_TC_HEAD(pipe2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_WRITE for pipes. This test used to trigger problem "
+ "fixed in rev. 1.5.2.9 of sys/kern/sys_pipe.c");
+}
+ATF_TC_BODY(pipe2, tc)
+{
+ struct kevent event[1];
+ char buffer[128];
+ int fds[2];
+ int kq, n;
+ int status;
+ pid_t child;
+
+ RL(pipe(fds));
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ /* spawn child reader */
+ RL(child = fork());
+ if (child == 0) {
+ int sz = read(fds[0], buffer, 128);
+ if (sz > 0)
+ (void)printf("pipe: child read '%.*s'\n", sz, buffer);
+ exit(sz <= 0);
+ }
+
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+
+ (void)printf("kevent num %d flags: %#x, fflags: %#x, data: "
+ "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data);
+
+ RL(n = write(fds[1], "foo", 3));
+ RL(close(fds[1]));
+
+ (void)waitpid(child, &status, 0);
+}
+
+ATF_TC(pipe3);
+ATF_TC_HEAD(pipe3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks EVFILT_WRITE for pipes. This test used to trigger problem "
+ "fixed in rev. 1.5.2.10 of sys/kern/sys_pipe.c");
+}
+ATF_TC_BODY(pipe3, tc)
+{
+ struct kevent event[1];
+ int fds[2];
+ int kq;
+
+ RL(pipe(fds));
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ /* close 'read' end first, then 'write' */
+
+ RL(close(fds[0]));
+ RL(close(fds[1]));
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pipe1);
+ ATF_TP_ADD_TC(tp, pipe2);
+ ATF_TP_ADD_TC(tp, pipe3);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c
new file mode 100644
index 0000000..6983910
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c
@@ -0,0 +1,130 @@
+/* $NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:58 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Jaromir Dolecek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:58 jmmv Exp $");
+
+#include <sys/event.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <util.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+static void
+h_check(bool check_master)
+{
+ char slavetty[1024];
+ char buffer[128];
+ struct kevent event[1];
+ struct pollfd pfd;
+ pid_t child;
+ int status, kq, n;
+ int amaster, aslave, acurrent;
+
+ RL(openpty(&amaster, &aslave, slavetty, NULL, NULL));
+ (void)printf("tty: openpty master %d slave %d tty '%s'\n",
+ amaster, aslave, slavetty);
+ acurrent = check_master ? amaster : aslave;
+
+ RL(child = fork());
+ if (child == 0) {
+ (void)sleep(1);
+
+ n = read(check_master ? aslave : amaster, buffer, 128);
+ (void)printf("tty: child read '%.*s'\n", n, buffer);
+
+ _exit(0);
+ }
+
+ pfd.fd = acurrent;
+ pfd.events = POLLOUT;
+ (void)printf("tty: polling ...\n");
+ RL(poll(&pfd, 1, INFTIM));
+ (void)printf("tty: returned from poll - %d\n", pfd.revents);
+
+ RL(kq = kqueue());
+
+ EV_SET(&event[0], acurrent, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
+ RL(kevent(kq, event, 1, NULL, 0, NULL));
+
+ RL(n = kevent(kq, NULL, 0, event, 1, NULL));
+
+ (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, data: "
+ "%" PRId64 "\n", n, event[0].filter, event[0].flags, event[0].fflags,
+ event[0].data);
+
+ ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE);
+
+ RL(n = write(acurrent, "f00\n", 4));
+ (void)printf("tty: wrote 'f00\\n' (wrote %d characters)\n", n);
+
+ (void)waitpid(child, &status, 0);
+ (void)printf("tty: successful end\n");
+}
+
+ATF_TC(master);
+ATF_TC_HEAD(master, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for master tty");
+}
+ATF_TC_BODY(master, tc)
+{
+ h_check(true);
+}
+
+ATF_TC(slave);
+ATF_TC_HEAD(slave, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for slave tty");
+}
+ATF_TC_BODY(slave, tc)
+{
+ h_check(false);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, master);
+ ATF_TP_ADD_TC(tp, slave);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_extattrctl.c b/contrib/netbsd-tests/kernel/t_extattrctl.c
new file mode 100644
index 0000000..2f8932e
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_extattrctl.c
@@ -0,0 +1,28 @@
+#include <sys/types.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <atf-c.h>
+
+ATF_TC(extattrctl_namei);
+ATF_TC_HEAD(extattrctl_namei, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "extattrctl namei safety (kern/43328)");
+}
+
+ATF_TC_BODY(extattrctl_namei, tc)
+{
+
+ rump_init();
+
+ rump_sys_extattrctl("/anyfile", 0, "/", 0, 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, extattrctl_namei);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_extent.c b/contrib/netbsd-tests/kernel/t_extent.c
new file mode 100644
index 0000000..faefafa
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_extent.c
@@ -0,0 +1,385 @@
+/* $NetBSD: t_extent.c,v 1.4 2012/01/27 18:53:10 para Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_extent.c,v 1.4 2012/01/27 18:53:10 para Exp $");
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/extent.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "../h_macros.h"
+
+static int ret;
+static struct extent *ex;
+
+#define h_create(name, start, end, flags) \
+ ATF_REQUIRE((ex = extent_create(name, \
+ start, end, 0, 0, flags)) != NULL);
+
+#define h_alloc_region(start, size) \
+ ATF_REQUIRE_EQ_MSG(ret = extent_alloc_region(ex, \
+ start, size, 0), 0, "%s", strerror(ret));
+
+#define h_free(start, size) \
+ ATF_REQUIRE_EQ_MSG(ret = extent_free(ex, \
+ start, size, 0), 0, "%s", strerror(ret));
+
+static void
+h_alloc_subregion(u_long substart, u_long subend, u_long size,
+ u_long alignment, u_long boundary, int expret, u_long expres)
+{
+ u_long result;
+
+#define FAIL(fmt, ...) \
+ atf_tc_fail("extent_alloc_subregion1(ex, %#lx, %#lx, %#lx, %#lx, 0, " \
+ "%#lx, 0, &result): " fmt, substart, subend, size, alignment, \
+ boundary, ##__VA_ARGS__)
+
+ ret = extent_alloc_subregion1(ex, substart, subend, size,
+ alignment, 0, boundary, 0, &result);
+
+ if (ret != expret)
+ FAIL("%s", strerror(errno));
+
+ if (expret == 0 && result != expres)
+ FAIL("result should be: %#lx, got: %#lx", expres, result);
+#undef FAIL
+}
+
+static void
+h_require(const char *name, u_long start,
+ u_long end, int flags, const char *exp)
+{
+ char buf[4096];
+ struct extent_region *rp;
+ int n = 0;
+
+ ATF_REQUIRE_STREQ_MSG(ex->ex_name, name,
+ "expected: \"%s\", got: \"%s\"", name, ex->ex_name);
+ ATF_REQUIRE_EQ_MSG(ex->ex_start, start,
+ "expected: %#lx, got: %#lx", start, ex->ex_start);
+ ATF_REQUIRE_EQ_MSG(ex->ex_end, end,
+ "expected: %#lx, got: %#lx", end, ex->ex_end);
+ ATF_REQUIRE_EQ_MSG(ex->ex_flags, flags,
+ "expected: %#x, got: %#x", flags, ex->ex_flags);
+
+ (void)memset(buf, 0, sizeof(buf));
+ LIST_FOREACH(rp, &ex->ex_regions, er_link)
+ n += snprintf(buf + n, sizeof(buf) - n,
+ "0x%lx - 0x%lx\n", rp->er_start, rp->er_end);
+
+ if (strcmp(buf, exp) == 0)
+ return;
+
+ printf("Incorrect extent map\n");
+ printf("Expected:\n%s\n", exp);
+ printf("Got:\n%s\n", buf);
+ atf_tc_fail("incorrect extent map");
+}
+
+ATF_TC(coalesce);
+ATF_TC_HEAD(coalesce, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks coalescing of regions");
+}
+ATF_TC_BODY(coalesce, tc)
+{
+ h_create("test1", 0, 0x4f, 0);
+
+ h_alloc_region(0x00, 0x10);
+ h_alloc_region(0x20, 0x10);
+ h_alloc_region(0x40, 0x10);
+ h_alloc_region(0x10, 0x10);
+ h_alloc_subregion(0, 0x4f, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x30);
+
+ h_require("test1", 0x00, 0x4f, 0x00,
+ "0x0 - 0x4f\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(subregion1);
+ATF_TC_HEAD(subregion1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that subregions work (PR kern/7539)");
+}
+ATF_TC_BODY(subregion1, tc)
+{
+ h_create("test2", 0, 0x2f, EX_NOCOALESCE);
+
+ h_alloc_region(0x00, 0x10);
+ h_alloc_subregion(0x20, 0x30, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20);
+
+ h_require("test2", 0x00, 0x2f, 0x2,
+ "0x0 - 0xf\n"
+ "0x20 - 0x2f\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(subregion2);
+ATF_TC_HEAD(subregion2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that subregion allocations don't overlap with existing "
+ "ones (fixed in 1.25)");
+}
+ATF_TC_BODY(subregion2, tc)
+{
+ h_create("test3", 0, 0x3f, EX_NOCOALESCE);
+
+ h_alloc_region(0x00, 0x20);
+ h_alloc_region(0x30, 0x10);
+ h_alloc_subregion(0x10, 0x3f, 0x10,
+ EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20);
+
+ h_require("test3", 0x00, 0x3f, 0x2,
+ "0x0 - 0x1f\n"
+ "0x20 - 0x2f\n"
+ "0x30 - 0x3f\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(bound1);
+ATF_TC_HEAD(bound1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks for overflow in boundary check, before an allocated region "
+ "(fixed in 1.32)");
+}
+ATF_TC_BODY(bound1, tc)
+{
+ h_create("test4", 0xf0000000, 0xffffffff, 0);
+
+ h_alloc_region(0xf1000000, 0x1);
+ h_alloc_subregion(0xf0000000, 0xffffffff, 0x1,
+ EX_NOALIGN, 0x20000000, 0, 0xf0000000);
+
+ h_require("test4", 0xf0000000, 0xffffffff, 0x0,
+ "0xf0000000 - 0xf0000000\n"
+ "0xf1000000 - 0xf1000000\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(bound2);
+ATF_TC_HEAD(bound2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks for overflow in boundary checks, before the subregion end "
+ "(fixed in 1.32)");
+}
+ATF_TC_BODY(bound2, tc)
+{
+ h_create("test5", 0xf0000000, 0xffffffff, 0);
+
+ h_alloc_subregion(0xf0000000, 0xffffffff, 0x1,
+ EX_NOALIGN, 0x20000000, 0, 0xf0000000);
+
+ h_require("test5", 0xf0000000, 0xffffffff, 0x0,
+ "0xf0000000 - 0xf0000000\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(bound3);
+ATF_TC_HEAD(bound3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks allocation beyond last boundary line: last two "
+ "allocations should succeed without boundary \"fixups\"");
+}
+ATF_TC_BODY(bound3, tc)
+{
+ h_create("test6", 0, 11, 0);
+
+ h_alloc_subregion(0, 11, 8, EX_NOALIGN, 8, 0, 0);
+ h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0x8);
+ h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0xa);
+
+ h_require("test6", 0x0, 0xb, 0x0, "0x0 - 0xb\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(bound4);
+ATF_TC_HEAD(bound4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks allocation beyond last boundary line: last allocation "
+ "should be bumped to the next boundary and exactly fit the "
+ "remaining space");
+}
+ATF_TC_BODY(bound4, tc)
+{
+ h_create("test7", 0, 11, 0);
+
+ h_alloc_subregion(0, 11, 7, EX_NOALIGN, 8, 0, 0);
+ h_alloc_subregion(0, 11, 4, EX_NOALIGN, 8, 0, 8);
+
+ h_require("test7", 0x0, 0xb, 0x0,
+ "0x0 - 0x6\n"
+ "0x8 - 0xb\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(subregion3);
+ATF_TC_HEAD(subregion3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that we don't allocate a region pasts the end of "
+ "subregion (i.e., the second alloc_subregion should fail). "
+ "subr_extent.c prior to rev. 1.43 allocated region starting "
+ "from 0x10");
+}
+ATF_TC_BODY(subregion3, tc)
+{
+ h_create("test8", 0, 0x4f, EX_NOCOALESCE);
+
+ h_alloc_region(0x30, 0x10);
+ h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0);
+ h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0);
+
+ h_require("test8", 0x0, 0x4f, 0x2,
+ "0x0 - 0xf\n"
+ "0x30 - 0x3f\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(bound5);
+ATF_TC_HEAD(bound5, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "When allocating a region with a boundary constraint, checks "
+ "proper detection of overflaps once the candidate region has "
+ "been aligned. subr_extent.c prior 1.45 could corrupt the extent "
+ "map in this situation");
+}
+ATF_TC_BODY(bound5, tc)
+{
+ h_create("test9", 0, 0x4f, 0);
+
+ h_alloc_subregion(0, 0x10, 4, EX_NOALIGN, 0, 0, 0);
+ h_alloc_subregion(0xd, 0x20, 2, EX_NOALIGN, 0, 0, 0xd);
+ h_alloc_subregion(0, 0x4f, 8, EX_NOALIGN, 8, 0, 0x10);
+
+ h_require("test9", 0x0, 0x4f, 0x0,
+ "0x0 - 0x3\n"
+ "0xd - 0xe\n"
+ "0x10 - 0x17\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(free);
+ATF_TC_HEAD(free, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks extent_free()");
+}
+ATF_TC_BODY(free, tc)
+{
+ h_create("test10", 0xc0002000, 0xffffe000, EX_BOUNDZERO);
+
+ h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000,
+ 0x10000, 0x10000, 0, 0xc0010000);
+ h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000,
+ 0x10000, 0x10000, 0, 0xc0020000);
+
+ h_require("test10", 0xc0002000, 0xffffe000, 0x0,
+ "0xc0010000 - 0xc0011fff\n"
+ "0xc0020000 - 0xc0021fff\n");
+
+ h_free(0xc0020000, 0x2000);
+ h_require("test10", 0xc0002000, 0xffffe000, 0x0,
+ "0xc0010000 - 0xc0011fff\n");
+
+ h_alloc_subregion(0xc0002000, 0xffffe000, 0x10000,
+ 0x10000, 0x10000, 0, 0xc0022000);
+
+ h_require("test10", 0xc0002000, 0xffffe000, 0x0,
+ "0xc0010000 - 0xc0011fff\n"
+ "0xc0022000 - 0xc0031fff\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TC(subregion4);
+ATF_TC_HEAD(subregion4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks for off-by-one bug which would cause a region at the end "
+ "of the extent to be allocated multiple times (fixed in 1.51)");
+}
+ATF_TC_BODY(subregion4, tc)
+{
+ h_create("test11", 0x10, 0x20, EX_NOCOALESCE);
+
+ h_alloc_subregion(0x10, 0x13, 0x4, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x10);
+ h_alloc_subregion(0x1e, 0x1f, 0x2, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x1e);
+ h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20);
+ h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0);
+ h_alloc_subregion(0x10, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x14);
+
+ h_require("test11", 0x10, 0x20, 0x2,
+ "0x10 - 0x13\n"
+ "0x14 - 0x14\n"
+ "0x1e - 0x1f\n"
+ "0x20 - 0x20\n");
+
+ extent_destroy(ex);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, coalesce);
+ ATF_TP_ADD_TC(tp, subregion1);
+ ATF_TP_ADD_TC(tp, subregion2);
+ ATF_TP_ADD_TC(tp, bound1);
+ ATF_TP_ADD_TC(tp, bound2);
+ ATF_TP_ADD_TC(tp, bound3);
+ ATF_TP_ADD_TC(tp, bound4);
+ ATF_TP_ADD_TC(tp, subregion3);
+ ATF_TP_ADD_TC(tp, bound5);
+ ATF_TP_ADD_TC(tp, free);
+ ATF_TP_ADD_TC(tp, subregion4);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_filedesc.c b/contrib/netbsd-tests/kernel/t_filedesc.c
new file mode 100644
index 0000000..6b367ee
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_filedesc.c
@@ -0,0 +1,108 @@
+/* $NetBSD: t_filedesc.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_filedesc.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $");
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <atf-c.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include "../h_macros.h"
+
+ATF_TC(getfilerace);
+ATF_TC_HEAD(getfilerace, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "race between multithreaded proc. "
+ "fd_getfile() and fd_close() (PR kern/43694)");
+}
+
+static int fd;
+static volatile bool quit;
+
+static void *
+wrkwrk(void *arg)
+{
+
+ /* just something to cause fd_getfile() to be called */
+ while (!quit)
+ rump_sys_write(fd, &fd, sizeof(fd));
+
+ return NULL;
+}
+
+/* for me, 1000 triggers extremely seldom, 10k sometimes, 100k almost always */
+#define DEFAULT_ITERATIONS 10000
+
+ATF_TC_BODY(getfilerace, tc)
+{
+ pthread_t pt;
+ int fd_wrk;
+ int i, iters;
+
+ /*
+ * Want a multiprocessor virtual kernel. A multiprocessor host
+ * probably helps too, but that's harder to do in software...
+ */
+ setenv("RUMP_NCPU", "2", 1);
+ rump_init();
+
+ fd = fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0);
+ if (fd == -1)
+ atf_tc_fail_errno("cannot open /dev/null");
+
+ if (atf_tc_has_config_var(tc, "iters"))
+ iters = atoi(atf_tc_get_config_var(tc, "iters"));
+ else
+ iters = DEFAULT_ITERATIONS;
+
+ pthread_create(&pt, NULL, wrkwrk, NULL);
+ for (i = 0; i < iters; i++) {
+ rump_sys_close(fd_wrk);
+ fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0);
+ assert(fd == fd_wrk);
+ }
+
+ quit = true;
+ pthread_join(pt, NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, getfilerace);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c
new file mode 100644
index 0000000..f54b289
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2013\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_kauth_pr_47598.c,v 1.3 2014/04/28 08:34:16 martin Exp $");
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <atf-c.h>
+
+/*
+ * helper function
+ */
+static const char curtain_name[] = "security.models.bsd44.curtain";
+static const char securelevel_name[] = "security.models.bsd44.securelevel";
+
+static bool may_lower_curtain(void);
+static int get_curtain(void);
+static void set_curtain(int newval);
+
+static bool
+may_lower_curtain(void)
+{
+ int seclevel;
+ size_t len = sizeof(seclevel);
+
+ if (sysctlbyname(securelevel_name, &seclevel, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read %s", securelevel_name);
+
+ return seclevel <= 0;
+}
+
+static int
+get_curtain(void)
+{
+ int curtain;
+ size_t len = sizeof(curtain);
+
+ if (sysctlbyname(curtain_name, &curtain, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read %s", curtain_name);
+
+ return curtain;
+}
+
+static void
+set_curtain(int newval)
+{
+
+ if (sysctlbyname(curtain_name, NULL, 0, &newval, sizeof(newval)) != 0)
+ atf_tc_fail("failed to set %s to %d", curtain_name, newval);
+}
+
+/*
+ * PR kern/47598: if security.models.extensions.curtain = 1 we crash when
+ * doing a netstat while an embryonic (not yet fully accepted) connection
+ * exists.
+ * This has been fixed with rev. 1.5 of
+ * src/sys/secmodel/extensions/secmodel_extensions.c.
+ */
+
+
+ATF_TC(kauth_curtain);
+ATF_TC_HEAD(kauth_curtain, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+ atf_tc_set_md_var(tc, "require.progs", "netstat");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks for kernel crash with curtain active (PR kern/47598)");
+}
+
+ATF_TC_BODY(kauth_curtain, tc)
+{
+
+ int old_curtain, s, s2, err;
+ socklen_t slen;
+ struct sockaddr_in sa;
+
+ /*
+ * save old value of "curtain" and enable it
+ */
+ old_curtain = get_curtain();
+ if (old_curtain < 1 && !may_lower_curtain())
+ atf_tc_skip("curtain is not enabled and we would not be able"
+ " to drop it later due to securelevel settings");
+
+ set_curtain(1);
+
+ /*
+ * create a socket and bind it to some arbitray free port
+ */
+ s = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
+ ATF_REQUIRE(s != -1);
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_len = sizeof(sa);
+ sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+ ATF_REQUIRE(bind(s, (struct sockaddr *)&sa, sizeof(sa))==0);
+ ATF_REQUIRE(listen(s, 16)==0);
+
+ /*
+ * extract address and open a connection to the port
+ */
+ slen = sizeof(sa);
+ ATF_REQUIRE(getsockname(s, (struct sockaddr *)&sa, &slen)==0);
+ s2 = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
+ ATF_REQUIRE(s2 != -1);
+ printf("port is %d\n", ntohs(sa.sin_port));
+ err = connect(s2, (struct sockaddr *)&sa, sizeof(sa));
+ ATF_REQUIRE_MSG(err == -1 && errno == EINPROGRESS,
+ "conect returned %d with errno %d", err, errno);
+ fflush(stdout);
+ fflush(stderr);
+
+ /*
+ * we now have a pending, not yet accepted connection - run netstat
+ */
+ system("netstat -aA");
+
+ /*
+ * cleanup
+ */
+ close(s2);
+ close(s);
+
+ /*
+ * restore old value of curtain
+ */
+ set_curtain(old_curtain);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, kauth_curtain);
+
+ return atf_no_error();
+}
+
+
diff --git a/contrib/netbsd-tests/kernel/t_lock.c b/contrib/netbsd-tests/kernel/t_lock.c
new file mode 100644
index 0000000..3704afb
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_lock.c
@@ -0,0 +1,87 @@
+/* $NetBSD: t_lock.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_lock.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $");
+
+#include <sys/time.h>
+
+#include <machine/lock.h>
+#include <signal.h>
+
+#include <atf-c.h>
+
+#include "../h_macros.h"
+
+__cpu_simple_lock_t lk;
+volatile int handled = 0;
+
+static void
+handler(int sig)
+{
+ handled = 1;
+ __cpu_simple_unlock(&lk);
+}
+
+ATF_TC(lock);
+ATF_TC_HEAD(lock, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "3");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks __cpu_simple_lock()/__cpu_simple_unlock()");
+}
+ATF_TC_BODY(lock, tc)
+{
+ struct itimerval itv;
+
+ __cpu_simple_lock_init(&lk);
+
+ REQUIRE_LIBC(signal(SIGVTALRM, handler), SIG_ERR);
+
+ itv.it_interval.tv_sec = 0;
+ itv.it_interval.tv_usec = 0;
+ itv.it_value.tv_sec = 1;
+ itv.it_value.tv_usec = 0;
+ RL(setitimer(ITIMER_VIRTUAL, &itv, NULL));
+
+ __cpu_simple_lock(&lk);
+ __cpu_simple_lock(&lk);
+
+ ATF_REQUIRE(handled);
+
+ __cpu_simple_unlock(&lk);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, lock);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_lockf.c b/contrib/netbsd-tests/kernel/t_lockf.c
new file mode 100644
index 0000000..d937301
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_lockf.c
@@ -0,0 +1,262 @@
+/* $NetBSD: t_lockf.c,v 1.9 2013/10/19 17:45:00 christos Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+
+/*
+ * lockf1 regression test:
+ *
+ * Tests:
+ * Fork N child processes, each of which gets M random byte range locks
+ * on a common file. We ignore all lock errors (practically speaking,
+ * this means EDEADLK or ENOLOCK), but we make numerous passes over all
+ * the children to make sure that they are still awake. (We do this by
+ * verifying that we can ptrace(ATTACH/DETACH) to the children and get
+ * their status via waitpid().)
+ * When finished, reap all the children.
+ */
+
+#define nlocks 500 /* number of locks per thread */
+#define nprocs 10 /* number of processes to spawn */
+#define npasses 50 /* number of passes to make over the children */
+#define sleeptime 150000 /* sleep time between locks, usec */
+#define filesize 8192 /* size of file to lock */
+
+const char *lockfile = "lockf_test";
+
+static u_int32_t
+random_uint32(void)
+{
+ return lrand48();
+}
+
+static void
+trylocks(int id)
+{
+ int i, fd;
+
+ srand48(getpid());
+
+ fd = open (lockfile, O_RDWR, 0);
+
+ if (fd < 0)
+ err(1, "%s", lockfile);
+
+ printf("%d: start\n", id);
+
+ for (i = 0; i < nlocks; i++) {
+ struct flock fl;
+
+ fl.l_start = random_uint32() % filesize;
+ fl.l_len = random_uint32() % filesize;
+ switch (random_uint32() % 3) {
+ case 0:
+ fl.l_type = F_RDLCK;
+ break;
+ case 1:
+ fl.l_type = F_WRLCK;
+ break;
+ case 2:
+ fl.l_type = F_UNLCK;
+ break;
+ }
+ fl.l_whence = SEEK_SET;
+
+ (void)fcntl(fd, F_SETLKW, &fl);
+
+ if (usleep(sleeptime) < 0)
+ err(1, "usleep");
+ }
+ printf("%d: done\n", id);
+ close (fd);
+}
+
+ATF_TC(randlock);
+ATF_TC_HEAD(randlock, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "300");
+ atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) locking");
+}
+
+ATF_TC_BODY(randlock, tc)
+{
+ int i, j, fd;
+ int pipe_fd[2];
+ pid_t *pid;
+ int status;
+ char pipe_in, pipe_out;
+ const char pipe_errmsg[] = "child: pipe write failed\n";
+
+ (void)unlink(lockfile);
+
+ fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666);
+ ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno));
+
+ ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0,
+ "ftruncate(%s): %s", lockfile, strerror(errno));
+
+ ATF_REQUIRE_MSG(pipe(pipe_fd) == 0, "pipe: %s", strerror(errno));
+
+ fsync(fd);
+ close(fd);
+
+ pid = malloc(nprocs * sizeof(pid_t));
+
+ for (i = 0; i < nprocs; i++) {
+ pipe_out = (char)('A' + i);
+ pid[i] = fork();
+ switch (pid[i]) {
+ case 0:
+ if (write(pipe_fd[1], &pipe_out, 1) != 1)
+ write(STDERR_FILENO, pipe_errmsg,
+ __arraycount(pipe_errmsg) - 1);
+ else
+ trylocks(i);
+ _exit(0);
+ break;
+ case -1:
+ atf_tc_fail("fork %d failed", i);
+ break;
+ default:
+ ATF_REQUIRE_MSG(read(pipe_fd[0], &pipe_in, 1) == 1,
+ "parent: read_pipe(%i): %s", i, strerror(errno));
+ ATF_REQUIRE_MSG(pipe_in == pipe_out,
+ "parent: pipe does not match");
+ break;
+ }
+ }
+ for (j = 0; j < npasses; j++) {
+ printf("parent: run %i\n", j+1);
+ for (i = 0; i < nprocs; i++) {
+ ATF_REQUIRE_MSG(ptrace(PT_ATTACH, pid[i], 0, 0) >= 0,
+ "ptrace attach %d", pid[i]);
+ ATF_REQUIRE_MSG(waitpid(pid[i], &status, WUNTRACED) >= 0,
+ "waitpid(ptrace)");
+ usleep(sleeptime / 3);
+ ATF_REQUIRE_MSG(ptrace(PT_DETACH, pid[i], (caddr_t)1,
+ 0) >= 0,
+ "ptrace detach %d", pid[i]);
+ usleep(sleeptime / 3);
+ }
+ }
+ for (i = 0; i < nprocs; i++) {
+ printf("reap %d: ", i);
+ fflush(stdout);
+ kill(pid[i], SIGINT);
+ waitpid(pid[i], &status, 0);
+ printf(" status %d\n", status);
+ }
+ atf_tc_pass();
+}
+
+static int
+dolock(int fd, int op, off_t lk_off, off_t lk_size)
+{
+ off_t result;
+ int ret;
+
+ result = lseek(fd, lk_off, SEEK_SET);
+ if (result == -1) {
+ return errno;
+ }
+ ATF_REQUIRE_MSG(result == lk_off, "lseek to wrong offset");
+ ret = lockf(fd, op, lk_size);
+ if (ret == -1) {
+ return errno;
+ }
+ return 0;
+}
+
+ATF_TC(deadlock);
+ATF_TC_HEAD(deadlock, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "30");
+ atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) deadlock detection");
+}
+
+ATF_TC_BODY(deadlock, tc)
+{
+ int fd;
+ int error;
+ int ret;
+ pid_t pid;
+
+ (void)unlink(lockfile);
+
+ fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666);
+ ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno));
+
+ ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0,
+ "ftruncate(%s): %s", lockfile, strerror(errno));
+
+ fsync(fd);
+
+ error = dolock(fd, F_LOCK, 0, 1);
+ ATF_REQUIRE_MSG(error == 0, "initial dolock: %s", strerror(errno));
+
+ pid = fork();
+ ATF_REQUIRE_MSG(pid != -1, "fork failed: %s", strerror(errno));
+ if (pid == 0) {
+ error = dolock(fd, F_LOCK, 1, 1);
+ ATF_REQUIRE_MSG(error == 0, "child dolock: %s",
+ strerror(errno));
+ dolock(fd, F_LOCK, 0, 1); /* will block */
+ atf_tc_fail("child did not block");
+ }
+ sleep(1); /* give child time to grab its lock then block */
+
+ error = dolock(fd, F_LOCK, 1, 1);
+ ATF_REQUIRE_MSG(error == EDEADLK, "parent did not detect deadlock: %s",
+ strerror(errno));
+ ret = kill(pid, SIGKILL);
+ ATF_REQUIRE_MSG(ret != -1, "failed to kill child: %s", strerror(errno));
+
+ atf_tc_pass();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, randlock);
+ ATF_TP_ADD_TC(tp, deadlock);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_mqueue.c b/contrib/netbsd-tests/kernel/t_mqueue.c
new file mode 100644
index 0000000..2a03101
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_mqueue.c
@@ -0,0 +1,137 @@
+/* $NetBSD: t_mqueue.c,v 1.4 2014/03/02 19:56:48 jmmv Exp $ */
+
+/*
+ * Test for POSIX message queue priority handling.
+ *
+ * This file is in the Public Domain.
+ */
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <mqueue.h>
+
+#define MQ_PRIO_BASE 24
+
+static void
+send_msgs(mqd_t mqfd)
+{
+ char msg[2];
+
+ msg[1] = '\0';
+
+ msg[0] = 'a';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
+ "mq_send 1 failed: %d", errno);
+
+ msg[0] = 'b';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
+ "mq_send 2 failed: %d", errno);
+
+ msg[0] = 'c';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
+ "mq_send 3 failed: %d", errno);
+
+ msg[0] = 'd';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1,
+ "mq_send 4 failed: %d", errno);
+
+ msg[0] = 'e';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1,
+ "mq_send 5 failed: %d", errno);
+
+ msg[0] = 'f';
+ ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
+ "mq_send 6 failed: %d", errno);
+}
+
+static void
+receive_msgs(mqd_t mqfd)
+{
+ struct mq_attr mqa;
+ char *m;
+ unsigned p;
+ int len;
+
+ ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d",
+ errno);
+
+ len = mqa.mq_msgsize;
+ m = calloc(1, len);
+ ATF_REQUIRE_MSG(m != NULL, "calloc failed");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 1 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b',
+ "mq_receive 1 prio/data mismatch");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 2 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f',
+ "mq_receive 2 prio/data mismatch");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 3 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a',
+ "mq_receive 3 prio/data mismatch");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 4 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c',
+ "mq_receive 4 prio/data mismatch");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 5 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd',
+ "mq_receive 5 prio/data mismatch");
+
+ ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
+ "mq_receive 6 failed: %d", errno);
+ ATF_REQUIRE_MSG(p == 0 && m[0] == 'e',
+ "mq_receive 6 prio/data mismatch");
+}
+
+ATF_TC(mqueue);
+ATF_TC_HEAD(mqueue, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "3");
+ atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive");
+}
+
+ATF_TC_BODY(mqueue, tc)
+{
+ int status;
+ char *tmpdir;
+ char template[32];
+ char mq_name[64];
+
+ strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template));
+ tmpdir = mkdtemp(template);
+ ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno);
+ snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir);
+
+ mqd_t mqfd;
+
+ mqfd = mq_open(mq_name, O_RDWR | O_CREAT,
+ S_IRUSR | S_IRWXG | S_IROTH, NULL);
+ ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno);
+
+ send_msgs(mqfd);
+ receive_msgs(mqfd);
+
+ status = mq_close(mqfd);
+ ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mqueue);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_ps_strings.sh b/contrib/netbsd-tests/kernel/t_ps_strings.sh
new file mode 100755
index 0000000..8adba54
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_ps_strings.sh
@@ -0,0 +1,85 @@
+# $NetBSD: t_ps_strings.sh,v 1.1 2011/03/05 18:14:33 pgoyette Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case validate
+validate_head()
+{
+ atf_set "descr" "Validates ps_strings passed to program"
+}
+validate_body()
+{
+ atf_check -s exit:0 -o ignore -e ignore \
+ $(atf_get_srcdir)/h_ps_strings1
+}
+
+# Function to parse and validate the output from ps
+
+parse_ps() {
+ local pid seq arg
+
+ pid="$1" ; shift
+
+ while [ "$1" != "$pid" ] ; do
+ echo $1
+ shift
+ done
+ if [ $# -eq 0 ] ; then
+ echo "NO_PID"
+ return
+ fi
+ shift
+
+ seq=0
+ while [ $# -gt 1 ] ; do
+ arg=$(printf "arg%04x" $seq)
+ if [ "$arg" != "$1" ] ; then
+ echo BAD_$seq
+ return
+ fi
+ shift
+ done
+ echo "OK"
+}
+
+atf_test_case update
+update_head()
+{
+ atf_set "descr" "Check updating of ps_strings"
+}
+update_body()
+{
+ $(atf_get_srcdir)/h_ps_strings2 > /dev/null 2>&1 &
+ h_pid=$!
+ parse=$(parse_ps $h_pid $(ps -wwo pid,args -p $h_pid) )
+ kill $h_pid
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case validate
+ atf_add_test_case update
+}
diff --git a/contrib/netbsd-tests/kernel/t_pty.c b/contrib/netbsd-tests/kernel/t_pty.c
new file mode 100644
index 0000000..fccfc17b
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_pty.c
@@ -0,0 +1,351 @@
+/* $Id: t_pty.c,v 1.1 2011/09/24 15:53:01 christos Exp $ */
+
+/*
+ * Allocates a pty(4) device, and sends the specified number of packets of the
+ * specified length though it, while a child reader process reads and reports
+ * results.
+ *
+ * Written by Matthew Mondor
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_pty.c,v 1.1 2011/09/24 15:53:01 christos Exp $");
+
+#include <errno.h>
+#include <err.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#ifdef __linux__
+#define _XOPEN_SOURCE
+#define __USE_XOPEN
+#endif
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifdef STANDALONE
+static __dead void usage(const char *);
+static void parse_args(int, char **);
+#else
+#include <atf-c.h>
+#include "../h_macros.h"
+#endif
+
+static int pty_open(void);
+static int tty_open(const char *);
+static void fd_nonblock(int);
+static pid_t child_spawn(const char *);
+static void run(void);
+
+static size_t buffer_size = 4096;
+static size_t packets = 2;
+static uint8_t *dbuf;
+static int verbose;
+static int qsize;
+
+
+static
+void run(void)
+{
+ size_t i;
+ int pty;
+ int status;
+ pid_t child;
+ if ((dbuf = calloc(1, buffer_size)) == NULL)
+ err(EXIT_FAILURE, "malloc(%zu)", buffer_size);
+
+ if (verbose)
+ (void)printf(
+ "parent: started; opening PTY and spawning child\n");
+ pty = pty_open();
+ child = child_spawn(ptsname(pty));
+ if (verbose)
+ (void)printf("parent: sleeping to make sure child is ready\n");
+ (void)sleep(1);
+
+ for (i = 0; i < buffer_size; i++)
+ dbuf[i] = i & 0xff;
+
+ if (verbose)
+ (void)printf("parent: writing\n");
+
+ for (i = 0; i < packets; i++) {
+ ssize_t size;
+
+ if (verbose)
+ (void)printf(
+ "parent: attempting to write %zu bytes to PTY\n",
+ buffer_size);
+ if ((size = write(pty, dbuf, buffer_size)) == -1) {
+ err(EXIT_FAILURE, "parent: write()");
+ break;
+ }
+ if (verbose)
+ (void)printf("parent: wrote %zd bytes to PTY\n", size);
+ }
+
+ if (verbose)
+ (void)printf("parent: waiting for child to exit\n");
+ if (waitpid(child, &status, 0) == -1)
+ err(EXIT_FAILURE, "waitpid");
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ errx(EXIT_FAILURE, "child failed");
+
+ if (verbose)
+ (void)printf("parent: closing PTY\n");
+ (void)close(pty);
+ if (verbose)
+ (void)printf("parent: exiting\n");
+}
+
+static void
+condition(int fd)
+{
+ struct termios tios;
+
+ if (qsize) {
+ int opt = qsize;
+ if (ioctl(fd, TIOCSQSIZE, &opt) == -1)
+ err(EXIT_FAILURE, "Couldn't set tty(4) buffer size");
+ if (ioctl(fd, TIOCGQSIZE, &opt) == -1)
+ err(EXIT_FAILURE, "Couldn't get tty(4) buffer size");
+ if (opt != qsize)
+ errx(EXIT_FAILURE, "Wrong qsize %d != %d\n",
+ qsize, opt);
+ }
+ if (tcgetattr(fd, &tios) == -1)
+ err(EXIT_FAILURE, "tcgetattr()");
+ cfmakeraw(&tios);
+ cfsetspeed(&tios, B921600);
+ if (tcsetattr(fd, TCSANOW, &tios) == -1)
+ err(EXIT_FAILURE, "tcsetattr()");
+}
+
+static int
+pty_open(void)
+{
+ int fd;
+
+ if ((fd = posix_openpt(O_RDWR)) == -1)
+ err(EXIT_FAILURE, "Couldn't pty(4) device");
+ condition(fd);
+ if (grantpt(fd) == -1)
+ err(EXIT_FAILURE,
+ "Couldn't grant permissions on tty(4) device");
+
+
+ condition(fd);
+
+ if (unlockpt(fd) == -1)
+ err(EXIT_FAILURE, "unlockpt()");
+
+ return fd;
+}
+
+static int
+tty_open(const char *ttydev)
+{
+ int fd;
+
+ if ((fd = open(ttydev, O_RDWR, 0)) == -1)
+ err(EXIT_FAILURE, "Couldn't open tty(4) device");
+
+#ifdef USE_PPP_DISCIPLINE
+ {
+ int opt = PPPDISC;
+ if (ioctl(fd, TIOCSETD, &opt) == -1)
+ err(EXIT_FAILURE,
+ "Couldn't set tty(4) discipline to PPP");
+ }
+#endif
+
+ condition(fd);
+
+ return fd;
+}
+
+static void
+fd_nonblock(int fd)
+{
+ int opt;
+
+ if ((opt = fcntl(fd, F_GETFL, NULL)) == -1)
+ err(EXIT_FAILURE, "fcntl()");
+ if (fcntl(fd, F_SETFL, opt | O_NONBLOCK) == -1)
+ err(EXIT_FAILURE, "fcntl()");
+}
+
+static pid_t
+child_spawn(const char *ttydev)
+{
+ pid_t pid;
+ int tty;
+ struct pollfd pfd;
+ size_t total = 0;
+
+ if ((pid = fork()) == -1)
+ err(EXIT_FAILURE, "fork()");
+ (void)setsid();
+ if (pid != 0)
+ return pid;
+
+ if (verbose)
+ (void)printf("child: started; open \"%s\"\n", ttydev);
+ tty = tty_open(ttydev);
+ fd_nonblock(tty);
+
+ if (verbose)
+ (void)printf("child: TTY open, starting read loop\n");
+ pfd.fd = tty;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ for (;;) {
+ int ret;
+ ssize_t size;
+
+ if (verbose)
+ (void)printf("child: polling\n");
+ if ((ret = poll(&pfd, 1, 2000)) == -1)
+ err(EXIT_FAILURE, "child: poll()");
+ if (ret == 0)
+ break;
+ if ((pfd.revents & POLLERR) != 0)
+ break;
+ if ((pfd.revents & POLLIN) != 0) {
+ for (;;) {
+ if (verbose)
+ (void)printf(
+ "child: attempting to read %zu"
+ " bytes\n", buffer_size);
+ if ((size = read(tty, dbuf, buffer_size))
+ == -1) {
+ if (errno == EAGAIN)
+ break;
+ err(EXIT_FAILURE, "child: read()");
+ }
+ if (qsize && size < qsize &&
+ (size_t)size < buffer_size)
+ errx(EXIT_FAILURE, "read returned %zd "
+ "less than the queue size %d",
+ size, qsize);
+ if (verbose)
+ (void)printf(
+ "child: read %zd bytes from TTY\n",
+ size);
+ if (size == 0)
+ goto end;
+ total += size;
+ }
+ }
+ }
+end:
+ if (verbose)
+ (void)printf("child: closing TTY %zu\n", total);
+ (void)close(tty);
+ if (verbose)
+ (void)printf("child: exiting\n");
+ if (total != buffer_size * packets)
+ errx(EXIT_FAILURE,
+ "Lost data %zu != %zu\n", total, buffer_size * packets);
+
+ exit(EXIT_SUCCESS);
+}
+
+#ifdef STANDALONE
+static void
+usage(const char *msg)
+{
+
+ if (msg != NULL)
+ (void) fprintf(stderr, "\n%s\n\n", msg);
+
+ (void)fprintf(stderr,
+ "Usage: %s [-v] [-q <qsize>] [-s <packetsize>] [-n <packets>]\n",
+ getprogname());
+
+ exit(EXIT_FAILURE);
+}
+
+static void
+parse_args(int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "n:q:s:v")) != -1) {
+ switch (ch) {
+ case 'n':
+ packets = (size_t)atoi(optarg);
+ break;
+ case 'q':
+ qsize = atoi(optarg);
+ break;
+ case 's':
+ buffer_size = (size_t)atoi(optarg);
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ usage(NULL);
+ break;
+ }
+ }
+ if (buffer_size < 0 || buffer_size > 65536)
+ usage("-s must be between 0 and 65536");
+ if (packets < 1 || packets > 100)
+ usage("-p must be between 1 and 100");
+}
+
+int
+main(int argc, char **argv)
+{
+
+ parse_args(argc, argv);
+ run();
+ exit(EXIT_SUCCESS);
+}
+
+#else
+ATF_TC(pty_no_queue);
+
+ATF_TC_HEAD(pty_no_queue, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that writing to pty "
+ "does not lose data with the default queue size of 1024");
+}
+
+ATF_TC_BODY(pty_no_queue, tc)
+{
+ qsize = 0;
+ run();
+}
+
+ATF_TC(pty_queue);
+
+ATF_TC_HEAD(pty_queue, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that writing to pty "
+ "does not lose data with the a queue size of 4096");
+}
+
+ATF_TC_BODY(pty_queue, tc)
+{
+ qsize = 4096;
+ run();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pty_no_queue);
+ ATF_TP_ADD_TC(tp, pty_queue);
+
+ return atf_no_error();
+}
+#endif
diff --git a/contrib/netbsd-tests/kernel/t_rnd.c b/contrib/netbsd-tests/kernel/t_rnd.c
new file mode 100644
index 0000000..7f1f288
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_rnd.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_rnd.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $ */
+
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_rnd.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $");
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/rnd.h>
+
+#include <atf-c.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include "../h_macros.h"
+
+ATF_TC(RNDADDDATA);
+ATF_TC_HEAD(RNDADDDATA, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks ioctl(RNDADDDATA) (PR kern/42020)");
+}
+
+/* Adapted from example provided by Juho Salminen in the noted PR. */
+ATF_TC_BODY(RNDADDDATA, tc)
+{
+ rnddata_t rd;
+ int fd;
+
+ rump_init();
+ fd = rump_sys_open("/dev/random", O_RDWR, 0);
+ if (fd == -1)
+ atf_tc_fail_errno("cannot open /dev/random");
+
+ rd.entropy = 1;
+ rd.len = 1;
+ if (rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1)
+ atf_tc_fail_errno("RNDADDDATA");
+}
+
+ATF_TC(RNDADDDATA2);
+ATF_TC_HEAD(RNDADDDATA2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "checks ioctl(RNDADDDATA) deals with "
+ "garbage len field");
+}
+ATF_TC_BODY(RNDADDDATA2, tc)
+{
+ rnddata_t rd;
+ int fd;
+
+ rump_init();
+ fd = rump_sys_open("/dev/random", O_RDWR, 0);
+ if (fd == -1)
+ atf_tc_fail_errno("cannot open /dev/random");
+
+ rd.entropy = 1;
+ rd.len = -1;
+ ATF_REQUIRE_ERRNO(EINVAL, rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, RNDADDDATA);
+ ATF_TP_ADD_TC(tp, RNDADDDATA2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_sysctl.c b/contrib/netbsd-tests/kernel/t_sysctl.c
new file mode 100644
index 0000000..8b7c97e
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_sysctl.c
@@ -0,0 +1,74 @@
+/* $NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2014\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $");
+
+#include <sys/sysctl.h>
+#include <errno.h>
+#include <memory.h>
+
+#include <atf-c.h>
+
+ATF_TC(bufsize);
+ATF_TC_HEAD(bufsize, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test sysctl integer reads with different buffer sizes");
+}
+ATF_TC_BODY(bufsize, tc)
+{
+ union {
+ int int_val;
+ unsigned char space[256];
+ } buf;
+ size_t len;
+ for (len = 0; len < sizeof(buf); len++) {
+ size_t oldlen = len;
+ int r;
+ memset(&buf, 0xFF, sizeof(buf));
+ r = sysctlbyname("kern.job_control", &buf, &oldlen, 0, (size_t) 0);
+ if (len < sizeof(int)) {
+ ATF_REQUIRE_EQ(r, -1);
+ ATF_REQUIRE_EQ(errno, ENOMEM);
+ } else {
+ ATF_REQUIRE_EQ(r, 0);
+ ATF_REQUIRE_EQ(buf.int_val, 1);
+ ATF_REQUIRE_EQ(oldlen, sizeof(int));
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, bufsize);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/kernel/t_sysv.c b/contrib/netbsd-tests/kernel/t_sysv.c
new file mode 100644
index 0000000..0860d4b
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_sysv.c
@@ -0,0 +1,854 @@
+/* $NetBSD: t_sysv.c,v 1.4 2014/03/02 20:13:12 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center, and by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Test the SVID-compatible Message Queue facility.
+ */
+
+#include <atf-c.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/param.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/wait.h>
+
+volatile int did_sigsys, did_sigchild;
+volatile int child_status, child_count;
+
+void sigsys_handler(int);
+void sigchld_handler(int);
+
+key_t get_ftok(int);
+
+void print_msqid_ds(struct msqid_ds *, mode_t);
+void receiver(void);
+
+void print_semid_ds(struct semid_ds *, mode_t);
+void waiter(void);
+
+void print_shmid_ds(struct shmid_ds *, mode_t);
+void sharer(void);
+
+#define MESSAGE_TEXT_LEN 256
+
+struct mymsg {
+ long mtype;
+ char mtext[MESSAGE_TEXT_LEN];
+};
+
+const char *m1_str = "California is overrated.";
+const char *m2_str = "The quick brown fox jumped over the lazy dog.";
+
+size_t pgsize;
+
+#define MTYPE_1 1
+#define MTYPE_1_ACK 2
+
+#define MTYPE_2 3
+#define MTYPE_2_ACK 4
+
+pid_t child_pid;
+
+key_t msgkey, semkey, shmkey;
+
+int maxloop = 1;
+
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_{STAT,SET} */
+ u_short *array; /* array for GETALL & SETALL */
+};
+
+
+/* Writes an integer to a file. To be used from the body of the test
+ * cases below to pass any global identifiers to the cleanup routine. */
+static void
+write_int(const char *path, const int value)
+{
+ int output;
+
+ output = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ ATF_REQUIRE_MSG(output != -1, "Failed to create %s", path);
+ write(output, &value, sizeof(value));
+ close(output);
+}
+
+
+/* Reads an integer from a file. To be used from the cleanup routines
+ * of the test cases below. */
+static int
+read_int(const char *path)
+{
+ int input;
+
+ input = open(path, O_RDONLY);
+ if (input == -1)
+ return -1;
+ else {
+ int value;
+ read(input, &value, sizeof(value));
+ return value;
+ }
+}
+
+
+void
+sigsys_handler(int signo)
+{
+
+ did_sigsys = 1;
+}
+
+void
+sigchld_handler(int signo)
+{
+ int c_status;
+
+ did_sigchild = 1;
+ /*
+ * Reap the child and return its status
+ */
+ if (wait(&c_status) == -1)
+ child_status = -errno;
+ else
+ child_status = c_status;
+
+ child_count--;
+}
+
+key_t get_ftok(int id)
+{
+ int fd;
+ char token_key[64], token_dir[64];
+ char *tmpdir;
+ key_t key;
+
+ strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key));
+ tmpdir = mkdtemp(token_key);
+ ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp() failed: %d", errno);
+
+ strlcpy(token_dir, tmpdir, sizeof(token_dir));
+ strlcpy(token_key, tmpdir, sizeof(token_key));
+ strlcat(token_key, "/token_key", sizeof(token_key));
+
+ /* Create the file, since ftok() requires it to exist! */
+
+ fd = open(token_key, O_RDWR | O_CREAT | O_EXCL);
+ if (fd == -1) {
+ rmdir(tmpdir);
+ atf_tc_fail("open() of temp file failed: %d", errno);
+ return (key_t)-1;
+ } else
+ close(fd);
+
+ key = ftok(token_key, id);
+
+ ATF_REQUIRE_MSG(unlink(token_key) != -1, "unlink() failed: %d", errno);
+ ATF_REQUIRE_MSG(rmdir(token_dir) != -1, "rmdir() failed: %d", errno);
+
+ return key;
+}
+
+ATF_TC_WITH_CLEANUP(msg);
+ATF_TC_HEAD(msg, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "3");
+ atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
+}
+
+ATF_TC_BODY(msg, tc)
+{
+ struct sigaction sa;
+ struct msqid_ds m_ds;
+ struct mymsg m;
+ sigset_t sigmask;
+ int sender_msqid;
+ int loop;
+ int c_status;
+
+ /*
+ * Install a SIGSYS handler so that we can exit gracefully if
+ * System V Message Queue support isn't in the kernel.
+ */
+ did_sigsys = 0;
+ sa.sa_handler = sigsys_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
+ "sigaction SIGSYS: %d", errno);
+
+ /*
+ * Install a SIGCHLD handler to deal with all possible exit
+ * conditions of the receiver.
+ */
+ did_sigchild = 0;
+ child_count = 0;
+ sa.sa_handler = sigchld_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
+ "sigaction SIGCHLD: %d", errno);
+
+ msgkey = get_ftok(4160);
+ ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed");
+
+ sender_msqid = msgget(msgkey, IPC_CREAT | 0640);
+ ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno);
+ write_int("sender_msqid", sender_msqid);
+
+ if (did_sigsys) {
+ atf_tc_skip("SYSV Message Queue not supported");
+ return;
+ }
+
+ ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
+ "msgctl IPC_STAT 1: %d", errno);
+
+ print_msqid_ds(&m_ds, 0640);
+
+ m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600;
+
+ ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1,
+ "msgctl IPC_SET: %d", errno);
+
+ memset(&m_ds, 0, sizeof(m_ds));
+
+ ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
+ "msgctl IPC_STAT 2: %d", errno);
+
+ ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600,
+ "IPC_SET of mode didn't hold");
+
+ print_msqid_ds(&m_ds, 0600);
+
+ switch ((child_pid = fork())) {
+ case -1:
+ atf_tc_fail("fork: %d", errno);
+ return;
+
+ case 0:
+ child_count++;
+ receiver();
+ break;
+
+ default:
+ break;
+ }
+
+ for (loop = 0; loop < maxloop; loop++) {
+ /*
+ * Send the first message to the receiver and wait for the ACK.
+ */
+ m.mtype = MTYPE_1;
+ strcpy(m.mtext, m1_str);
+ ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN,
+ 0) != -1, "sender: msgsnd 1: %d", errno);
+
+ ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN,
+ MTYPE_1_ACK, 0) == MESSAGE_TEXT_LEN,
+ "sender: msgrcv 1 ack: %d", errno);
+
+ print_msqid_ds(&m_ds, 0600);
+
+ /*
+ * Send the second message to the receiver and wait for the ACK.
+ */
+ m.mtype = MTYPE_2;
+ strcpy(m.mtext, m2_str);
+ ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, 0) != -1,
+ "sender: msgsnd 2: %d", errno);
+
+ ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN,
+ MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN,
+ "sender: msgrcv 2 ack: %d", errno);
+ }
+
+ /*
+ * Wait for child to finish
+ */
+ sigemptyset(&sigmask);
+ (void) sigsuspend(&sigmask);
+
+ /*
+ * ...and any other signal is an unexpected error.
+ */
+ if (did_sigchild) {
+ c_status = child_status;
+ if (c_status < 0)
+ atf_tc_fail("waitpid: %d", -c_status);
+ else if (WIFEXITED(c_status) == 0)
+ atf_tc_fail("child abnormal exit: %d", c_status);
+ else if (WEXITSTATUS(c_status) != 0)
+ atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
+ else {
+ ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds)
+ != -1, "msgctl IPC_STAT: %d", errno);
+
+ print_msqid_ds(&m_ds, 0600);
+ atf_tc_pass();
+ }
+ } else
+ atf_tc_fail("sender: received unexpected signal");
+}
+
+ATF_TC_CLEANUP(msg, tc)
+{
+ int sender_msqid;
+
+ /*
+ * Remove the message queue if it exists.
+ */
+ sender_msqid = read_int("sender_msqid");
+ if (sender_msqid != -1)
+ if (msgctl(sender_msqid, IPC_RMID, NULL) == -1)
+ err(1, "msgctl IPC_RMID");
+}
+
+void
+print_msqid_ds(mp, mode)
+ struct msqid_ds *mp;
+ mode_t mode;
+{
+ uid_t uid = geteuid();
+ gid_t gid = getegid();
+
+ printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
+ mp->msg_perm.uid, mp->msg_perm.gid,
+ mp->msg_perm.cuid, mp->msg_perm.cgid,
+ mp->msg_perm.mode & 0777);
+
+ printf("qnum %lu, qbytes %lu, lspid %d, lrpid %d\n",
+ mp->msg_qnum, (u_long)mp->msg_qbytes, mp->msg_lspid,
+ mp->msg_lrpid);
+
+ printf("stime: %s", ctime(&mp->msg_stime));
+ printf("rtime: %s", ctime(&mp->msg_rtime));
+ printf("ctime: %s", ctime(&mp->msg_ctime));
+
+ /*
+ * Sanity check a few things.
+ */
+
+ ATF_REQUIRE_MSG(mp->msg_perm.uid == uid && mp->msg_perm.cuid == uid,
+ "uid mismatch");
+
+ ATF_REQUIRE_MSG(mp->msg_perm.gid == gid && mp->msg_perm.cgid == gid,
+ "gid mismatch");
+
+ ATF_REQUIRE_MSG((mp->msg_perm.mode & 0777) == mode, "mode mismatch");
+}
+
+void
+receiver()
+{
+ struct mymsg m;
+ int msqid, loop;
+
+ if ((msqid = msgget(msgkey, 0)) == -1)
+ err(1, "receiver: msgget");
+
+ for (loop = 0; loop < maxloop; loop++) {
+ /*
+ * Receive the first message, print it, and send an ACK.
+ */
+ if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN)
+ err(1, "receiver: msgrcv 1");
+
+ printf("%s\n", m.mtext);
+ if (strcmp(m.mtext, m1_str) != 0)
+ err(1, "receiver: message 1 data isn't correct");
+
+ m.mtype = MTYPE_1_ACK;
+
+ if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1)
+ err(1, "receiver: msgsnd ack 1");
+
+ /*
+ * Receive the second message, print it, and send an ACK.
+ */
+
+ if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN)
+ err(1, "receiver: msgrcv 2");
+
+ printf("%s\n", m.mtext);
+ if (strcmp(m.mtext, m2_str) != 0)
+ err(1, "receiver: message 2 data isn't correct");
+
+ m.mtype = MTYPE_2_ACK;
+
+ if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1)
+ err(1, "receiver: msgsnd ack 2");
+ }
+
+ exit(0);
+}
+
+/*
+ * Test the SVID-compatible Semaphore facility.
+ */
+
+ATF_TC_WITH_CLEANUP(sem);
+ATF_TC_HEAD(sem, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "3");
+ atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
+}
+
+ATF_TC_BODY(sem, tc)
+{
+ struct sigaction sa;
+ union semun sun;
+ struct semid_ds s_ds;
+ sigset_t sigmask;
+ int sender_semid;
+ int i;
+ int c_status;
+
+ /*
+ * Install a SIGSYS handler so that we can exit gracefully if
+ * System V Semaphore support isn't in the kernel.
+ */
+ did_sigsys = 0;
+ sa.sa_handler = sigsys_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
+ "sigaction SIGSYS: %d", errno);
+
+ /*
+ * Install a SIGCHLD handler to deal with all possible exit
+ * conditions of the receiver.
+ */
+ did_sigchild = 0;
+ child_count = 0;
+ sa.sa_handler = sigchld_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
+ "sigaction SIGCHLD: %d", errno);
+
+ semkey = get_ftok(4160);
+ ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed");
+
+ sender_semid = semget(semkey, 1, IPC_CREAT | 0640);
+ ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno);
+ write_int("sender_semid", sender_semid);
+
+ if (did_sigsys) {
+ atf_tc_skip("SYSV Semaphore not supported");
+ return;
+ }
+
+ sun.buf = &s_ds;
+ ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
+ "semctl IPC_STAT: %d", errno);
+
+ print_semid_ds(&s_ds, 0640);
+
+ s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600;
+
+ sun.buf = &s_ds;
+ ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1,
+ "semctl IPC_SET: %d", errno);
+
+ memset(&s_ds, 0, sizeof(s_ds));
+
+ sun.buf = &s_ds;
+ ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
+ "semctl IPC_STAT: %d", errno);
+
+ ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600,
+ "IPC_SET of mode didn't hold");
+
+ print_semid_ds(&s_ds, 0600);
+
+ for (child_count = 0; child_count < 5; child_count++) {
+ switch ((child_pid = fork())) {
+ case -1:
+ atf_tc_fail("fork: %d", errno);
+ return;
+
+ case 0:
+ waiter();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Wait for all of the waiters to be attempting to acquire the
+ * semaphore.
+ */
+ for (;;) {
+ i = semctl(sender_semid, 0, GETNCNT);
+ if (i == -1)
+ atf_tc_fail("semctl GETNCNT: %d", i);
+ if (i == 5)
+ break;
+ }
+
+ /*
+ * Now set the thundering herd in motion by initializing the
+ * semaphore to the value 1.
+ */
+ sun.val = 1;
+ ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1,
+ "sender: semctl SETVAL to 1: %d", errno);
+
+ /*
+ * Wait for all children to finish
+ */
+ sigemptyset(&sigmask);
+ for (;;) {
+ (void) sigsuspend(&sigmask);
+ if (did_sigchild) {
+ c_status = child_status;
+ if (c_status < 0)
+ atf_tc_fail("waitpid: %d", -c_status);
+ else if (WIFEXITED(c_status) == 0)
+ atf_tc_fail("c abnormal exit: %d", c_status);
+ else if (WEXITSTATUS(c_status) != 0)
+ atf_tc_fail("c status: %d",
+ WEXITSTATUS(c_status));
+ else {
+ sun.buf = &s_ds;
+ ATF_REQUIRE_MSG(semctl(sender_semid, 0,
+ IPC_STAT, sun) != -1,
+ "semctl IPC_STAT: %d", errno);
+
+ print_semid_ds(&s_ds, 0600);
+ atf_tc_pass();
+ }
+ if (child_count <= 0)
+ break;
+ did_sigchild = 0;
+ } else {
+ atf_tc_fail("sender: received unexpected signal");
+ break;
+ }
+ }
+}
+
+ATF_TC_CLEANUP(sem, tc)
+{
+ int sender_semid;
+
+ /*
+ * Remove the semaphore if it exists
+ */
+ sender_semid = read_int("sender_semid");
+ if (sender_semid != -1)
+ if (semctl(sender_semid, 0, IPC_RMID) == -1)
+ err(1, "semctl IPC_RMID");
+}
+
+void
+print_semid_ds(sp, mode)
+ struct semid_ds *sp;
+ mode_t mode;
+{
+ uid_t uid = geteuid();
+ gid_t gid = getegid();
+
+ printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
+ sp->sem_perm.uid, sp->sem_perm.gid,
+ sp->sem_perm.cuid, sp->sem_perm.cgid,
+ sp->sem_perm.mode & 0777);
+
+ printf("nsems %u\n", sp->sem_nsems);
+
+ printf("otime: %s", ctime(&sp->sem_otime));
+ printf("ctime: %s", ctime(&sp->sem_ctime));
+
+ /*
+ * Sanity check a few things.
+ */
+
+ ATF_REQUIRE_MSG(sp->sem_perm.uid == uid && sp->sem_perm.cuid == uid,
+ "uid mismatch");
+
+ ATF_REQUIRE_MSG(sp->sem_perm.gid == gid && sp->sem_perm.cgid == gid,
+ "gid mismatch");
+
+ ATF_REQUIRE_MSG((sp->sem_perm.mode & 0777) == mode,
+ "mode mismatch %o != %o", (sp->sem_perm.mode & 0777), mode);
+}
+
+void
+waiter()
+{
+ struct sembuf s;
+ int semid;
+
+ if ((semid = semget(semkey, 1, 0)) == -1)
+ err(1, "waiter: semget");
+
+ /*
+ * Attempt to acquire the semaphore.
+ */
+ s.sem_num = 0;
+ s.sem_op = -1;
+ s.sem_flg = SEM_UNDO;
+
+ if (semop(semid, &s, 1) == -1)
+ err(1, "waiter: semop -1");
+
+ printf("WOO! GOT THE SEMAPHORE!\n");
+ sleep(1);
+
+ /*
+ * Release the semaphore and exit.
+ */
+ s.sem_num = 0;
+ s.sem_op = 1;
+ s.sem_flg = SEM_UNDO;
+
+ if (semop(semid, &s, 1) == -1)
+ err(1, "waiter: semop +1");
+
+ exit(0);
+}
+
+/*
+ * Test the SVID-compatible Shared Memory facility.
+ */
+
+ATF_TC_WITH_CLEANUP(shm);
+ATF_TC_HEAD(shm, tc)
+{
+
+ atf_tc_set_md_var(tc, "timeout", "3");
+ atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory");
+}
+
+ATF_TC_BODY(shm, tc)
+{
+ struct sigaction sa;
+ struct shmid_ds s_ds;
+ sigset_t sigmask;
+ char *shm_buf;
+ int sender_shmid;
+ int c_status;
+
+ /*
+ * Install a SIGSYS handler so that we can exit gracefully if
+ * System V Shared Memory support isn't in the kernel.
+ */
+ did_sigsys = 0;
+ sa.sa_handler = sigsys_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
+ "sigaction SIGSYS: %d", errno);
+
+ /*
+ * Install a SIGCHLD handler to deal with all possible exit
+ * conditions of the sharer.
+ */
+ did_sigchild = 0;
+ child_count = 0;
+ sa.sa_handler = sigchld_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
+ "sigaction SIGCHLD: %d", errno);
+
+ pgsize = sysconf(_SC_PAGESIZE);
+
+ shmkey = get_ftok(4160);
+ ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed");
+
+ ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize,
+ IPC_CREAT | 0640)) != -1,
+ "shmget: %d", errno);
+ write_int("sender_shmid", sender_shmid);
+
+ ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
+ "shmctl IPC_STAT: %d", errno);
+
+ print_shmid_ds(&s_ds, 0640);
+
+ s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600;
+
+ ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1,
+ "shmctl IPC_SET: %d", errno);
+
+ memset(&s_ds, 0, sizeof(s_ds));
+
+ ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
+ "shmctl IPC_STAT: %d", errno);
+
+ ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600,
+ "IPC_SET of mode didn't hold");
+
+ print_shmid_ds(&s_ds, 0600);
+
+ shm_buf = shmat(sender_shmid, NULL, 0);
+ ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno);
+
+ /*
+ * Write the test pattern into the shared memory buffer.
+ */
+ strcpy(shm_buf, m2_str);
+
+ switch ((child_pid = fork())) {
+ case -1:
+ atf_tc_fail("fork: %d", errno);
+ return;
+
+ case 0:
+ sharer();
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * Wait for child to finish
+ */
+ sigemptyset(&sigmask);
+ (void) sigsuspend(&sigmask);
+
+ if (did_sigchild) {
+ c_status = child_status;
+ if (c_status < 0)
+ atf_tc_fail("waitpid: %d", -c_status);
+ else if (WIFEXITED(c_status) == 0)
+ atf_tc_fail("c abnormal exit: %d", c_status);
+ else if (WEXITSTATUS(c_status) != 0)
+ atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
+ else {
+ ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT,
+ &s_ds) != -1,
+ "shmctl IPC_STAT: %d", errno);
+
+ print_shmid_ds(&s_ds, 0600);
+ atf_tc_pass();
+ }
+ } else
+ atf_tc_fail("sender: received unexpected signal");
+}
+
+ATF_TC_CLEANUP(shm, tc)
+{
+ int sender_shmid;
+
+ /*
+ * Remove the shared memory area if it exists.
+ */
+ sender_shmid = read_int("sender_shmid");
+ if (sender_shmid != -1)
+ if (shmctl(sender_shmid, IPC_RMID, NULL) == -1)
+ err(1, "shmctl IPC_RMID");
+}
+
+void
+print_shmid_ds(sp, mode)
+ struct shmid_ds *sp;
+ mode_t mode;
+{
+ uid_t uid = geteuid();
+ gid_t gid = getegid();
+
+ printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
+ sp->shm_perm.uid, sp->shm_perm.gid,
+ sp->shm_perm.cuid, sp->shm_perm.cgid,
+ sp->shm_perm.mode & 0777);
+
+ printf("segsz %lu, lpid %d, cpid %d, nattch %u\n",
+ (u_long)sp->shm_segsz, sp->shm_lpid, sp->shm_cpid,
+ sp->shm_nattch);
+
+ printf("atime: %s", ctime(&sp->shm_atime));
+ printf("dtime: %s", ctime(&sp->shm_dtime));
+ printf("ctime: %s", ctime(&sp->shm_ctime));
+
+ /*
+ * Sanity check a few things.
+ */
+
+ ATF_REQUIRE_MSG(sp->shm_perm.uid == uid && sp->shm_perm.cuid == uid,
+ "uid mismatch");
+
+ ATF_REQUIRE_MSG(sp->shm_perm.gid == gid && sp->shm_perm.cgid == gid,
+ "gid mismatch");
+
+ ATF_REQUIRE_MSG((sp->shm_perm.mode & 0777) == mode, "mode mismatch");
+}
+
+void
+sharer()
+{
+ int shmid;
+ void *shm_buf;
+
+ shmid = shmget(shmkey, pgsize, 0);
+ ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno);
+
+ shm_buf = shmat(shmid, NULL, 0);
+ ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno);
+
+ printf("%s\n", (const char *)shm_buf);
+
+ ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0,
+ "receiver: data isn't correct");
+
+ exit(0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msg);
+ ATF_TP_ADD_TC(tp, sem);
+ ATF_TP_ADD_TC(tp, shm);
+
+ return atf_no_error();
+}
+
diff --git a/contrib/netbsd-tests/kernel/t_umount.sh b/contrib/netbsd-tests/kernel/t_umount.sh
new file mode 100755
index 0000000..b62ba10
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_umount.sh
@@ -0,0 +1,95 @@
+# $NetBSD: t_umount.sh,v 1.5 2010/11/07 17:51:19 jmmv Exp $
+#
+# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+TMPMP=umount-f_mount
+TMPIM=umount-f.im
+
+VND=vnd0
+BVND=/dev/${VND}
+CVND=/dev/r${VND}
+MPART=a
+
+atf_test_case umount cleanup
+umount_head()
+{
+ atf_set "descr" "Checks forced unmounting"
+ atf_set "require.user" "root"
+}
+umount_body()
+{
+ cat >disktab <<EOF
+floppy288|2.88MB 3.5in Extra High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\
+ :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\
+ :pb#5760:ob#0:\
+ :pc#5760:oc#0:
+EOF
+
+ echo "*** Creating a dummy directory tree at" \
+ "${TMPMP} mounted on ${TMPIM}"
+
+ atf_check -o ignore -e ignore mkdir ${TMPMP}
+ atf_check -o ignore -e ignore touch ${TMPMP}/under_the_mount
+ atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860
+ atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM}
+ atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288
+ atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART}
+ atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP}
+ atf_check -o ignore -e ignore touch ${TMPMP}/in_mounted_directory
+
+ echo "*** Testing forced unmount"
+ test -e "${TMPMP}/in_mounted_directory" || \
+ atf_fail "Test file not present in mounted directory!"
+
+ mydir="`pwd`"
+ cd "${TMPMP}"
+ atf_check -o ignore -e ignore umount -f "${BVND}${MPART}"
+
+ atf_check -s ne:0 -e inline:"ls: .: No such file or directory\n" ls .
+ atf_check -s ne:0 -e inline:"ls: ..: No such file or directory\n" ls ..
+
+ atf_check -s ne:0 -e ignore -o inline:"cd: can't cd to .\n" \
+ -x "cd . 2>&1"
+ atf_check -s ne:0 -e ignore -o inline:"cd: can't cd to ..\n" \
+ -x "cd .. 2>&1"
+
+ cd "${mydir}"
+
+ test -e "${TMPMP}/under_the_mount" || \
+ atf_fail "Original mount point dissapeared!"
+}
+umount_cleanup()
+{
+ echo "*** Cleaning up ${TMPMP}, ${TMPIM}."
+ umount -f "${TMPMP}"
+ vnconfig -u "${VND}"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case umount
+}
diff --git a/contrib/netbsd-tests/kernel/t_umountstress.sh b/contrib/netbsd-tests/kernel/t_umountstress.sh
new file mode 100755
index 0000000..fd50a1d
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/t_umountstress.sh
@@ -0,0 +1,209 @@
+# $NetBSD: t_umountstress.sh,v 1.5 2013/05/31 14:40:48 gson Exp $
+#
+# Copyright (c) 2013 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+TMPMP=umount-stress_mount
+TMPIM=umount-stress.im
+
+VND=vnd0
+BVND=/dev/${VND}
+CVND=/dev/r${VND}
+MPART=a
+
+atf_test_case fileop cleanup
+fileop_head()
+{
+ atf_set "descr" "Checks unmounting a filesystem doing file operations"
+ atf_set "require.user" "root"
+}
+fileop_body()
+{
+ cat >disktab <<EOF
+floppy288|2.88MB 3.5in Extra High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\
+ :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\
+ :pb#5760:ob#0:\
+ :pc#5760:oc#0:
+EOF
+
+ echo "*** Creating a dummy directory tree at" \
+ "${TMPMP} mounted on ${TMPIM}"
+
+ atf_check -o ignore -e ignore mkdir ${TMPMP}
+ atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860
+ atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM}
+ atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288
+ atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART}
+ atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP}
+
+ echo "*** Testing fileops"
+
+ touch ${TMPMP}/hold
+ exec 9< ${TMPMP}/hold
+
+ (
+ for j in 0 1 2; do
+ for k in 0 1 2 3 4 5 6 7 8 9; do
+ if ! dd msgfmt=quiet if=/dev/zero \
+ count=1 of=${TMPMP}/test$i$j$k; then
+ echo 1 >result
+ exit
+ fi
+ done
+ done
+ echo 0 >result
+ ) &
+ busypid=$!
+
+ while ! test -f result; do
+ if err=$(umount ${TMPMP} 2>&1); then
+ kill $busypid
+ exec 9<&-
+ wait
+ atf_fail "Unmount succeeded while busy"
+ return
+ fi
+
+ case $err in
+ *:\ Device\ busy)
+ ;;
+ *)
+ kill $busypid
+ exec 9<&-
+ wait
+ atf_fail "Unmount failed: $err"
+ return
+ ;;
+ esac
+ done
+
+ exec 9<&-
+ wait
+
+ rc=`cat result`
+ rm -f result
+
+ case $rc in
+ 0) ;;
+ *) atf_fail "File operation failed"
+ esac
+}
+fileop_cleanup()
+{
+ echo "*** Cleaning up ${TMPMP}, ${TMPIM}."
+ umount -f "${TMPMP}"
+ vnconfig -u "${VND}"
+}
+
+atf_test_case mountlist cleanup
+mountlist_head()
+{
+ atf_set "descr" "Checks unmounting a filesystem using mountlist"
+ atf_set "require.user" "root"
+}
+mountlist_body()
+{
+ cat >disktab <<EOF
+floppy288|2.88MB 3.5in Extra High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\
+ :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\
+ :pb#5760:ob#0:\
+ :pc#5760:oc#0:
+EOF
+
+ echo "*** Creating a dummy directory tree at" \
+ "${TMPMP} mounted on ${TMPIM}"
+
+ atf_check -o ignore -e ignore mkdir ${TMPMP}
+ atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860
+ atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM}
+ atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288
+ atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART}
+ atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP}
+
+ echo "*** Testing mountlist"
+
+ (
+ for j in 0 1 2 3 4 5 6 7 8 9; do
+ for k in 0 1 2 3 4 5 6 7 8 9; do
+ if ! out=$(mount); then
+ echo 1 >result
+ exit
+ fi
+ done
+ done
+ echo 0 >result
+ ) &
+ busypid=$!
+
+ while ! test -f result; do
+ if err=$(umount ${TMPMP} 2>&1); then
+ if ! mount -o async ${BVND}${MPART} ${TMPMP}; then
+ kill $busypid
+ exec 9<&-
+ wait
+ atf_fail "Remount failed"
+ return
+ fi
+ continue
+ fi
+
+ case $err in
+ *:\ Device\ busy)
+ ;;
+ *)
+ kill $busypid
+ exec 9<&-
+ wait
+ atf_fail "Unmount failed: $err"
+ return
+ ;;
+ esac
+ done
+
+ exec 9<&-
+ wait
+
+ rc=`cat result`
+ rm -f result
+
+ case $rc in
+ 0) ;;
+ *) atf_fail "Mountlist operation failed"
+ esac
+}
+mountlist_cleanup()
+{
+ echo "*** Cleaning up ${TMPMP}, ${TMPIM}."
+ umount -f "${TMPMP}"
+ vnconfig -u "${VND}"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case fileop
+ atf_add_test_case mountlist
+}
diff --git a/contrib/netbsd-tests/kernel/tty/t_pr.c b/contrib/netbsd-tests/kernel/tty/t_pr.c
new file mode 100644
index 0000000..c590ea5
--- /dev/null
+++ b/contrib/netbsd-tests/kernel/tty/t_pr.c
@@ -0,0 +1,186 @@
+/* $NetBSD: t_pr.c,v 1.7 2011/04/26 20:42:01 martin Exp $ */
+
+/*-
+ * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Antti Kantee <pooka@NetBSD.org> and Martin Husemann <martin@NetBSD.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+static int
+sendsome(int from, int to)
+{
+ size_t i;
+ ssize_t cnt;
+ static const char msg[] = "hello world\n";
+ char buf[sizeof(msg)+10];
+
+ memset(buf, 0, sizeof(buf));
+ rump_sys_write(from, msg, strlen(msg));
+ cnt = rump_sys_read(to, buf, sizeof(buf));
+ if (cnt < (ssize_t)strlen(msg)) {
+ printf("short message read: %zd chars: \"%s\"\n", cnt, buf);
+ return 1;
+ }
+ for (i = 0; i < sizeof(buf); i++) {
+ if (buf[i] == '\r' || buf[i] == '\n') {
+ buf[i] = '\n';
+ buf[i+1] = '\0';
+ break;
+ }
+ }
+
+ return strcmp(buf, msg) != 0;
+}
+
+static int
+exercise_ptytty(int master, int slave)
+{
+ int error, flags;
+
+ /*
+ * send a few bytes from master to slave and read them back
+ */
+ error = sendsome(master, slave);
+ if (error)
+ return error;
+
+ flags = FREAD|FWRITE;
+ rump_sys_ioctl(master, TIOCFLUSH, &flags);
+
+ /*
+ * and the same in the other direction
+ */
+ error = sendsome(slave, master);
+ if (error)
+ return error;
+
+ flags = FREAD|FWRITE;
+ rump_sys_ioctl(master, TIOCFLUSH, &flags);
+ return 0;
+}
+
+ATF_TC(client_first);
+ATF_TC_HEAD(client_first, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "test basic tty/pty operation when opening client side first");
+}
+
+ATF_TC_BODY(client_first, tc)
+{
+ int master, slave, error, v;
+
+ rump_init();
+ slave = rump_sys_open("/dev/ttyp1", O_RDWR|O_NONBLOCK);
+ ATF_CHECK(slave != -1);
+
+ master = rump_sys_open("/dev/ptyp1", O_RDWR);
+ ATF_CHECK(master != -1);
+
+ v = 0;
+ rump_sys_ioctl(slave, FIOASYNC, &v);
+ error = exercise_ptytty(master, slave);
+ ATF_CHECK(error == 0);
+
+ rump_sys_close(master);
+ rump_sys_close(slave);
+}
+
+ATF_TC(master_first);
+ATF_TC_HEAD(master_first, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "test basic tty/pty operation when opening master side first");
+}
+
+ATF_TC_BODY(master_first, tc)
+{
+ int master, slave, error;
+
+ rump_init();
+ master = rump_sys_open("/dev/ptyp1", O_RDWR);
+ ATF_CHECK(master != -1);
+
+ slave = rump_sys_open("/dev/ttyp1", O_RDWR);
+ ATF_CHECK(slave != -1);
+
+ error = exercise_ptytty(master, slave);
+ ATF_CHECK(error == 0);
+
+ rump_sys_close(master);
+ rump_sys_close(slave);
+}
+
+ATF_TC(ptyioctl);
+ATF_TC_HEAD(ptyioctl, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "ioctl on pty with client side not open");
+}
+
+ATF_TC_BODY(ptyioctl, tc)
+{
+ struct termios tio;
+ int fd;
+
+ rump_init();
+ fd = rump_sys_open("/dev/ptyp1", O_RDWR);
+ ATF_CHECK(fd != -1);
+
+ /*
+ * This used to die with null deref under ptcwakeup()
+ * atf_tc_expect_signal(-1, "PR kern/40688");
+ */
+ rump_sys_ioctl(fd, TIOCGETA, &tio);
+
+ rump_sys_close(fd);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ptyioctl);
+ ATF_TP_ADD_TC(tp, client_first);
+ ATF_TP_ADD_TC(tp, master_first);
+
+ return atf_no_error();
+}
OpenPOWER on IntegriCloud