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:
53
tests/kernel/Makefile
Normal file
53
tests/kernel/Makefile
Normal 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>
|
||||
1
tests/kernel/Makefile.inc
Normal file
1
tests/kernel/Makefile.inc
Normal file
@@ -0,0 +1 @@
|
||||
.include "../Makefile.inc"
|
||||
124
tests/kernel/gen_t_subr_prf
Executable file
124
tests/kernel/gen_t_subr_prf
Executable 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
|
||||
74
tests/kernel/h_ps_strings1.c
Normal file
74
tests/kernel/h_ps_strings1.c
Normal 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;
|
||||
}
|
||||
69
tests/kernel/h_ps_strings2.c
Normal file
69
tests/kernel/h_ps_strings2.c
Normal 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;
|
||||
}
|
||||
18
tests/kernel/kqueue/Makefile
Normal file
18
tests/kernel/kqueue/Makefile
Normal 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>
|
||||
1
tests/kernel/kqueue/Makefile.inc
Normal file
1
tests/kernel/kqueue/Makefile.inc
Normal file
@@ -0,0 +1 @@
|
||||
.include "../Makefile.inc"
|
||||
17
tests/kernel/kqueue/read/Makefile
Normal file
17
tests/kernel/kqueue/read/Makefile
Normal 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>
|
||||
98
tests/kernel/kqueue/read/t_fifo.c
Normal file
98
tests/kernel/kqueue/read/t_fifo.c
Normal 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();
|
||||
}
|
||||
139
tests/kernel/kqueue/read/t_file.c
Normal file
139
tests/kernel/kqueue/read/t_file.c
Normal 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();
|
||||
}
|
||||
79
tests/kernel/kqueue/read/t_file2.c
Normal file
79
tests/kernel/kqueue/read/t_file2.c
Normal 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();
|
||||
}
|
||||
84
tests/kernel/kqueue/read/t_pipe.c
Normal file
84
tests/kernel/kqueue/read/t_pipe.c
Normal 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();
|
||||
}
|
||||
144
tests/kernel/kqueue/read/t_ttypty.c
Normal file
144
tests/kernel/kqueue/read/t_ttypty.c
Normal 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();
|
||||
}
|
||||
115
tests/kernel/kqueue/t_ioctl.c
Normal file
115
tests/kernel/kqueue/t_ioctl.c
Normal 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();
|
||||
}
|
||||
154
tests/kernel/kqueue/t_proc1.c
Normal file
154
tests/kernel/kqueue/t_proc1.c
Normal 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();
|
||||
}
|
||||
138
tests/kernel/kqueue/t_proc2.c
Normal file
138
tests/kernel/kqueue/t_proc2.c
Normal 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();
|
||||
}
|
||||
99
tests/kernel/kqueue/t_proc3.c
Normal file
99
tests/kernel/kqueue/t_proc3.c
Normal 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
133
tests/kernel/kqueue/t_sig.c
Normal 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();
|
||||
}
|
||||
15
tests/kernel/kqueue/write/Makefile
Normal file
15
tests/kernel/kqueue/write/Makefile
Normal 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>
|
||||
102
tests/kernel/kqueue/write/t_fifo.c
Normal file
102
tests/kernel/kqueue/write/t_fifo.c
Normal 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();
|
||||
}
|
||||
147
tests/kernel/kqueue/write/t_pipe.c
Normal file
147
tests/kernel/kqueue/write/t_pipe.c
Normal 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();
|
||||
}
|
||||
130
tests/kernel/kqueue/write/t_ttypty.c
Normal file
130
tests/kernel/kqueue/write/t_ttypty.c
Normal 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();
|
||||
}
|
||||
28
tests/kernel/t_extattrctl.c
Normal file
28
tests/kernel/t_extattrctl.c
Normal 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
385
tests/kernel/t_extent.c
Normal 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
108
tests/kernel/t_filedesc.c
Normal 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();
|
||||
}
|
||||
128
tests/kernel/t_kauth_pr_47598.c
Normal file
128
tests/kernel/t_kauth_pr_47598.c
Normal 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
87
tests/kernel/t_lock.c
Normal 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
262
tests/kernel/t_lockf.c
Normal 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
148
tests/kernel/t_mqueue.c
Normal 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();
|
||||
}
|
||||
85
tests/kernel/t_ps_strings.sh
Normal file
85
tests/kernel/t_ps_strings.sh
Normal 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
351
tests/kernel/t_pty.c
Normal 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
95
tests/kernel/t_rnd.c
Normal 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
816
tests/kernel/t_sysv.c
Normal 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
95
tests/kernel/t_umount.sh
Normal 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
|
||||
}
|
||||
209
tests/kernel/t_umountstress.sh
Normal file
209
tests/kernel/t_umountstress.sh
Normal 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
11
tests/kernel/tty/Makefile
Normal 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
186
tests/kernel/tty/t_pr.c
Normal 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();
|
||||
}
|
||||
Reference in New Issue
Block a user