summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-11-23 09:10:34 -0200
committerRenato Botelho <renato@netgate.com>2015-11-23 09:10:34 -0200
commit175c045d4a1c422d916e6326fe84ccbc0d0a113f (patch)
treeb8b853af14fbe0de33493ba527990a2aa469dd8c /tests
parenta9f1fcf48af9df36b9cd440fdc571067e1eef636 (diff)
parent749b28b1257beaf3e3d4f30302f7dfd901c958ac (diff)
downloadFreeBSD-src-175c045d4a1c422d916e6326fe84ccbc0d0a113f.zip
FreeBSD-src-175c045d4a1c422d916e6326fe84ccbc0d0a113f.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/kern/Makefile10
-rw-r--r--tests/sys/kern/acct/Makefile17
-rw-r--r--tests/sys/kern/acct/acct_test.c237
-rw-r--r--tests/sys/kern/pipe/Makefile16
-rw-r--r--tests/sys/kern/pipe/big_pipe_test.c88
-rw-r--r--tests/sys/kern/pipe/pipe_fstat_bug_test.c138
-rw-r--r--tests/sys/kern/pipe/pipe_ino_test.c65
-rw-r--r--tests/sys/kern/pipe/pipe_overcommit1_test.c52
-rw-r--r--tests/sys/kern/pipe/pipe_overcommit2_test.c83
-rw-r--r--tests/sys/kern/pipe/pipe_reverse2_test.c67
-rw-r--r--tests/sys/kern/pipe/pipe_reverse_test.c149
-rw-r--r--tests/sys/kern/pipe/pipe_wraparound_test.c140
12 files changed, 1062 insertions, 0 deletions
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index c345e5d..5328b99 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -1,5 +1,9 @@
# $FreeBSD$
+SRCTOP= ${.CURDIR:H:H:H}
+OBJTOP= ${.OBJDIR:H:H:H}
+TESTSRC= ${SRCTOP}/contrib/netbsd-tests/kernel
+
TESTSDIR= ${TESTSBASE}/sys/kern
ATF_TESTS_C+= kern_descrip_test
@@ -10,8 +14,14 @@ TEST_METADATA.unix_seqpacket_test+= timeout="15"
LDADD.ptrace_test+= -lpthread
LDADD.unix_seqpacket_test+= -lpthread
+NETBSD_ATF_TESTS_C+= lockf_test
+
WARNS?= 5
+TESTS_SUBDIRS+= acct
TESTS_SUBDIRS+= execve
+TESTS_SUBDIRS+= pipe
+
+.include <netbsd-tests.test.mk>
.include <bsd.test.mk>
diff --git a/tests/sys/kern/acct/Makefile b/tests/sys/kern/acct/Makefile
new file mode 100644
index 0000000..966fe9a
--- /dev/null
+++ b/tests/sys/kern/acct/Makefile
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/kern/acct
+
+ATF_TESTS_C= acct_test
+
+CFLAGS+= -I${.OBJDIR}
+
+CLEANFILES+= convert.c
+
+DPSRCS.acct_test= convert.c
+
+convert.c: ${SRCTOP}/sys/kern/kern_acct.c
+ sed -n -e 's/log(/syslog(/g' \
+ -e '/FLOAT_CONVERSION_START/,/FLOAT_CONVERSION_END/p' ${.ALLSRC} >>${.TARGET}
+
+.include <bsd.test.mk>
diff --git a/tests/sys/kern/acct/acct_test.c b/tests/sys/kern/acct/acct_test.c
new file mode 100644
index 0000000..2bf221c
--- /dev/null
+++ b/tests/sys/kern/acct/acct_test.c
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2011 Giorgos Keramidas. All rights reserved.
+ * Copyright (c) 2007 Diomidis Spinellis. 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <syslog.h>
+#include <time.h>
+
+#include <atf-c.h>
+
+#define KASSERT(val, msg) assert(val)
+
+typedef u_int32_t comp_t;
+
+#define AHZ 1000000
+
+#include "convert.c"
+
+union cf {
+ comp_t c;
+ float f;
+};
+
+static void
+check_result(const char *name, float expected, union cf v)
+{
+ double eps;
+
+ eps = fabs(expected - v.f) / expected;
+ ATF_CHECK(eps <= FLT_EPSILON);
+ if (eps > FLT_EPSILON) {
+ printf("Error in %s\n", name);
+ printf("Got 0x%08x %12g\n", v.c, v.f);
+ v.f = expected;
+ printf("Expected 0x%08x %12g (%.15lg)\n", v.c, v.f, expected);
+ printf("Epsilon=%lg, rather than %g\n", eps, FLT_EPSILON);
+ }
+}
+
+/*
+ * Test case for encoding {0 sec, 0 usec} within a reasonable epsilon.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_zero);
+ATF_TC_BODY(encode_tv_zero, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ v.c = encode_timeval(tv);
+ ATF_CHECK(fabs(v.f - 0.0) < FLT_EPSILON);
+}
+
+/*
+ * Test case for encoding a random long number.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_long);
+ATF_TC_BODY(encode_long, tc)
+{
+ union cf v;
+ long l;
+
+ l = random();
+ v.c = encode_long(l);
+ check_result(atf_tc_get_ident(tc), l, v);
+}
+
+/*
+ * Test case for encoding a small number of seconds {1 sec, 0 usec}.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_only_sec);
+ATF_TC_BODY(encode_tv_only_sec, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+}
+
+/*
+ * Test case for encoding a small number of usec {0 sec, 1 usec}.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_only_usec);
+ATF_TC_BODY(encode_tv_only_usec, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+}
+
+/*
+ * Test case for encoding a large number of usec {1 sec, 999.999 usec}.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_many_usec);
+ATF_TC_BODY(encode_tv_many_usec, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 999999L;
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+}
+
+/*
+ * Test case for encoding a huge number of usec {1 sec, 1.000.000 usec} that
+ * overflows the usec counter and should show up as an increase in timeval's
+ * seconds instead.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_usec_overflow);
+ATF_TC_BODY(encode_tv_usec_overflow, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 1000000L;
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+}
+
+/*
+ * Test case for encoding a very large number of seconds, one that is very
+ * near to the limit of 32-bit signed values. With a usec value of 999.999
+ * microseconds this should result in the largest value we can represent with
+ * a timeval struct.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_upper_limit);
+ATF_TC_BODY(encode_tv_upper_limit, tc)
+{
+ union cf v;
+ struct timeval tv;
+
+ tv.tv_sec = 2147483647L;
+ tv.tv_usec = 999999L;
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+}
+
+/*
+ * Test case for encoding a million random timeval objects, and checking that
+ * the conversion does not diverge too much from the expected values.
+ */
+
+ATF_TC_WITHOUT_HEAD(encode_tv_random_million);
+ATF_TC_BODY(encode_tv_random_million, tc)
+{
+ union cf v;
+ struct timeval tv;
+ long k;
+
+ atf_tc_expect_fail("the testcase violates FLT_EPSILON");
+
+ ATF_REQUIRE_MSG(unsetenv("TZ") == 0, "unsetting TZ failed; errno=%d", errno);
+
+ for (k = 1; k < 1000000L; k++) {
+ tv.tv_sec = random();
+ tv.tv_usec = (random() % 1000000L);
+ v.c = encode_timeval(tv);
+ check_result(atf_tc_get_ident(tc),
+ (float)tv.tv_sec * AHZ + tv.tv_usec, v);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, encode_long);
+ ATF_TP_ADD_TC(tp, encode_tv_zero);
+ ATF_TP_ADD_TC(tp, encode_tv_only_sec);
+ ATF_TP_ADD_TC(tp, encode_tv_only_usec);
+ ATF_TP_ADD_TC(tp, encode_tv_many_usec);
+ ATF_TP_ADD_TC(tp, encode_tv_usec_overflow);
+ ATF_TP_ADD_TC(tp, encode_tv_upper_limit);
+ ATF_TP_ADD_TC(tp, encode_tv_random_million);
+
+ return atf_no_error();
+}
diff --git a/tests/sys/kern/pipe/Makefile b/tests/sys/kern/pipe/Makefile
new file mode 100644
index 0000000..bcd2d07
--- /dev/null
+++ b/tests/sys/kern/pipe/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/kern/pipe
+
+PLAIN_TESTS_C+= big_pipe_test
+PLAIN_TESTS_C+= pipe_fstat_bug_test
+PLAIN_TESTS_C+= pipe_ino_test
+PLAIN_TESTS_C+= pipe_overcommit1_test
+PLAIN_TESTS_C+= pipe_overcommit2_test
+PLAIN_TESTS_C+= pipe_reverse2_test
+PLAIN_TESTS_C+= pipe_reverse_test
+PLAIN_TESTS_C+= pipe_wraparound_test
+
+WARNS?= 6
+
+.include <bsd.test.mk>
diff --git a/tests/sys/kern/pipe/big_pipe_test.c b/tests/sys/kern/pipe/big_pipe_test.c
new file mode 100644
index 0000000..fa5687e
--- /dev/null
+++ b/tests/sys/kern/pipe/big_pipe_test.c
@@ -0,0 +1,88 @@
+#include <sys/select.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BIG_PIPE_SIZE 64*1024 /* From sys/pipe.h */
+
+/*
+ * Test for the non-blocking big pipe bug (write(2) returning
+ * EAGAIN while select(2) returns the descriptor as ready for write).
+ *
+ * $FreeBSD$
+ */
+
+static void
+write_frame(int fd, char *buf, unsigned long buflen)
+{
+ fd_set wfd;
+ int i;
+
+ while (buflen) {
+ FD_ZERO(&wfd);
+ FD_SET(fd, &wfd);
+ i = select(fd+1, NULL, &wfd, NULL, NULL);
+ if (i < 0)
+ err(1, "select failed");
+ if (i != 1) {
+ errx(1, "select returned unexpected value %d\n", i);
+ exit(1);
+ }
+ i = write(fd, buf, buflen);
+ if (i < 0) {
+ if (errno != EAGAIN)
+ warn("write failed");
+ exit(1);
+ }
+ buf += i;
+ buflen -= i;
+ }
+}
+
+int
+main(void)
+{
+ /* any value over PIPE_SIZE should do */
+ char buf[BIG_PIPE_SIZE];
+ int i, flags, fd[2];
+
+ if (pipe(fd) < 0)
+ errx(1, "pipe failed");
+
+ flags = fcntl(fd[1], F_GETFL);
+ if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) {
+ printf("fcntl failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ switch (fork()) {
+ case -1:
+ err(1, "fork failed: %s\n", strerror(errno));
+ break;
+ case 0:
+ close(fd[1]);
+ for (;;) {
+ /* Any small size should do */
+ i = read(fd[0], buf, 256);
+ if (i == 0)
+ break;
+ if (i < 0)
+ err(1, "read");
+ }
+ exit(0);
+ default:
+ break;
+ }
+
+ close(fd[0]);
+ memset(buf, 0, sizeof buf);
+ for (i = 0; i < 1000; i++)
+ write_frame(fd[1], buf, sizeof buf);
+
+ printf("ok\n");
+ exit(0);
+}
diff --git a/tests/sys/kern/pipe/pipe_fstat_bug_test.c b/tests/sys/kern/pipe/pipe_fstat_bug_test.c
new file mode 100644
index 0000000..ae0b309
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_fstat_bug_test.c
@@ -0,0 +1,138 @@
+/*
+Copyright (C) 2004 Michael J. Silbersack. 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 AUTHOR 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 AUTHOR 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/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * $FreeBSD$
+ * The goal of this program is to see if fstat reports the correct
+ * data count for a pipe. Prior to revision 1.172 of sys_pipe.c,
+ * 0 would be returned once the pipe entered direct write mode.
+ *
+ * Linux (2.6) always returns zero, so it's not a valuable platform
+ * for comparison.
+ */
+
+int
+main(void)
+{
+ char buffer[32768], buffer2[32768], go[] = "go", go2[] = "go2";
+ int desc[2], ipc_coord[2];
+ ssize_t error;
+ int successes = 0;
+ struct stat status;
+ pid_t new_pid;
+
+ error = pipe(desc);
+ if (error == -1)
+ err(1, "Couldn't allocate data pipe");
+
+ error = pipe(ipc_coord);
+ if (error == -1)
+ err(1, "Couldn't allocate IPC coordination pipe");
+
+ new_pid = fork();
+ assert(new_pid != -1);
+
+ close(new_pid == 0 ? desc[0] : desc[1]);
+
+#define SYNC_R(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: waiting for synchronization", __LINE__); \
+ if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+ errno = _error; \
+ } while(0)
+
+#define SYNC_W(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: sending synchronization", __LINE__); \
+ if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+ errno = _error; \
+ } while(0)
+
+#define WRITE(s) do { \
+ ssize_t _size; \
+ if ((_size = write(desc[1], &buffer, s)) != s) \
+ warn("short write; wrote %zd, expected %d", _size, s); \
+ } while(0)
+
+ if (new_pid == 0) {
+
+ SYNC_R(0, go);
+ WRITE(145);
+ SYNC_W(0, go2);
+
+ SYNC_R(0, go);
+ WRITE(2048);
+ SYNC_W(0, go2);
+
+ SYNC_R(0, go);
+ WRITE(4096);
+ SYNC_W(0, go2);
+
+ SYNC_R(0, go);
+ WRITE(8191);
+ SYNC_W(0, go2);
+
+ SYNC_R(0, go);
+ SYNC_W(0, go2); /* XXX: why is this required? */
+ WRITE(8192);
+ SYNC_W(0, go2);
+
+ close(ipc_coord[0]);
+ close(ipc_coord[1]);
+
+ _exit(0);
+ }
+
+ while (successes < 5) {
+ SYNC_W(1, go);
+ SYNC_R(1, go2);
+ fstat(desc[0], &status);
+ error = read(desc[0], &buffer2, sizeof(buffer2));
+
+ if (status.st_size != error)
+ err(1, "FAILURE: stat size %jd read size %zd",
+ (intmax_t)status.st_size, error);
+ if (error > 0) {
+ printf("SUCCESS at stat size %jd read size %zd\n",
+ (intmax_t)status.st_size, error);
+ successes++;
+ }
+ }
+
+ exit(0);
+}
diff --git a/tests/sys/kern/pipe/pipe_ino_test.c b/tests/sys/kern/pipe/pipe_ino_test.c
new file mode 100644
index 0000000..94692aa
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_ino_test.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2011 Giovanni Trematerra <giovanni.trematerra@gmail.com>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * $FreeBSD$
+ * Test conformance to stat(2) SUSv4 description:
+ * "For all other file types defined in this volume of POSIX.1-2008, the
+ * structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atim,
+ * st_ctim, and st_mtim shall have meaningful values ...".
+ * Check that st_dev and st_ino are meaningful.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ int pipefd[2];
+ struct stat st1, st2;
+
+ if (pipe(pipefd) == -1)
+ err(1, "FAIL: pipe");
+
+ if (fstat(pipefd[0], &st1) == -1)
+ err(1, "FAIL: fstat st1");
+ if (fstat(pipefd[1], &st2) == -1)
+ err(1, "FAIL: fstat st2");
+ if (st1.st_dev != st2.st_dev || st1.st_dev == 0 || st2.st_dev == 0)
+ errx(1, "FAIL: wrong dev number %d %d", st1.st_dev, st2.st_dev);
+ if (st1.st_ino == st2.st_ino)
+ errx(1, "FAIL: inode numbers are equal: %d", st1.st_ino);
+
+ close(pipefd[0]);
+ close(pipefd[1]);
+ printf("PASS\n");
+
+ return (0);
+}
diff --git a/tests/sys/kern/pipe/pipe_overcommit1_test.c b/tests/sys/kern/pipe/pipe_overcommit1_test.c
new file mode 100644
index 0000000..f8f881d
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_overcommit1_test.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (C) 2005 Michael J. Silbersack <silby@freebsd.org>
+ * 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(s), this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified other than the possible
+ * addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice(s), 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 HOLDER(S) ``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 HOLDER(S) 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/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * $FreeBSD$
+ * This program just allocates as many pipes as it can to ensure
+ * that using up all pipe memory doesn't cause a panic.
+ */
+
+int
+main(void)
+{
+ int pipes[10000], returnval;
+ unsigned int i;
+
+ for (i = 0; i < nitems(pipes); i++) {
+ returnval = pipe(&pipes[i]);
+ }
+ printf("PASS\n");
+
+ exit(0);
+}
diff --git a/tests/sys/kern/pipe/pipe_overcommit2_test.c b/tests/sys/kern/pipe/pipe_overcommit2_test.c
new file mode 100644
index 0000000..ee1e714
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_overcommit2_test.c
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (C) 2005 Michael J. Silbersack <silby@freebsd.org>
+ * 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(s), this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified other than the possible
+ * addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice(s), 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 HOLDER(S) ``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 HOLDER(S) 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/param.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * $FreeBSD$
+ * This program tests how sys_pipe.c handles the case where there
+ * is ample memory to allocate a pipe, but the file descriptor
+ * limit for that user has been exceeded.
+ */
+
+int
+main(void)
+{
+ char template[] = "pipe.XXXXXXXXXX";
+ int lastfd, pipes[10000], returnval;
+ unsigned int i;
+
+ lastfd = -1;
+
+ if (mkstemp(template) == -1)
+ err(1, "mkstemp failed");
+
+ for (i = 0; i < nitems(pipes); i++) {
+ returnval = open(template, O_RDONLY);
+ if (returnval == -1 && (errno == ENFILE || errno == EMFILE))
+ break; /* All descriptors exhausted. */
+ else
+ lastfd = returnval;
+ }
+
+ /* First falloc failure case in sys_pipe.c:pipe() */
+ for (i = 0; i < 1000; i++) {
+ returnval = pipe(&pipes[i]);
+ }
+
+ /*
+ * Free just one FD so that the second falloc failure
+ * case will occur.
+ */
+ close(lastfd);
+
+ for (i = 0; i < 1000; i++) {
+ returnval = pipe(&pipes[i]);
+ }
+ printf("PASS\n");
+
+ unlink(template);
+
+ exit(0);
+}
diff --git a/tests/sys/kern/pipe/pipe_reverse2_test.c b/tests/sys/kern/pipe/pipe_reverse2_test.c
new file mode 100644
index 0000000..4666d95
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_reverse2_test.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2010 Jilles Tjoelker
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/select.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*
+ * Check that pipes can be selected for writing in the reverse direction.
+ */
+int
+main(void)
+{
+ int pip[2];
+ fd_set set;
+ int n;
+
+ if (pipe(pip) == -1)
+ err(1, "FAIL: pipe");
+
+ FD_ZERO(&set);
+ FD_SET(pip[0], &set);
+ n = select(pip[1] + 1, NULL, &set, NULL, &(struct timeval){ 0, 0 });
+ if (n != 1)
+ errx(1, "FAIL: select initial reverse direction");
+
+ n = write(pip[0], "x", 1);
+ if (n != 1)
+ err(1, "FAIL: write reverse direction");
+
+ FD_ZERO(&set);
+ FD_SET(pip[0], &set);
+ n = select(pip[1] + 1, NULL, &set, NULL, &(struct timeval){ 0, 0 });
+ if (n != 1)
+ errx(1, "FAIL: select reverse direction after write");
+
+ printf("PASS\n");
+
+ return (0);
+}
diff --git a/tests/sys/kern/pipe/pipe_reverse_test.c b/tests/sys/kern/pipe/pipe_reverse_test.c
new file mode 100644
index 0000000..fd4518d
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_reverse_test.c
@@ -0,0 +1,149 @@
+/*
+Copyright (C) 2004 Michael J. Silbersack. 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 AUTHOR 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 AUTHOR 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/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * $FreeBSD$
+ * This program simply tests writing through the reverse direction of
+ * a pipe. Nothing too fancy, it's only needed because most pipe-using
+ * programs never touch the reverse direction (it doesn't exist on
+ * Linux.)
+ */
+
+int
+main(void)
+{
+ char buffer[65535], buffer2[65535], go[] = "go", go2[] = "go2";
+ int desc[2], ipc_coord[2];
+ size_t i;
+ ssize_t total;
+ int buggy, error;
+ pid_t new_pid;
+
+ buggy = 0;
+ total = 0;
+
+ error = pipe(desc);
+ if (error == -1)
+ err(1, "Couldn't allocate data pipe");
+
+ error = pipe(ipc_coord);
+ if (error == -1)
+ err(1, "Couldn't allocate IPC coordination pipe");
+
+ buffer[0] = 'A';
+
+ for (i = 1; i < (int)sizeof(buffer); i++) {
+ buffer[i] = buffer[i - 1] + 1;
+ if (buffer[i] > 'Z')
+ buffer[i] = 'A';
+ }
+
+ new_pid = fork();
+ assert(new_pid != -1);
+
+#define SYNC_R(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: waiting for synchronization", __LINE__); \
+ if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+ errno = _error; \
+ } while(0)
+
+#define SYNC_W(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: sending synchronization", __LINE__); \
+ if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+ errno = _error; \
+ } while(0)
+
+#define WRITE(s) do { \
+ ssize_t _size; \
+ if ((_size = write(desc[1], &buffer[total], s)) != s) \
+ warn("short write; wrote %zd, expected %d", _size, s); \
+ total += _size; \
+ } while(0)
+
+ if (new_pid == 0) {
+ SYNC_R(0, go);
+ for (i = 0; i < 8; i++)
+ WRITE(4096);
+
+ SYNC_W(0, go2);
+ SYNC_R(0, go);
+
+ for (i = 0; i < 2; i++)
+ WRITE(4096);
+
+ SYNC_W(0, go2);
+
+ _exit(0);
+ }
+
+ SYNC_W(1, go);
+ SYNC_R(1, go2);
+
+ error = read(desc[0], &buffer2, 8 * 4096);
+ total += error;
+ printf("Read %d bytes\n", error);
+
+ SYNC_W(1, go);
+ SYNC_R(1, go2);
+
+ error = read(desc[0], &buffer2[total], 2 * 4096);
+ total += error;
+ printf("Read %d bytes, done\n", error);
+
+ if (memcmp(buffer, buffer2, total) != 0) {
+ for (i = 0; i < (size_t)total; i++) {
+ if (buffer[i] != buffer2[i]) {
+ buggy = 1;
+ printf("Location %zu input: %hhx "
+ "output: %hhx\n",
+ i, buffer[i], buffer2[i]);
+ }
+ }
+ }
+
+ waitpid(new_pid, NULL, 0);
+
+ if ((buggy == 1) || (total != 10 * 4096))
+ errx(1, "FAILED");
+ else
+ printf("SUCCESS\n");
+
+ exit(0);
+}
diff --git a/tests/sys/kern/pipe/pipe_wraparound_test.c b/tests/sys/kern/pipe/pipe_wraparound_test.c
new file mode 100644
index 0000000..1ee0203
--- /dev/null
+++ b/tests/sys/kern/pipe/pipe_wraparound_test.c
@@ -0,0 +1,140 @@
+/*
+Copyright (C) 2004 Michael J. Silbersack. 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 AUTHOR 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 AUTHOR 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/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * $FreeBSD$
+ * This program tests to make sure that wraparound writes and reads
+ * are working, assuming that 16K socket buffers are used. In order
+ * to really stress the pipe code with this test, kernel modifications
+ * nay be necessary.
+ */
+
+int main (void)
+{
+ char buffer[32768], buffer2[32768], go[] = "go", go2[] = "go2";
+ int desc[2], ipc_coord[2];
+ ssize_t error, total;
+ int buggy, i;
+ pid_t new_pid;
+
+ buggy = 0;
+ total = 0;
+
+ error = pipe(desc);
+ if (error == -1)
+ err(1, "Couldn't allocate data pipe");
+
+ error = pipe(ipc_coord);
+ if (error == -1)
+ err(1, "Couldn't allocate IPC coordination pipe");
+
+ buffer[0] = 'A';
+
+ for (i = 1; i < (int)sizeof(buffer); i++) {
+ buffer[i] = buffer[i - 1] + 1;
+ if (buffer[i] > 'Z')
+ buffer[i] = 'A';
+ }
+
+ new_pid = fork();
+ assert(new_pid != -1);
+
+#define SYNC_R(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: waiting for synchronization", __LINE__); \
+ if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+ errno = _error; \
+ } while(0)
+
+#define SYNC_W(i, _buf) do { \
+ int _error = errno; \
+ warnx("%d: sending synchronization", __LINE__); \
+ if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+ err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+ errno = _error; \
+ } while(0)
+
+#define WRITE(s) do { \
+ ssize_t _size; \
+ if ((_size = write(desc[1], &buffer[total], s)) != s) \
+ warn("short write; wrote %zd, expected %d", _size, s); \
+ total += _size; \
+ } while(0)
+
+ if (new_pid == 0) {
+ WRITE(4096);
+ WRITE(4096);
+ WRITE(4000);
+ SYNC_W(0, go2);
+
+ SYNC_R(0, go);
+ WRITE(3000);
+ WRITE(3000);
+ SYNC_W(0, go2);
+
+ _exit(0);
+ }
+
+ SYNC_R(1, go2);
+ error = read(desc[0], &buffer2, 8192);
+ total += error;
+ printf("Read %zd bytes\n", error);
+ SYNC_W(1, go);
+ SYNC_R(1, go2);
+ error = read(desc[0], &buffer2[total], 16384);
+ total += error;
+ printf("Read %zd bytes, done\n", error);
+
+ if (memcmp(buffer, buffer2, total) != 0) {
+ for (i = 0; i < total; i++) {
+ if (buffer[i] != buffer2[i]) {
+ buggy = 1;
+ printf("Location %d input: %hhx output: %hhx\n",
+ i, buffer[i], buffer2[i]);
+ }
+ }
+ }
+
+ waitpid(new_pid, NULL, 0);
+
+ if (buggy)
+ errx(1, "FAILURE");
+
+ printf("SUCCESS\n");
+
+ exit(0);
+}
OpenPOWER on IntegriCloud