Importing NetBSD "Kyua" test framework

To do so, a few dependencies have been imported:

 * external/bsd/lutok
 * external/mit/lua
 * external/public-domain/sqlite
 * external/public-domain/xz

The Kyua framework is the new generation of ATF (Automated Test
Framework), it is composed of:

 * external/bsd/atf
 * external/bsd/kyua-atf-compat
 * external/bsd/kyua-cli
 * external/bsd/kyua-tester
 * tests

Kyua/ATF being written in C++, it depends on libstdc++ which is
provided by GCC. As this is not part of the sources, Kyua is only
compiled when the native GCC utils are installed.

To install Kyua do the following:

 * In a cross-build enviromnent, add the following to the build.sh
   commandline: -V MKBINUTILS=yes -V MKGCCCMDS=yes

WARNING:
  At this point the import is still experimental, and not supported
  on native builds (a.k.a make build).

Change-Id: I26aee23c5bbd2d64adcb7c1beb98fe0d479d7ada
This commit is contained in:
2013-02-26 09:24:42 +01:00
committed by Gerrit Code Review
parent 003ff52ebb
commit 11be35a165
2893 changed files with 502052 additions and 2630 deletions

53
tests/kernel/Makefile Normal file
View File

@@ -0,0 +1,53 @@
# $NetBSD: Makefile,v 1.33 2013/04/16 22:05:44 mlelstv Exp $
NOMAN= # defined
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/kernel
TESTS_SUBDIRS= kqueue
TESTS_C= t_lock
TESTS_C+= t_lockf
TESTS_C+= t_pty
TESTS_C+= t_mqueue
TESTS_C+= t_sysv
TESTS_C+= t_subr_prf
TESTS_C+= t_kauth_pr_47598
TESTS_SH= t_umount
TESTS_SH+= t_umountstress
TESTS_SH+= t_ps_strings
BINDIR= ${TESTSDIR}
PROGS= h_ps_strings1
PROGS+= h_ps_strings2
LDADD.t_mqueue+= -lrt
.if (${MKRUMP} != "no")
TESTS_SUBDIRS+= tty
TESTS_C+= t_extattrctl
TESTS_C+= t_filedesc
TESTS_C+= t_rnd
LDADD.t_extattrctl+= -lrumpvfs -lrump -lrumpuser -lpthread
LDADD.t_filedesc+= ${LDADD.t_rnd}
LDADD.t_rnd+= -lrumpvfs -lrumpdev_rnd -lrumpdev -lrump -lrumpuser -lpthread
.endif
.PATH: ${NETBSDSRCDIR}/sys/kern
TESTS_C+= t_extent
SRCS.t_extent= t_extent.c subr_extent.c
CPPFLAGS.t_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE
CPPFLAGS.subr_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE
t_subr_prf.c: gen_t_subr_prf ${NETBSDSRCDIR}/sys/kern/subr_prf.c
${HOST_SH} ${.ALLSRC} ${.TARGET}
CLEANFILES+= t_subr_prf.c
.include <bsd.test.mk>

View File

@@ -0,0 +1 @@
.include "../Makefile.inc"

124
tests/kernel/gen_t_subr_prf Executable file
View File

@@ -0,0 +1,124 @@
#!/bin/sh
cat << _EOF > $2
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.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;
#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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,18 @@
# $NetBSD: Makefile,v 1.3 2012/11/17 21:55:24 joerg Exp $
NOMAN= # defined
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/kernel/kqueue
TESTS_SUBDIRS= read
TESTS_SUBDIRS+= write
TESTS_C= t_ioctl
TESTS_C+= t_proc1
TESTS_C+= t_proc2
TESTS_C+= t_proc3
TESTS_C+= t_sig
.include <bsd.test.mk>

View File

@@ -0,0 +1 @@
.include "../Makefile.inc"

View File

@@ -0,0 +1,17 @@
# $NetBSD: Makefile,v 1.1 2009/02/20 21:39:57 jmmv Exp $
NOMAN= # defined
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/kernel/kqueue/read
TESTS_C= t_fifo
TESTS_C+= t_file
TESTS_C+= t_file2
TESTS_C+= t_pipe
TESTS_C+= t_ttypty
LDADD.t_ttypty= -lutil
.include <bsd.test.mk>

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

133
tests/kernel/kqueue/t_sig.c Normal file
View File

@@ -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();
}

View File

@@ -0,0 +1,15 @@
# $NetBSD: Makefile,v 1.1 2009/02/20 21:39:57 jmmv Exp $
NOMAN= # defined
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/kernel/kqueue/write
TESTS_C= t_fifo
TESTS_C+= t_pipe
TESTS_C+= t_ttypty
LDADD.t_ttypty= -lutil
.include <bsd.test.mk>

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

385
tests/kernel/t_extent.c Normal file
View File

@@ -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();
}

108
tests/kernel/t_filedesc.c Normal file
View File

@@ -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();
}

View File

@@ -0,0 +1,128 @@
/*-
* 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.2 2013/02/28 20:41:21 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>
/*
* 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)
{
static const char curtain_name[] = "security.models.bsd44.curtain";
int old_curtain, new_curtain = 1, s, s2, err;
size_t old_curtain_len = sizeof(old_curtain);
socklen_t slen;
struct sockaddr_in sa;
/*
* save old value of "curtain" and enable it
*/
if (sysctlbyname(curtain_name, &old_curtain, &old_curtain_len,
&new_curtain, sizeof(new_curtain)) != 0)
atf_tc_fail("failed to enable %s", curtain_name);
/*
* 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
*/
if (sysctlbyname(curtain_name, NULL, 0,
&old_curtain, sizeof(old_curtain)) != 0)
atf_tc_fail("failed to restore %s", curtain_name);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, kauth_curtain);
return atf_no_error();
}

87
tests/kernel/t_lock.c Normal file
View File

@@ -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();
}

262
tests/kernel/t_lockf.c Normal file
View File

@@ -0,0 +1,262 @@
/* $NetBSD: t_lockf.c,v 1.8 2013/02/20 02:22:48 pgoyette 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, ret, 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;
ret = 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();
}

148
tests/kernel/t_mqueue.c Normal file
View File

@@ -0,0 +1,148 @@
/* $NetBSD: t_mqueue.c,v 1.3 2012/11/06 19:35:38 pgoyette 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>
char *tmpdir;
#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_WITH_CLEANUP(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 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_TC_CLEANUP(mqueue, tc)
{
int status;
if (tmpdir != NULL) {
status = rmdir(tmpdir);
ATF_REQUIRE_MSG(status == 0, "rmdir failed: %d", errno);
}
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, mqueue);
return atf_no_error();
}

View File

@@ -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
}

351
tests/kernel/t_pty.c Normal file
View File

@@ -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

95
tests/kernel/t_rnd.c Normal file
View File

@@ -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();
}

816
tests/kernel/t_sysv.c Normal file
View File

@@ -0,0 +1,816 @@
/* $NetBSD: t_sysv.c,v 1.2 2012/11/06 18:31:53 pgoyette 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
int sender_msqid = -1;
int sender_semid = -1;
int sender_shmid = -1;
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 */
};
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 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);
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, sizeof(m), 0) != -1,
"sender: msgsnd 1: %d", errno);
ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m),
MTYPE_1_ACK, 0) == sizeof(m),
"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, sizeof(m), 0) != -1,
"sender: msgsnd 2: %d", errno);
ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m),
MTYPE_2_ACK, 0) == sizeof(m),
"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)
{
/*
* Remove the message queue if it exists.
*/
if (sender_msqid != -1)
ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_RMID, NULL) != -1,
"msgctl IPC_RMID: %d", errno);
sender_msqid = -1;
}
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, sizeof(m), MTYPE_1, 0) != sizeof(m))
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, sizeof(m), 0) == -1)
err(1, "receiver: msgsnd ack 1");
/*
* Receive the second message, print it, and send an ACK.
*/
if (msgrcv(msqid, &m, sizeof(m), MTYPE_2, 0) != sizeof(m))
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, sizeof(m), 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 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);
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)
{
/*
* Remove the semaphore if it exists
*/
if (sender_semid != -1)
ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_RMID) != -1,
"semctl IPC_RMID: %d", errno);
sender_semid = -1;
}
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 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);
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)
{
/*
* Remove the shared memory area if it exists.
*/
if (sender_shmid != -1)
ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_RMID, NULL) != -1,
"shmctl IPC_RMID: %d", errno);
sender_shmid = -1;
}
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();
}

95
tests/kernel/t_umount.sh Normal file
View File

@@ -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
}

View File

@@ -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
}

11
tests/kernel/tty/Makefile Normal file
View File

@@ -0,0 +1,11 @@
# $NetBSD: Makefile,v 1.1 2010/06/28 19:04:00 pooka Exp $
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/kernel/tty
TESTS_C= t_pr
LDADD+= -lrumpkern_tty -lrumpvfs -lrump -lrumpuser -lpthread
.include <bsd.test.mk>

186
tests/kernel/tty/t_pr.c Normal file
View File

@@ -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();
}