summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/Makefile8
-rw-r--r--tests/sys/Makefile.inc3
-rw-r--r--tests/sys/fifo/Makefile13
-rw-r--r--tests/sys/fifo/fifo_create.c282
-rw-r--r--tests/sys/fifo/fifo_io.c1399
-rw-r--r--tests/sys/fifo/fifo_misc.c335
-rw-r--r--tests/sys/fifo/fifo_open.c476
-rw-r--r--tests/sys/file/Makefile25
-rw-r--r--tests/sys/file/closefrom_test.c275
-rw-r--r--tests/sys/file/dup_test.c386
-rw-r--r--tests/sys/file/fcntlflags_test.c110
-rw-r--r--tests/sys/file/flock_helper.c1598
-rwxr-xr-xtests/sys/file/flock_test.sh57
-rw-r--r--tests/sys/file/ftruncate_test.c177
-rw-r--r--tests/sys/file/newfileops_on_fork_test.c121
-rw-r--r--tests/sys/kqueue/Makefile26
-rw-r--r--tests/sys/kqueue/common.h78
-rw-r--r--tests/sys/kqueue/config.h13
-rwxr-xr-xtests/sys/kqueue/kqueue_test.sh17
-rw-r--r--tests/sys/kqueue/main.c284
-rw-r--r--tests/sys/kqueue/proc.c255
-rw-r--r--tests/sys/kqueue/read.c324
-rw-r--r--tests/sys/kqueue/signal.c199
-rw-r--r--tests/sys/kqueue/timer.c178
-rw-r--r--tests/sys/kqueue/user.c129
-rw-r--r--tests/sys/kqueue/vnode.c266
-rw-r--r--tests/sys/mmap/Makefile7
-rw-r--r--tests/sys/mmap/mmap.c105
-rw-r--r--tests/sys/mqueue/Makefile20
-rw-r--r--tests/sys/mqueue/mqtest1.c53
-rw-r--r--tests/sys/mqueue/mqtest2.c97
-rw-r--r--tests/sys/mqueue/mqtest3.c112
-rw-r--r--tests/sys/mqueue/mqtest4.c116
-rw-r--r--tests/sys/mqueue/mqtest5.c124
-rw-r--r--tests/sys/posixshm/Makefile10
-rw-r--r--tests/sys/posixshm/posixshm.c627
-rw-r--r--tests/sys/posixshm/test.c128
-rw-r--r--tests/sys/posixshm/test.h59
-rw-r--r--tests/sys/sockets/Makefile54
-rw-r--r--tests/sys/sockets/README.unix_cmsg160
-rw-r--r--tests/sys/sockets/accept_fd_leak_test.c215
-rw-r--r--tests/sys/sockets/accf_data_attach_test.c216
-rw-r--r--tests/sys/sockets/fstat_test.c71
-rw-r--r--tests/sys/sockets/kqueue_test.c368
-rw-r--r--tests/sys/sockets/listen_backlog_test.c383
-rw-r--r--tests/sys/sockets/listenclose_test.c111
-rw-r--r--tests/sys/sockets/pr_atomic_test.c109
-rw-r--r--tests/sys/sockets/reconnect_test.c132
-rw-r--r--tests/sys/sockets/rtsocket_test.c101
-rw-r--r--tests/sys/sockets/sblock_test.c207
-rw-r--r--tests/sys/sockets/sendfile_test.c486
-rw-r--r--tests/sys/sockets/shutdown_test.c110
-rw-r--r--tests/sys/sockets/sigpipe_test.c322
-rw-r--r--tests/sys/sockets/so_setfib_test.c200
-rw-r--r--tests/sys/sockets/socketpair_test.c161
-rw-r--r--tests/sys/sockets/unix_bindconnect_test.c318
-rw-r--r--tests/sys/sockets/unix_close_race_test.c143
-rw-r--r--tests/sys/sockets/unix_cmsg.c1969
-rw-r--r--tests/sys/sockets/unix_cmsg_test.sh85
-rw-r--r--tests/sys/sockets/unix_gc_test.c808
-rw-r--r--tests/sys/sockets/unix_passfd_test.c389
-rw-r--r--tests/sys/sockets/unix_sendtorace_test.c215
-rw-r--r--tests/sys/sockets/unix_socket_test.c84
-rw-r--r--tests/sys/sockets/unix_sorflush_test.c99
-rw-r--r--tests/sys/sockets/zerosend_test.c290
-rw-r--r--tests/sys/vfs/Makefile7
-rwxr-xr-xtests/sys/vfs/trailing_slash_test.sh41
67 files changed, 0 insertions, 16346 deletions
diff --git a/tests/sys/Makefile b/tests/sys/Makefile
index dc447d0..9225eab 100644
--- a/tests/sys/Makefile
+++ b/tests/sys/Makefile
@@ -4,17 +4,9 @@
TESTSDIR= ${TESTSBASE}/sys
-TESTS_SUBDIRS+= fifo
-TESTS_SUBDIRS+= file
TESTS_SUBDIRS+= kern
-TESTS_SUBDIRS+= kqueue
-TESTS_SUBDIRS+= mqueue
-TESTS_SUBDIRS+= mmap
TESTS_SUBDIRS+= netinet
TESTS_SUBDIRS+= opencrypto
-TESTS_SUBDIRS+= posixshm
-TESTS_SUBDIRS+= sockets
-TESTS_SUBDIRS+= vfs
# Items not integrated into kyua runs by default
SUBDIR+= pjdfstest
diff --git a/tests/sys/Makefile.inc b/tests/sys/Makefile.inc
deleted file mode 100644
index f341842..0000000
--- a/tests/sys/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD$
-
-WARNS?= 6
diff --git a/tests/sys/fifo/Makefile b/tests/sys/fifo/Makefile
deleted file mode 100644
index 602bf1e..0000000
--- a/tests/sys/fifo/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/fifo
-
-PLAIN_TESTS_C+= fifo_create
-PLAIN_TESTS_C+= fifo_io
-PLAIN_TESTS_C+= fifo_misc
-PLAIN_TESTS_C+= fifo_open
-
-TEST_METADATA.fifo_create+= required_user="root"
-TEST_METADATA.fifo_open+= required_user="root"
-
-.include <bsd.test.mk>
diff --git a/tests/sys/fifo/fifo_create.c b/tests/sys/fifo/fifo_create.c
deleted file mode 100644
index 2eb01e5..0000000
--- a/tests/sys/fifo/fifo_create.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*-
- * Copyright (c) 2005-2008 Robert N. M. Watson
- * 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/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Simple regression test for the creation and destruction of POSIX fifos in
- * the file system name space. Using a specially created directory, create
- * a fifo in it and check that the following properties are present, as
- * specified in IEEE Std 1003.1, 2004 Edition:
- *
- * - When mkfifo() or mknod(S_IFIFO) is called, on success, a fifo is
- * created.
- *
- * - On an error, no fifo is created. (XXX: Not tested)
- *
- * - The mode bits on the fifo are a product of combining the umask and
- * requested mode.
- *
- * - The fifo's owner will be the processes effective user ID. (XXX: Not
- * tested)
- *
- * - The fifo's group will be the parent directory's group or the effective
- * group ID of the process. For historical reasons, BSD prefers the group
- * ID of the process, so we will generate an error if it's not that. (XXX:
- * Not tested)
- *
- * - The st_atime, st_ctime, st_mtime of the fifo will be set appropriately,
- * and st_ctime and st_mtime on the directory will be updated. (XXX: We
- * test they are updated, not correct)
- *
- * - EEXIST is returned if the named file already exists.
- *
- * In addition, we check that we can unlink the fifo, and that if we do, it
- * disappears.
- *
- * This test must run as root in order to usefully frob the process
- * credential to test permission parts.
- */
-
-/*
- * All activity occurs within a temporary directory created early in the
- * test.
- */
-static char temp_dir[PATH_MAX];
-
-static void __unused
-atexit_temp_dir(void)
-{
-
- rmdir(temp_dir);
-}
-
-/*
- * Basic creation tests: verify that mkfifo(2) (or mknod(2)) creates a fifo,
- * that the time stamps on the directory are updated, that if we try twice we
- * get EEXIST, and that we can unlink it.
- */
-static void
-fifo_create_test(int use_mkfifo)
-{
- struct stat old_dirsb, dirsb, fifosb;
- const char *testname;
- char path[] = "testfifo";
- int error;
-
- if (use_mkfifo)
- testname = "mkfifo";
- else
- testname = "mknod";
-
- /*
- * Sleep to make sure that the time stamp on the directory will be
- * updated.
- */
- if (stat(".", &old_dirsb) < 0)
- err(-1, "basic_create_test: %s: stat: %s", testname,
- temp_dir);
-
- sleep(2);
-
- if (use_mkfifo) {
- if (mkfifo(path, 0600) < 0)
- err(-1, "basic_create_test: %s: %s", testname, path);
- } else {
- if (mknod(path, S_IFIFO | 0600, 0) < 0)
- err(-1, "basic_create_test: %s: %s", testname, path);
- }
-
- if (stat(path, &fifosb) < 0) {
- error = errno;
- (void)unlink(path);
- errno = error;
- err(-1, "basic_create_test: %s: stat: %s", testname, path);
- }
-
- if (!(S_ISFIFO(fifosb.st_mode))) {
- (void)unlink(path);
- errx(-1, "basic_create_test: %s produced non-fifo",
- testname);
- }
-
- if (use_mkfifo) {
- if (mkfifo(path, 0600) == 0)
- errx(-1, "basic_create_test: dup %s succeeded",
- testname);
- } else {
- if (mknod(path, S_IFIFO | 0600, 0) == 0)
- errx(-1, "basic_create_test: dup %s succeeded",
- testname);
- }
-
- if (errno != EEXIST)
- err(-1, "basic_create_test: dup %s unexpected error",
- testname);
-
- if (stat(".", &dirsb) < 0) {
- error = errno;
- (void)unlink(path);
- errno = error;
- err(-1, "basic_create_test: %s: stat: %s", testname,
- temp_dir);
- }
-
- if (old_dirsb.st_ctime == dirsb.st_ctime) {
- (void)unlink(path);
- errx(-1, "basic_create_test: %s: old_dirsb.st_ctime == "
- "dirsb.st_ctime", testname);
- }
-
- if (old_dirsb.st_mtime == dirsb.st_mtime) {
- (void)unlink(path);
- errx(-1, "basic_create_test: %s: old_dirsb.st_mtime == "
- "dirsb.st_mtime", testname);
- }
-
- if (unlink(path) < 0)
- err(-1, "basic_create_test: %s: unlink: %s", testname, path);
-
- if (stat(path, &fifosb) == 0)
- errx(-1, "basic_create_test: %s: unlink failed to unlink",
- testname);
- if (errno != ENOENT)
- err(-1, "basic_create_test: %s: unlink unexpected error",
- testname);
-}
-
-/*
- * Having determined that basic create/remove/etc functionality is present
- * for fifos, now make sure that the umask, requested permissions, and
- * resulting mode are handled properly.
- */
-static const struct permission_test {
- mode_t pt_umask;
- mode_t pt_reqmode;
- mode_t pt_mode;
-} permission_test[] = {
- {0000, 0, S_IFIFO},
- {0000, S_IRWXU, S_IFIFO | S_IRWXU},
- {0000, S_IRWXU | S_IRWXG | S_IRWXO, S_IFIFO | S_IRWXU | S_IRWXG |
- S_IRWXO },
- {0077, S_IRWXU, S_IFIFO | S_IRWXU},
- {0077, S_IRWXU | S_IRWXG | S_IRWXO, S_IFIFO | S_IRWXU},
-};
-static const int permission_test_count = sizeof(permission_test) /
- sizeof(struct permission_test);
-
-static void
-fifo_permission_test(int use_mkfifo)
-{
- const struct permission_test *ptp;
- mode_t __unused old_umask;
- char path[] = "testfifo";
- const char *testname;
- struct stat sb;
- int error, i;
-
- if (use_mkfifo)
- testname = "mkfifo";
- else
- testname = "mknod";
-
- old_umask = umask(0022);
- for (i = 0; i < permission_test_count; i++) {
- ptp = &permission_test[i];
-
- umask(ptp->pt_umask);
- if (use_mkfifo) {
- if (mkfifo(path, ptp->pt_reqmode) < 0)
- err(-1, "fifo_permission_test: %s: %08o "
- "%08o %08o\n", testname, ptp->pt_umask,
- ptp->pt_reqmode, ptp->pt_mode);
- } else {
- if (mknod(path, S_IFIFO | ptp->pt_reqmode, 0) < 0)
- err(-1, "fifo_permission_test: %s: %08o "
- "%08o %08o\n", testname, ptp->pt_umask,
- ptp->pt_reqmode, ptp->pt_mode);
- }
-
- if (stat(path, &sb) < 0) {
- error = errno;
- (void)unlink(path);
- errno = error;
- err(-1, "fifo_permission_test: %s: %s", testname,
- path);
- }
-
- if (sb.st_mode != ptp->pt_mode) {
- (void)unlink(path);
- errx(-1, "fifo_permission_test: %s: %08o %08o %08o "
- "got %08o", testname, ptp->pt_umask,
- ptp->pt_reqmode, ptp->pt_mode, sb.st_mode);
- }
-
- if (unlink(path) < 0)
- err(-1, "fifo_permission_test: %s: unlink: %s",
- testname, path);
- }
- umask(old_umask);
-}
-
-int
-main(void)
-{
- int i;
-
- if (geteuid() != 0)
- errx(-1, "must be run as root");
-
- strcpy(temp_dir, "fifo_create.XXXXXXXXXXX");
- if (mkdtemp(temp_dir) == NULL)
- err(-1, "mkdtemp");
- atexit(atexit_temp_dir);
-
- if (chdir(temp_dir) < 0)
- err(-1, "chdir");
-
- /*
- * Run each test twice, once with mknod(2) and a second time with
- * mkfifo(2). Historically, BSD has not allowed mknod(2) to be used
- * to create fifos, but the Single UNIX Specification requires it.
- */
- for (i = 0; i < 2; i++) {
- fifo_create_test(i);
- fifo_permission_test(i);
- }
-
- return (0);
-}
diff --git a/tests/sys/fifo/fifo_io.c b/tests/sys/fifo/fifo_io.c
deleted file mode 100644
index 93d4be7..0000000
--- a/tests/sys/fifo/fifo_io.c
+++ /dev/null
@@ -1,1399 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/event.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Regression test to exercise POSIX fifo I/O.
- *
- * We test a number of aspect of behavior, including:
- *
- * - If there's no data to read, then for blocking fifos, we block, and for
- * non-blocking, we return EAGAIN.
- *
- * - If we write ten bytes, ten bytes can be read, and they're the same
- * bytes, in the same order.
- *
- * - If we write two batches of five bytes, we can read the same ten bytes in
- * one read of ten bytes.
- *
- * - If we write ten bytes, we can read the same ten bytes in two reads of
- * five bytes each.
- *
- * - If we over-fill a buffer (by writing 512k, which we take to be a large
- * number above default buffer sizes), we block if there is no reader.
- *
- * - That once 512k (ish) is read from the other end, the blocked writer
- * wakes up.
- *
- * - When a fifo is empty, poll, select, kqueue, and fionread report it is
- * writable but not readable.
- *
- * - When a fifo has data in it, poll, select, and kqueue report that it is
- * writable.
- *
- * - XXX: blocked reader semantics?
- *
- * - XXX: event behavior on remote close?
- *
- * Although behavior of O_RDWR isn't defined for fifos by POSIX, we expect
- * "reasonable" behavior, and run some additional tests relating to event
- * management on O_RDWR fifo descriptors.
- */
-
-#define KQUEUE_MAX_EVENT 8
-
-/*
- * All activity occurs within a temporary directory created early in the
- * test.
- */
-static char temp_dir[PATH_MAX];
-
-static void __unused
-atexit_temp_dir(void)
-{
-
- rmdir(temp_dir);
-}
-
-static void
-makefifo(const char *fifoname, const char *testname)
-{
-
- if (mkfifo(fifoname, 0700) < 0)
- err(-1, "%s: makefifo: mkfifo: %s", testname, fifoname);
-}
-
-static void
-cleanfifo2(const char *fifoname, int fd1, int fd2)
-{
-
- if (fd1 != -1)
- close(fd1);
- if (fd2 != -1)
- close(fd2);
- (void)unlink(fifoname);
-}
-
-static void
-cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3)
-{
-
- if (fd3 != -1)
- close(fd3);
- cleanfifo2(fifoname, fd1, fd2);
-}
-
-/*
- * Open two different file descriptors for a fifo: one read, one write. Do
- * so using non-blocking opens in order to avoid deadlocking the process.
- */
-static int
-openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
-{
- int error, fd1, fd2;
-
- fd1 = open(fifoname, O_RDONLY | O_NONBLOCK);
- if (fd1 < 0)
- return (-1);
- fd2 = open(fifoname, O_WRONLY | O_NONBLOCK);
- if (fd2 < 0) {
- error = errno;
- close(fd1);
- errno = error;
- return (-1);
- }
- *reader_fdp = fd1;
- *writer_fdp = fd2;
-
- return (0);
-}
-
-/*
- * Open one file descriptor for the fifo, supporting both read and write.
- */
-static int
-openfifo_rw(const char *fifoname, int *fdp)
-{
- int fd;
-
- fd = open(fifoname, O_RDWR);
- if (fd < 0)
- return (-1);
- *fdp = fd;
-
- return (0);
-}
-
-static int
-set_nonblocking(int fd, const char *testname)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- warn("%s: fcntl(fd, F_GETFL)", testname);
- return(-1);
- }
-
- flags |= O_NONBLOCK;
-
- if (fcntl(fd, F_SETFL, flags) < 0) {
- warn("%s: fcntl(fd, 0x%x)", testname, flags);
- return (-1);
- }
-
- return (0);
-}
-
-static int
-set_blocking(int fd, const char *testname)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- warn("%s: fcntl(fd, F_GETFL)", testname);
- return(-1);
- }
-
- flags &= ~O_NONBLOCK;
-
- if (fcntl(fd, F_SETFL, flags) < 0) {
- warn("%s: fcntl(fd, 0x%x)", testname, flags);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Drain a file descriptor (fifo) of any readable data. Note: resets the
- * blocking state.
- */
-static int
-drain_fd(int fd, const char *testname)
-{
- ssize_t len;
- u_char ch;
-
- if (set_nonblocking(fd, testname) < 0)
- return (-1);
-
- while ((len = read(fd, &ch, sizeof(ch))) > 0);
- if (len < 0) {
- switch (errno) {
- case EAGAIN:
- return (0);
- default:
- warn("%s: drain_fd: read", testname);
- return (-1);
- }
- }
- warn("%s: drain_fd: read: returned 0 bytes", testname);
- return (-1);
-}
-
-/*
- * Simple I/O test: write ten integers, and make sure we get back the same
- * integers in the same order. This assumes a minimum fifo buffer > 10
- * bytes in order to not block and deadlock.
- */
-static void
-test_simpleio(void)
-{
- int i, reader_fd, writer_fd;
- u_char buffer[10];
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd)
- < 0) {
- warn("test_simpleio: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- for (i = 0; i < 10; i++)
- buffer[i] = i;
-
- len = write(writer_fd, (char *)buffer, sizeof(buffer));
- if (len < 0) {
- warn("test_simpleio: write");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(buffer)) {
- warnx("test_simplio: tried %zu but wrote %zd", sizeof(buffer),
- len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- len = read(reader_fd, (char *)buffer, sizeof(buffer));
- if (len < 0) {
- warn("test_simpleio: read");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(buffer)) {
- warnx("test_simpleio: tried %zu but read %zd", sizeof(buffer),
- len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- for (i = 0; i < 10; i++) {
- if (buffer[i] == i)
- continue;
- warnx("test_simpleio: write byte %d as 0x%02x, but read "
- "0x%02x", i, i, buffer[i]);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-static volatile int alarm_fired;
-/*
- * Non-destructive SIGALRM handler.
- */
-static void
-sigalarm(int signum __unused)
-{
-
- alarm_fired = 1;
-}
-
-/*
- * Wrapper function for write, which uses a timer to interrupt any blocking.
- * Because we can't reliably detect EINTR for blocking I/O, we also track
- * whether or not our timeout fired.
- */
-static int __unused
-timed_write(int fd, void *data, size_t len, ssize_t *written_lenp,
- int timeout, int *timedoutp, const char *testname)
-{
- struct sigaction act, oact;
- ssize_t written_len;
- int error;
-
- alarm_fired = 0;
- bzero(&act, sizeof(oact));
- act.sa_handler = sigalarm;
- if (sigaction(SIGALRM, &act, &oact) < 0) {
- warn("%s: timed_write: sigaction", testname);
- return (-1);
- }
- alarm(timeout);
- written_len = write(fd, data, len);
- error = errno;
- alarm(0);
- if (sigaction(SIGALRM, &oact, NULL) < 0) {
- warn("%s: timed_write: sigaction", testname);
- return (-1);
- }
- if (alarm_fired)
- *timedoutp = 1;
- else
- *timedoutp = 0;
-
- errno = error;
- if (written_len < 0)
- return (-1);
- *written_lenp = written_len;
- return (0);
-}
-
-/*
- * Wrapper function for read, which uses a timer to interrupt any blocking.
- * Because we can't reliably detect EINTR for blocking I/O, we also track
- * whether or not our timeout fired.
- */
-static int
-timed_read(int fd, void *data, size_t len, ssize_t *read_lenp,
- int timeout, int *timedoutp, const char *testname)
-{
- struct sigaction act, oact;
- ssize_t read_len;
- int error;
-
- alarm_fired = 0;
- bzero(&act, sizeof(oact));
- act.sa_handler = sigalarm;
- if (sigaction(SIGALRM, &act, &oact) < 0) {
- warn("%s: timed_write: sigaction", testname);
- return (-1);
- }
- alarm(timeout);
- read_len = read(fd, data, len);
- error = errno;
- alarm(0);
- if (sigaction(SIGALRM, &oact, NULL) < 0) {
- warn("%s: timed_write: sigaction", testname);
- return (-1);
- }
- if (alarm_fired)
- *timedoutp = 1;
- else
- *timedoutp = 0;
-
- errno = error;
- if (read_len < 0)
- return (-1);
- *read_lenp = read_len;
- return (0);
-}
-
-/*
- * This test operates on blocking and non-blocking fifo file descriptors, in
- * order to determine whether they block at good moments or not. By good we
- * mean: don't block for non-blocking sockets, and do block for blocking
- * ones, assuming there isn't I/O buffer to satisfy the request.
- *
- * We use a timeout of 5 seconds, concluding that in 5 seconds either all I/O
- * that can take place will, and that if we reach the end of the timeout,
- * then blocking has occurred.
- *
- * We assume that the buffer size on a fifo is <512K, and as such, that
- * writing that much data without an active reader will result in blocking.
- */
-static void
-test_blocking_read_empty(void)
-{
- int reader_fd, ret, timedout, writer_fd;
- ssize_t len;
- u_char ch;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd)
- < 0) {
- warn("test_blocking_read_empty: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- /*
- * Read one byte from an empty blocking fifo, block as there is no
- * data.
- */
- if (set_blocking(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret != -1) {
- warnx("test_blocking_read_empty: timed_read: returned "
- "success");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (errno != EINTR) {
- warn("test_blocking_read_empty: timed_read");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- /*
- * Read one byte from an empty non-blocking fifo, return EAGAIN as
- * there is no data.
- */
- if (set_nonblocking(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret != -1) {
- warnx("test_blocking_read_empty: timed_read: returned "
- "success");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (errno != EAGAIN) {
- warn("test_blocking_read_empty: timed_read");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * Write one byte to an empty fifo, then try to read one byte and make sure
- * we don't block in either the write or the read. This tests both for
- * improper blocking in the send and receive code.
- */
-static void
-test_blocking_one_byte(void)
-{
- int reader_fd, ret, timedout, writer_fd;
- ssize_t len;
- u_char ch;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_blocking: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- if (set_blocking(writer_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (set_blocking(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ch = 0xfe;
- ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_blocking_one_byte: timed_write");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(ch)) {
- warnx("test_blocking_one_byte: timed_write: tried to write "
- "%zu, wrote %zd", sizeof(ch), len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ch = 0xab;
- ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_blocking_one_byte: timed_read");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(ch)) {
- warnx("test_blocking_one_byte: timed_read: wanted %zu, "
- "read %zd", sizeof(ch), len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (ch != 0xfe) {
- warnx("test_blocking_one_byte: timed_read: expected to read "
- "0x%02x, read 0x%02x", 0xfe, ch);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * Write one byte to an empty fifo, then try to read one byte and make sure
- * we don't get back EAGAIN.
- */
-static void
-test_nonblocking_one_byte(void)
-{
- int reader_fd, ret, timedout, writer_fd;
- ssize_t len;
- u_char ch;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_nonblocking: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- if (set_nonblocking(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ch = 0xfe;
- ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_nonblocking_one_byte: timed_write");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(ch)) {
- warnx("test_nonblocking_one_byte: timed_write: tried to write "
- "%zu, wrote %zd", sizeof(ch), len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- ch = 0xab;
- ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_nonblocking_one_byte: timed_read");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != sizeof(ch)) {
- warnx("test_nonblocking_one_byte: timed_read: wanted %zu, read "
- "%zd", sizeof(ch), len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (ch != 0xfe) {
- warnx("test_nonblocking_one_byte: timed_read: expected to read "
- "0x%02x, read 0x%02x", 0xfe, ch);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * First of two test cases involving a 512K buffer: write the buffer into a
- * blocking file descriptor. We'd like to know it blocks, but the closest we
- * can get is to see if SIGALRM fired during the I/O resulting in a partial
- * write.
- */
-static void
-test_blocking_partial_write(void)
-{
- int reader_fd, ret, timedout, writer_fd;
- u_char *buffer;
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_blocking_partial_write: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- if (set_blocking(writer_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- buffer = malloc(512*1024);
- if (buffer == NULL) {
- warn("test_blocking_partial_write: malloc");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- bzero(buffer, 512*1024);
-
- ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_blocking_partial_write: timed_write");
- free(buffer);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (!timedout) {
- warnx("test_blocking_partial_write: timed_write: blocking "
- "socket didn't time out");
- free(buffer);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- free(buffer);
-
- if (drain_fd(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * Write a 512K buffer to an empty fifo using a non-blocking file descriptor,
- * and make sure it doesn't block.
- */
-static void
-test_nonblocking_partial_write(void)
-{
- int reader_fd, ret, timedout, writer_fd;
- u_char *buffer;
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_blocking_partial_write: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- if (set_nonblocking(writer_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- buffer = malloc(512*1024);
- if (buffer == NULL) {
- warn("test_blocking_partial_write: malloc");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- bzero(buffer, 512*1024);
-
- ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
- __func__);
- if (ret < 0) {
- warn("test_blocking_partial_write: timed_write");
- free(buffer);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (timedout) {
- warnx("test_blocking_partial_write: timed_write: "
- "non-blocking socket timed out");
- free(buffer);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (len == 0 || len >= 512*1024) {
- warnx("test_blocking_partial_write: timed_write: requested "
- "%d, sent %zd", 512*1024, len);
- free(buffer);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- free(buffer);
-
- if (drain_fd(reader_fd, __func__) < 0) {
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * test_coalesce_big_read() verifies that data mingles in the fifo across
- * message boundaries by performing two small writes, then a bigger read
- * that should return data from both writes.
- */
-static void
-test_coalesce_big_read(void)
-{
- int i, reader_fd, writer_fd;
- u_char buffer[10];
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_coalesce_big_read: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- /* Write five, write five, read ten. */
- for (i = 0; i < 10; i++)
- buffer[i] = i;
-
- len = write(writer_fd, buffer, 5);
- if (len < 0) {
- warn("test_coalesce_big_read: write 5");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 5) {
- warnx("test_coalesce_big_read: write 5 wrote %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- len = write(writer_fd, buffer + 5, 5);
- if (len < 0) {
- warn("test_coalesce_big_read: write 5");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 5) {
- warnx("test_coalesce_big_read: write 5 wrote %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- len = read(reader_fd, buffer, 10);
- if (len < 0) {
- warn("test_coalesce_big_read: read 10");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 10) {
- warnx("test_coalesce_big_read: read 10 read %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- for (i = 0; i < 10; i++) {
- if (buffer[i] == i)
- continue;
- warnx("test_coalesce_big_read: expected to read 0x%02x, "
- "read 0x%02x", i, buffer[i]);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", -1, -1);
-}
-
-/*
- * test_coalesce_big_write() verifies that data mingles in the fifo across
- * message boundaries by performing one big write, then two smaller reads
- * that should return sequential elements of data from the write.
- */
-static void
-test_coalesce_big_write(void)
-{
- int i, reader_fd, writer_fd;
- u_char buffer[10];
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_coalesce_big_write: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- /* Write ten, read five, read five. */
- for (i = 0; i < 10; i++)
- buffer[i] = i;
-
- len = write(writer_fd, buffer, 10);
- if (len < 0) {
- warn("test_coalesce_big_write: write 10");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 10) {
- warnx("test_coalesce_big_write: write 10 wrote %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- len = read(reader_fd, buffer, 5);
- if (len < 0) {
- warn("test_coalesce_big_write: read 5");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 5) {
- warnx("test_coalesce_big_write: read 5 read %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- len = read(reader_fd, buffer + 5, 5);
- if (len < 0) {
- warn("test_coalesce_big_write: read 5");
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (len != 5) {
- warnx("test_coalesce_big_write: read 5 read %zd", len);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- for (i = 0; i < 10; i++) {
- if (buffer[i] == i)
- continue;
- warnx("test_coalesce_big_write: expected to read 0x%02x, "
- "read 0x%02x", i, buffer[i]);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", -1, -1);
-}
-
-static int
-poll_status(int fd, int *readable, int *writable, int *exception,
- const char *testname)
-{
- struct pollfd fds[1];
-
- fds[0].fd = fd;
- fds[0].events = POLLIN | POLLOUT | POLLERR;
- fds[0].revents = 0;
-
- if (poll(fds, 1, 0) < 0) {
- warn("%s: poll", testname);
- return (-1);
- }
- *readable = (fds[0].revents & POLLIN) ? 1 : 0;
- *writable = (fds[0].revents & POLLOUT) ? 1 : 0;
- *exception = (fds[0].revents & POLLERR) ? 1 : 0;
- return (0);
-}
-
-static int
-select_status(int fd, int *readable, int *writable, int *exception,
- const char *testname)
-{
- struct fd_set readfds, writefds, exceptfds;
- struct timeval timeout;
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptfds);
- FD_SET(fd, &readfds);
- FD_SET(fd, &writefds);
- FD_SET(fd, &exceptfds);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- if (select(fd+1, &readfds, &writefds, &exceptfds, &timeout) < 0) {
- warn("%s: select", testname);
- return (-1);
- }
- *readable = FD_ISSET(fd, &readfds) ? 1 : 0;
- *writable = FD_ISSET(fd, &writefds) ? 1 : 0;
- *exception = FD_ISSET(fd, &exceptfds) ? 1 : 0;
- return (0);
-}
-
-/*
- * Given an existing kqueue, set up read and write event filters for the
- * passed file descriptor. Typically called once for the read endpoint, and
- * once for the write endpoint.
- */
-static int
-kqueue_setup(int kqueue_fd, int fd, const char *testname)
-{
- struct kevent kevent_changelist[2];
- struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
- struct timespec timeout;
- int i, ret;
-
- timeout.tv_sec = 0;
- timeout.tv_nsec = 0;
-
- bzero(&kevent_changelist, sizeof(kevent_changelist));
- EV_SET(&kevent_changelist[0], fd, EVFILT_READ, EV_ADD, 0, 0, 0);
- EV_SET(&kevent_changelist[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
-
- bzero(&kevent_eventlist, sizeof(kevent_eventlist));
- ret = kevent(kqueue_fd, kevent_changelist, 2, kevent_eventlist,
- KQUEUE_MAX_EVENT, &timeout);
- if (ret < 0) {
- warn("%s:%s: kevent initial register", testname, __func__);
- return (-1);
- }
-
- /*
- * Verify that the events registered alright.
- */
- for (i = 0; i < ret; i++) {
- kp = &kevent_eventlist[i];
- if (kp->flags != EV_ERROR)
- continue;
- errno = kp->data;
- warn("%s:%s: kevent register index %d", testname, __func__,
- i);
- return (-1);
- }
-
- return (0);
-}
-
-static int
-kqueue_status(int kqueue_fd, int fd, int *readable, int *writable,
- int *exception, const char *testname)
-{
- struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
- struct timespec timeout;
- int i, ret;
-
- timeout.tv_sec = 0;
- timeout.tv_nsec = 0;
-
- ret = kevent(kqueue_fd, NULL, 0, kevent_eventlist, KQUEUE_MAX_EVENT,
- &timeout);
- if (ret < 0) {
- warn("%s: %s: kevent", testname, __func__);
- return (-1);
- }
-
- *readable = *writable = *exception = 0;
- for (i = 0; i < ret; i++) {
- kp = &kevent_eventlist[i];
- if (kp->ident != (u_int)fd)
- continue;
- if (kp->filter == EVFILT_READ)
- *readable = 1;
- if (kp->filter == EVFILT_WRITE)
- *writable = 1;
- }
-
- return (0);
-}
-
-static int
-fionread_status(int fd, int *readable, const char *testname)
-{
- int i;
-
- if (ioctl(fd, FIONREAD, &i) < 0) {
- warn("%s: ioctl(FIONREAD)", testname);
- return (-1);
- }
-
- if (i > 0)
- *readable = 1;
- else
- *readable = 0;
- return (0);
-}
-
-#define READABLE 1
-#define WRITABLE 1
-#define EXCEPTION 1
-
-#define NOT_READABLE 0
-#define NOT_WRITABLE 0
-#define NOT_EXCEPTION 0
-
-static int
-assert_status(int fd, int kqueue_fd, int assert_readable,
- int assert_writable, int assert_exception, const char *testname,
- const char *conditionname, const char *fdname)
-{
- int readable, writable, exception;
-
- if (poll_status(fd, &readable, &writable, &exception, testname) < 0)
- return (-1);
-
- if (readable != assert_readable || writable != assert_writable ||
- exception != assert_exception) {
- warnx("%s: %s polls r:%d, w:%d, e:%d on %s", testname,
- fdname, readable, writable, exception, conditionname);
- return (-1);
- }
-
- if (select_status(fd, &readable, &writable, &exception, testname) < 0)
- return (-1);
-
- if (readable != assert_readable || writable != assert_writable ||
- exception != assert_exception) {
- warnx("%s: %s selects r:%d, w:%d, e:%d on %s", testname,
- fdname, readable, writable, exception, conditionname);
- return (-1);
- }
-
- if (kqueue_status(kqueue_fd, fd, &readable, &writable, &exception,
- testname) < 0)
- return (-1);
-
- if (readable != assert_readable || writable != assert_writable ||
- exception != assert_exception) {
- warnx("%s: %s kevent r:%d, w:%d, e:%d on %s", testname,
- fdname, readable, writable, exception, conditionname);
- return (-1);
- }
-
- if (fionread_status(fd, &readable, __func__) < 0)
- return (-1);
-
- if (readable != assert_readable) {
- warnx("%s: %s fionread r:%d on %s", testname, fdname,
- readable, conditionname);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * test_events() uses poll(), select(), and kevent() to query the status of
- * fifo file descriptors and determine whether they match expected state
- * based on earlier semantic tests: specifically, whether or not poll/select/
- * kevent will correctly inform on readable/writable state following I/O.
- *
- * It would be nice to also test status changes as a result of closing of one
- * or another fifo endpoint.
- */
-static void
-test_events_outofbox(void)
-{
- int kqueue_fd, reader_fd, writer_fd;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_events_outofbox: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- kqueue_fd = kqueue();
- if (kqueue_fd < 0) {
- warn("%s: kqueue", __func__);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Make sure that fresh, out-of-the-box fifo file descriptors have
- * good initial states. The reader_fd should have no active state,
- * since it will not be readable (no data in pipe), writable (it's
- * a read-only descriptor), and there's no reason for error yet.
- */
- if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
- NOT_EXCEPTION, __func__, "create", "reader_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Make sure that fresh, out-of-the-box fifo file descriptors have
- * good initial states. The writer_fd should be ready to write.
- */
- if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "create", "writer_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
-}
-
-static void
-test_events_write_read_byte(void)
-{
- int kqueue_fd, reader_fd, writer_fd;
- ssize_t len;
- u_char ch;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_events_write_read_byte: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- kqueue_fd = kqueue();
- if (kqueue_fd < 0) {
- warn("%s: kqueue", __func__);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Write a byte to the fifo, and make sure that the read end becomes
- * readable, and that the write end remains writable (small write).
- */
- ch = 0x00;
- len = write(writer_fd, &ch, sizeof(ch));
- if (len < 0) {
- warn("%s: write", __func__);
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (assert_status(reader_fd, kqueue_fd, READABLE, NOT_WRITABLE,
- NOT_EXCEPTION, __func__, "write", "reader_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * the writer_fd should remain writable.
- */
- if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "write", "writer_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Read the byte from the reader_fd, and now confirm that that fifo
- * becomes unreadable.
- */
- len = read(reader_fd, &ch, sizeof(ch));
- if (len < 0) {
- warn("%s: read", __func__);
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
- NOT_EXCEPTION, __func__, "write+read", "reader_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * The writer_fd should remain writable.
- */
- if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "write+read", "writer_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
-}
-
-/*
- * Write a 512k buffer to the fifo in non-blocking mode, and make sure that
- * the write end becomes un-writable as a result of a partial write that
- * fills the fifo buffer.
- */
-static void
-test_events_partial_write(void)
-{
- int kqueue_fd, reader_fd, writer_fd;
- u_char *buffer;
- ssize_t len;
-
- makefifo("testfifo", __func__);
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("test_events_partial_write: openfifo: testfifo");
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- kqueue_fd = kqueue();
- if (kqueue_fd < 0) {
- warn("%s: kqueue", __func__);
- cleanfifo2("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (set_nonblocking(writer_fd, "test_events") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- buffer = malloc(512*1024);
- if (buffer == NULL) {
- warn("test_events_partial_write: malloc");
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
- bzero(buffer, 512*1024);
-
- len = write(writer_fd, buffer, 512*1024);
- if (len < 0) {
- warn("test_events_partial_write: write");
- free(buffer);
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- free(buffer);
-
- if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
- NOT_EXCEPTION, __func__, "big write", "writer_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (drain_fd(reader_fd, "test_events") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Test that the writer_fd has been restored to writable state after
- * draining.
- */
- if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "big write + drain", "writer_fd") < 0) {
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
-}
-
-/*
- * We don't comprehensively test O_RDWR file descriptors, but do run a couple
- * of event tests to make sure that the fifo implementation doesn't mixed up
- * status checks. In particular, at least one past FreeBSD bug exists in
- * which the FIONREAD test was performed on the wrong socket implementing the
- * fifo, resulting in the fifo never returning readable.
- */
-static void
-test_events_rdwr(void)
-{
- int fd, kqueue_fd;
- ssize_t len;
- char ch;
-
- makefifo("testfifo", __func__);
- if (openfifo_rw("testfifo", &fd) < 0) {
- warn("%s: openfifo_rw: testfifo", __func__);
- cleanfifo2("testfifo", -1, -1);
- exit(-1);
- }
-
- kqueue_fd = kqueue();
- if (kqueue_fd < 0) {
- warn("%s: kqueue", __func__);
- cleanfifo2("testifo", fd, -1);
- exit(-1);
- }
-
- if (kqueue_setup(kqueue_fd, fd, __func__) < 0) {
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * On first creation, the O_RDWR descriptor should be writable but
- * not readable.
- */
- if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "create", "fd") < 0) {
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Write a byte, which should cause the file descriptor to become
- * readable and writable.
- */
- ch = 0x00;
- len = write(fd, &ch, sizeof(ch));
- if (len < 0) {
- warn("%s: write", __func__);
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- if (assert_status(fd, kqueue_fd, READABLE, WRITABLE, NOT_EXCEPTION,
- __func__, "write", "fd") < 0) {
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- /*
- * Read a byte, which should cause the file descriptor to return to
- * simply being writable.
- */
- len = read(fd, &ch, sizeof(ch));
- if (len < 0) {
- warn("%s: read", __func__);
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
- NOT_EXCEPTION, __func__, "write+read", "fd") < 0) {
- cleanfifo2("testfifo", fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifo2("testfifo", fd, kqueue_fd);
-}
-
-int
-main(void)
-{
-
- strcpy(temp_dir, "fifo_io.XXXXXXXXXXX");
- if (mkdtemp(temp_dir) == NULL)
- err(-1, "mkdtemp");
- atexit(atexit_temp_dir);
-
- if (chdir(temp_dir) < 0)
- err(-1, "chdir %s", temp_dir);
-
- test_simpleio();
- test_blocking_read_empty();
- test_blocking_one_byte();
- test_nonblocking_one_byte();
- test_blocking_partial_write();
- test_nonblocking_partial_write();
- test_coalesce_big_read();
- test_coalesce_big_write();
- test_events_outofbox();
- test_events_write_read_byte();
- test_events_partial_write();
- test_events_rdwr();
-
- return (0);
-}
diff --git a/tests/sys/fifo/fifo_misc.c b/tests/sys/fifo/fifo_misc.c
deleted file mode 100644
index 888547e..0000000
--- a/tests/sys/fifo/fifo_misc.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * Copyright (c) 2012 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/types.h>
-#include <sys/event.h>
-#include <sys/filio.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Regression test for piddling details of fifos.
- */
-
-/*
- * All activity occurs within a temporary directory created early in the
- * test.
- */
-static char temp_dir[PATH_MAX];
-
-static void __unused
-atexit_temp_dir(void)
-{
-
- rmdir(temp_dir);
-}
-
-static void
-makefifo(const char *fifoname, const char *testname)
-{
-
- if (mkfifo(fifoname, 0700) < 0)
- err(-1, "%s: makefifo: mkfifo: %s", testname, fifoname);
-}
-
-static void
-cleanfifo(const char *fifoname, int fd1, int fd2)
-{
-
- if (fd1 != -1)
- close(fd1);
- if (fd2 != -1)
- close(fd2);
- (void)unlink(fifoname);
-}
-
-static int
-openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
-{
- int error, fd1, fd2;
-
- fd1 = open(fifoname, O_RDONLY | O_NONBLOCK);
- if (fd1 < 0)
- return (-1);
- fd2 = open(fifoname, O_WRONLY | O_NONBLOCK);
- if (fd2 < 0) {
- error = errno;
- close(fd1);
- errno = error;
- return (-1);
- }
- *reader_fdp = fd1;
- *writer_fdp = fd2;
-
- return (0);
-}
-
-/*
- * POSIX does not allow lseek(2) on fifos, so we expect ESPIPE as a result.
- */
-static void
-test_lseek(void)
-{
- int reader_fd, writer_fd;
-
- makefifo("testfifo", __func__);
-
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("%s: openfifo", __func__);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- if (lseek(reader_fd, 1, SEEK_CUR) >= 0) {
- warnx("%s: lseek succeeded instead of returning ESPIPE",
- __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (errno != ESPIPE) {
- warn("%s: lseek returned instead of ESPIPE", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * truncate(2) on FIFO should silently return success.
- */
-static void
-test_truncate(void)
-{
-
- makefifo("testfifo", __func__);
-
- if (truncate("testfifo", 1024) != 0) {
- warn("%s: truncate", __func__);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- cleanfifo("testfifo", -1, -1);
-}
-
-static int
-test_ioctl_setclearflag(int fd, int flag, const char *testname,
- const char *fdname, const char *flagname)
-{
- int i;
-
- i = 1;
- if (ioctl(fd, flag, &i) < 0) {
- warn("%s:%s: ioctl(%s, %s, 1)", testname, __func__, fdname,
- flagname);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- i = 0;
- if (ioctl(fd, flag, &i) < 0) {
- warn("%s:%s: ioctl(%s, %s, 0)", testname, __func__, fdname,
- flagname);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- return (0);
-}
-
-/*
- * Test that various ioctls can be issued against the file descriptor. We
- * don't currently test the semantics of these changes here.
- */
-static void
-test_ioctl(void)
-{
- int reader_fd, writer_fd;
-
- makefifo("testfifo", __func__);
-
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("%s: openfifo", __func__);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- /*
- * Set and remove the non-blocking I/O flag.
- */
- if (test_ioctl_setclearflag(reader_fd, FIONBIO, __func__,
- "reader_fd", "FIONBIO") < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (test_ioctl_setclearflag(writer_fd, FIONBIO, __func__,
- "writer_fd", "FIONBIO") < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- /*
- * Set and remove the async I/O flag.
- */
- if (test_ioctl_setclearflag(reader_fd, FIOASYNC, __func__,
- "reader_fd", "FIOASYNC") < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (test_ioctl_setclearflag(writer_fd, FIOASYNC, __func__,
- "writer_fd", "FIONASYNC") < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo("testfifo", reader_fd, writer_fd);
-}
-
-/*
- * fchmod(2)/fchown(2) on FIFO should work.
- */
-static void
-test_chmodchown(void)
-{
- struct stat sb;
- int reader_fd, writer_fd;
- uid_t u;
- gid_t g;
-
- makefifo("testfifo", __func__);
-
- if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
- warn("%s: openfifo", __func__);
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- if (fchmod(reader_fd, 0666) != 0) {
- warn("%s: fchmod", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (stat("testfifo", &sb) != 0) {
- warn("%s: stat", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if ((sb.st_mode & 0777) != 0666) {
- warnx("%s: stat chmod result", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (fstat(writer_fd, &sb) != 0) {
- warn("%s: fstat", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if ((sb.st_mode & 0777) != 0666) {
- warnx("%s: fstat chmod result", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (fchown(reader_fd, -1, -1) != 0) {
- warn("%s: fchown 1", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- u = geteuid();
- if (u == 0)
- u = 1;
- g = getegid();
- if (fchown(reader_fd, u, g) != 0) {
- warn("%s: fchown 2", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
- if (stat("testfifo", &sb) != 0) {
- warn("%s: stat", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (sb.st_uid != u || sb.st_gid != g) {
- warnx("%s: stat chown result", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (fstat(writer_fd, &sb) != 0) {
- warn("%s: fstat", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- if (sb.st_uid != u || sb.st_gid != g) {
- warnx("%s: fstat chown result", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- cleanfifo("testfifo", -1, -1);
-}
-
-int
-main(void)
-{
-
- strcpy(temp_dir, "fifo_misc.XXXXXXXXXXX");
- if (mkdtemp(temp_dir) == NULL)
- err(-1, "mkdtemp");
- atexit(atexit_temp_dir);
-
- if (chdir(temp_dir) < 0)
- err(-1, "chdir %s", temp_dir);
-
- test_lseek();
- test_truncate();
- test_ioctl();
- test_chmodchown();
-
- return (0);
-}
diff --git a/tests/sys/fifo/fifo_open.c b/tests/sys/fifo/fifo_open.c
deleted file mode 100644
index 892f481..0000000
--- a/tests/sys/fifo/fifo_open.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Regression test to exercise various POSIX-defined parts of fifo behavior
- * described for open(2):
- *
- * O_NONBLOCK
- * When opening a FIFO with O_RDONLY or O_WRONLY set:
- *
- * - If O_NONBLOCK is set, an open() for reading-only shall return without
- * delay. An open() for writing-only shall return an error if no process
- * currently has the file open for reading.
- *
- * - If O_NONBLOCK is clear, an open() for reading-only shall block the
- * calling thread until a thread opens the file for writing. An open()
- * for writing-only shall block the calling thread until a thread opens
- * the file for reading.
- *
- * When opening a block special or character special file that supports
- * non-blocking opens:
- *
- * - If O_NONBLOCK is set, the open() function shall return without blocking
- * for the device to be ready or available. Subsequent behavior of the
- * device is device-specific.
- *
- * - If O_NONBLOCK is clear, the open() function shall block the calling
- * thread until the device is ready or available before returning.
- *
- * Special errors:
- *
- * [ENXIO]
- * O_NONBLOCK is set, the named file is a FIFO, O_WRONLY is set, and no
- * process has the file open for reading.
- */
-
-/*
- * In order to test blocking/non-blocking behavior, test processes must
- * potentially block themselves until released. As bugs in blocking result
- * in processes that won't un-block, we must sacrifice a process to the task,
- * watching and potentially killing it after a time-out. The main test
- * process is never used to open or act directly on a fifo (other than to
- * create or unlink it) in order to avoid the main test process being
- * blocked.
- */
-
-/*
- * All activity occurs within a temporary directory created early in the
- * test.
- */
-static char temp_dir[PATH_MAX];
-
-static void __unused
-atexit_temp_dir(void)
-{
-
- rmdir(temp_dir);
-}
-
-/*
- * Run a function in a particular test process.
- */
-static int
-run_in_process(int (*func)(void), pid_t *pidp, const char *errstr)
-{
- pid_t pid;
-
- pid = fork();
- if (pid < 0) {
- warn("%s: run_in_process: fork", errstr);
- return (-1);
- }
-
- if (pid == 0)
- exit(func());
-
- if (pidp != NULL)
- *pidp = pid;
-
- return (0);
-}
-
-/*
- * Wait for a process on a timeout, and if the timeout expires, kill the
- * process. Test each second rather than waiting the full timeout at once to
- * minimize the amount of time spent hanging around unnecessarily.
- */
-static int
-wait_and_timeout(pid_t pid, int timeout, int *status, const char *errstr)
-{
- pid_t wpid;
- int i;
-
- /*
- * Count up to the timeout, but do a non-hanging waitpid() after each
- * second so we can avoid waiting a lot of extra time.
- */
- for (i = 0; i < timeout; i++) {
- wpid = waitpid(pid, status, WNOHANG);
- if (wpid < 0) {
- warn("%s: wait_and_timeout: waitpid %d", errstr, pid);
- return (-1);
- }
-
- if (wpid == pid)
- return (0);
-
- sleep(1);
- }
-
- wpid = waitpid(pid, status, WNOHANG);
- if (wpid < 0) {
- warn("%s: wait_and_timeout: waitpid %d", errstr, pid);
- return (-1);
- }
-
- if (wpid == pid)
- return (0);
-
- if (kill(pid, SIGTERM) < 0) {
- warn("%s: wait_and_timeout: kill %d", errstr, pid);
- return (-1);
- }
-
- wpid = waitpid(pid, status, 0);
- if (wpid < 0) {
- warn("%s: wait_and_timeout: waitpid %d", errstr, pid);
- return (-1);
- }
-
- if (wpid != pid) {
- warn("%s: waitpid: returned %d not %d", errstr, wpid, pid);
- return (-1);
- }
-
- warnx("%s: process blocked", errstr);
- return (-1);
-}
-
-static int
-non_blocking_open_reader(void)
-{
- int fd;
-
- fd = open("testfifo", O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return (errno);
- close(fd);
-
- return (0);
-}
-
-static int
-non_blocking_open_writer(void)
-{
- int fd;
-
- fd = open("testfifo", O_WRONLY | O_NONBLOCK);
- if (fd < 0)
- return (errno);
- close(fd);
-
- return (0);
-}
-
-static int
-blocking_open_reader(void)
-{
- int fd;
-
- fd = open("testfifo", O_RDONLY);
- if (fd < 0)
- return (errno);
- close(fd);
-
- return (0);
-}
-
-static int
-blocking_open_writer(void)
-{
- int fd;
-
- fd = open("testfifo", O_WRONLY);
- if (fd < 0)
- return (errno);
- close(fd);
-
- return (0);
-}
-
-static void
-test_blocking_reader(void)
-{
- pid_t reader_pid, writer_pid, wpid;
- int error, status;
-
- if (mkfifo("testfifo", 0600) < 0)
- err(-1, "test_blocking_reader: mkfifo: testfifo");
-
- /*
- * Block a process in opening the fifo.
- */
- if (run_in_process(blocking_open_reader, &reader_pid,
- "test_blocking_reader: blocking_open_reader") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- /*
- * Test that it blocked.
- */
- sleep(5);
- wpid = waitpid(reader_pid, &status, WNOHANG);
- if (wpid < 0) {
- error = errno;
- (void)unlink("testfifo");
- errno = error;
- err(-1, "test_blocking_reader: waitpid %d", reader_pid);
- }
-
- if (wpid != 0 && wpid != reader_pid) {
- (void)unlink("testfifo");
- errx(-1, "test_blocking_reader: waitpid %d returned %d",
- reader_pid, wpid);
- }
-
- if (wpid == reader_pid) {
- (void)unlink("testfifo");
- errx(-1, "test_blocking_reader: blocking child didn't "
- "block");
- }
-
- /*
- * Unblock the blocking reader.
- */
- if (run_in_process(blocking_open_writer, &writer_pid,
- "test_blocking_reader: blocking_open_writer") < 0) {
- (void)unlink("testfifo");
- (void)kill(reader_pid, SIGTERM);
- (void)waitpid(reader_pid, &status, 0);
- exit(-1);
- }
-
- /*
- * Make sure both processes exited quickly (<1 second) to make sure
- * they didn't block, and GC.
- */
- if (wait_and_timeout(reader_pid, 1, &status,
- "test_blocking_reader: blocking_open_reader") < 0) {
- (void)unlink("testinfo");
- (void)kill(reader_pid, SIGTERM);
- (void)kill(writer_pid, SIGTERM);
- exit(-1);
- }
-
- if (wait_and_timeout(writer_pid, 1, &status,
- "test_blocking_reader: blocking_open_writer") < 0) {
- (void)unlink("testinfo");
- (void)kill(writer_pid, SIGTERM);
- exit(-1);
- }
-
- if (unlink("testfifo") < 0)
- err(-1, "test_blocking_reader: unlink: testfifo");
-}
-static void
-test_blocking_writer(void)
-{
- pid_t reader_pid, writer_pid, wpid;
- int error, status;
-
- if (mkfifo("testfifo", 0600) < 0)
- err(-1, "test_blocking_writer: mkfifo: testfifo");
-
- /*
- * Block a process in opening the fifo.
- */
- if (run_in_process(blocking_open_writer, &writer_pid,
- "test_blocking_writer: blocking_open_writer") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- /*
- * Test that it blocked.
- */
- sleep(5);
- wpid = waitpid(writer_pid, &status, WNOHANG);
- if (wpid < 0) {
- error = errno;
- (void)unlink("testfifo");
- errno = error;
- err(-1, "test_blocking_writer: waitpid %d", writer_pid);
- }
-
- if (wpid != 0 && wpid != writer_pid) {
- (void)unlink("testfifo");
- errx(-1, "test_blocking_writer: waitpid %d returned %d",
- writer_pid, wpid);
- }
-
- if (wpid == writer_pid) {
- (void)unlink("testfifo");
- errx(-1, "test_blocking_writer: blocking child didn't "
- "block");
- }
-
- /*
- * Unblock the blocking writer.
- */
- if (run_in_process(blocking_open_reader, &reader_pid,
- "test_blocking_writer: blocking_open_reader") < 0) {
- (void)unlink("testfifo");
- (void)kill(writer_pid, SIGTERM);
- (void)waitpid(writer_pid, &status, 0);
- exit(-1);
- }
-
- /*
- * Make sure both processes exited quickly (<1 second) to make sure
- * they didn't block, and GC.
- */
- if (wait_and_timeout(writer_pid, 1, &status,
- "test_blocking_writer: blocking_open_writer") < 0) {
- (void)unlink("testinfo");
- (void)kill(writer_pid, SIGTERM);
- (void)kill(reader_pid, SIGTERM);
- (void)waitpid(writer_pid, &status, 0);
- (void)waitpid(reader_pid, &status, 0);
- exit(-1);
- }
-
- if (wait_and_timeout(reader_pid, 1, &status,
- "test_blocking_writer: blocking_open_reader") < 0) {
- (void)unlink("testinfo");
- (void)kill(reader_pid, SIGTERM);
- (void)waitpid(reader_pid, &status, 0);
- exit(-1);
- }
-
- if (unlink("testfifo") < 0)
- err(-1, "test_blocking_writer: unlink: testfifo");
-}
-
-static void
-test_non_blocking_reader(void)
-{
- int status;
- pid_t pid;
-
- if (mkfifo("testfifo", 0600) < 0)
- err(-1, "test_non_blocking_reader: mkfifo: testfifo");
-
- if (run_in_process(non_blocking_open_reader, &pid,
- "test_non_blocking_reader: non_blocking_open_reader") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- status = -1;
- if (wait_and_timeout(pid, 5, &status,
- "test_non_blocking_reader: non_blocking_open_reader") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- if (WEXITSTATUS(status) != 0) {
- (void)unlink("testfifo");
- errno = WEXITSTATUS(status);
- err(-1, "test_non_blocking_reader: "
- "non_blocking_open_reader: open: testfifo");
- }
-
- if (unlink("testfifo") < 0)
- err(-1, "test_non_blocking_reader: unlink: testfifo");
-}
-
-static void
-test_non_blocking_writer(void)
-{
- int status;
- pid_t pid;
-
- if (mkfifo("testfifo", 0600) < 0)
- err(-1, "test_non_blocking_writer: mkfifo: testfifo");
-
- if (run_in_process(non_blocking_open_writer, &pid,
- "test_non_blocking_writer: non_blocking_open_writer") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- status = -1;
- if (wait_and_timeout(pid, 5, &status,
- "test_non_blocking_writer: non_blocking_open_writer") < 0) {
- (void)unlink("testfifo");
- exit(-1);
- }
-
- if (WEXITSTATUS(status) != ENXIO) {
- (void)unlink("testfifo");
-
- errno = WEXITSTATUS(status);
- if (errno == 0)
- errx(-1, "test_non_blocking_writer: "
- "non_blocking_open_writer: open succeeded");
- err(-1, "test_non_blocking_writer: "
- "non_blocking_open_writer: open: testfifo");
- }
-
- if (unlink("testfifo") < 0)
- err(-1, "test_non_blocking_writer: unlink: testfifo");
-}
-
-int
-main(void)
-{
-
- if (geteuid() != 0)
- errx(-1, "must be run as root");
-
- strcpy(temp_dir, "fifo_open.XXXXXXXXXXX");
- if (mkdtemp(temp_dir) == NULL)
- err(-1, "mkdtemp");
- if (chdir(temp_dir) < 0)
- err(-1, "chdir: %s", temp_dir);
- atexit(atexit_temp_dir);
-
- test_non_blocking_reader();
- test_non_blocking_writer();
-
- test_blocking_reader();
- test_blocking_writer();
-
- return (0);
-}
diff --git a/tests/sys/file/Makefile b/tests/sys/file/Makefile
deleted file mode 100644
index 6151c9f..0000000
--- a/tests/sys/file/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/file
-
-BINDIR= ${TESTSDIR}
-
-TAP_TESTS_C+= closefrom_test
-TAP_TESTS_C+= dup_test
-TAP_TESTS_C+= fcntlflags_test
-TAP_TESTS_SH+= flock_test
-PLAIN_TESTS_C+= ftruncate_test
-PLAIN_TESTS_C+= newfileops_on_fork_test
-
-PROGS+= flock_helper
-
-DPADD.closefrom_test= ${LIBUTIL}
-LDADD.closefrom_test= -lutil
-
-DPADD.flock_helper= ${LIBPTHREAD}
-LDADD.flock_helper= -lpthread
-
-DPADD.newfileops_on_fork_test= ${LIBPTHREAD}
-LDADD.newfileops_on_fork_test= -lpthread
-
-.include <bsd.test.mk>
diff --git a/tests/sys/file/closefrom_test.c b/tests/sys/file/closefrom_test.c
deleted file mode 100644
index bd4acf6..0000000
--- a/tests/sys/file/closefrom_test.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
- * Written by: John H. Baldwin <jhb@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, 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Regression tests for the closefrom(2) system call.
- */
-
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libutil.h>
-#include <paths.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-struct shared_info {
- int failed;
- char tag[64];
- char message[0];
-};
-
-static int test = 1;
-
-static void
-ok(const char *descr)
-{
-
- printf("ok %d - %s\n", test, descr);
- test++;
-}
-
-static void
-fail(const char *descr, const char *fmt, ...)
-{
- va_list ap;
-
- printf("not ok %d - %s", test, descr);
- test++;
- if (fmt) {
- va_start(ap, fmt);
- printf(" # ");
- vprintf(fmt, ap);
- va_end(ap);
- }
- printf("\n");
- exit(1);
-}
-
-#define fail_err(descr) fail((descr), "%s", strerror(errno))
-
-static void
-cok(struct shared_info *info, const char *descr)
-{
-
- info->failed = 0;
- strlcpy(info->tag, descr, sizeof(info->tag));
- exit(0);
-}
-
-static void
-cfail(struct shared_info *info, const char *descr, const char *fmt, ...)
-{
- va_list ap;
-
- info->failed = 1;
- strlcpy(info->tag, descr, sizeof(info->tag));
- if (fmt) {
- va_start(ap, fmt);
- vsprintf(info->message, fmt, ap);
- va_end(ap);
- }
- exit(0);
-}
-
-#define cfail_err(info, descr) cfail((info), (descr), "%s", strerror(errno))
-
-/*
- * Use kinfo_getfile() to fetch the list of file descriptors and figure out
- * the highest open file descriptor.
- */
-static int
-highest_fd(void)
-{
- struct kinfo_file *kif;
- int cnt, i, highest;
-
- kif = kinfo_getfile(getpid(), &cnt);
- if (kif == NULL)
- fail_err("kinfo_getfile");
- highest = INT_MIN;
- for (i = 0; i < cnt; i++)
- if (kif[i].kf_fd > highest)
- highest = kif[i].kf_fd;
- free(kif);
- return (highest);
-}
-
-static int
-devnull(void)
-{
- int fd;
-
- fd = open(_PATH_DEVNULL, O_RDONLY);
- if (fd < 0)
- fail_err("open(\" "_PATH_DEVNULL" \")");
- return (fd);
-}
-
-int
-main(void)
-{
- struct shared_info *info;
- pid_t pid;
- int fd, i, start;
-
- printf("1..15\n");
-
- /* We better start up with fd's 0, 1, and 2 open. */
- start = devnull();
- if (start == -1)
- fail("open", "bad descriptor %d", start);
- ok("open");
-
- /* Make sure highest_fd() works. */
- fd = highest_fd();
- if (start != fd)
- fail("highest_fd", "bad descriptor %d != %d", start, fd);
- ok("highest_fd");
-
- /* Try to use closefrom() for just closing fd 3. */
- closefrom(start + 1);
- fd = highest_fd();
- if (fd != start)
- fail("closefrom", "highest fd %d", fd);
- ok("closefrom");
-
- /* Eat up 16 descriptors. */
- for (i = 0; i < 16; i++)
- (void)devnull();
- fd = highest_fd();
- if (fd != start + 16)
- fail("open 16", "highest fd %d", fd);
- ok("open 16");
-
- /* Close half of them. */
- closefrom(11);
- fd = highest_fd();
- if (fd != 10)
- fail("closefrom", "highest fd %d", fd);
- ok("closefrom");
-
- /* Explicitly close descriptors 6 and 8 to create holes. */
- if (close(6) < 0 || close(8) < 0)
- fail_err("close2 ");
- ok("close 2");
-
- /* Verify that close on 6 and 8 fails with EBADF. */
- if (close(6) == 0)
- fail("close(6)", "did not fail");
- if (errno != EBADF)
- fail_err("close(6)");
- ok("close(6)");
- if (close(8) == 0)
- fail("close(8)", "did not fail");
- if (errno != EBADF)
- fail_err("close(8)");
- ok("close(8)");
-
- /* Close from 4 on. */
- closefrom(4);
- fd = highest_fd();
- if (fd != 3)
- fail("closefrom", "highest fd %d", fd);
- ok("closefrom");
-
- /* Allocate a small SHM region for IPC with our child. */
- info = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANON |
- MAP_SHARED, -1, 0);
- if (info == MAP_FAILED)
- fail_err("mmap");
- ok("mmap");
-
- /* Fork a child process to test closefrom(0). */
- pid = fork();
- if (pid < 0)
- fail_err("fork");
- if (pid == 0) {
- /* Child. */
- closefrom(0);
- fd = highest_fd();
- if (fd >= 0)
- cfail(info, "closefrom(0)", "highest fd %d", fd);
- cok(info, "closefrom(0)");
- }
- if (wait(NULL) < 0)
- fail_err("wait");
- if (info->failed)
- fail(info->tag, "%s", info->message);
- ok(info->tag);
-
- /* Fork a child process to test closefrom(-1). */
- pid = fork();
- if (pid < 0)
- fail_err("fork");
- if (pid == 0) {
- /* Child. */
- closefrom(-1);
- fd = highest_fd();
- if (fd >= 0)
- cfail(info, "closefrom(-1)", "highest fd %d", fd);
- cok(info, "closefrom(-1)");
- }
- if (wait(NULL) < 0)
- fail_err("wait");
- if (info->failed)
- fail(info->tag, "%s", info->message);
- ok(info->tag);
-
- /* Dup stdout to 6. */
- if (dup2(1, 6) < 0)
- fail_err("dup2");
- fd = highest_fd();
- if (fd != 6)
- fail("dup2", "highest fd %d", fd);
- ok("dup2");
-
- /* Do a closefrom() starting in a hole. */
- closefrom(4);
- fd = highest_fd();
- if (fd != 3)
- fail("closefrom", "highest fd %d", fd);
- ok("closefrom");
-
- /* Do a closefrom() beyond our highest open fd. */
- closefrom(32);
- fd = highest_fd();
- if (fd != 3)
- fail("closefrom", "highest fd %d", fd);
- ok("closefrom");
-
- return (0);
-}
diff --git a/tests/sys/file/dup_test.c b/tests/sys/file/dup_test.c
deleted file mode 100644
index 8173818..0000000
--- a/tests/sys/file/dup_test.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * $OpenBSD: dup2test.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
- * $OpenBSD: dup2_self.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
- * $OpenBSD: fcntl_dup.c,v 1.2 2003/07/31 21:48:08 deraadt Exp $
- *
- * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain.
- *
- * $FreeBSD$
- */
-
-/*
- * Test #1: check if dup(2) works.
- * Test #2: check if dup2(2) works.
- * Test #3: check if dup2(2) returned a fd we asked for.
- * Test #4: check if dup2(2) cleared close-on-exec flag for duped fd.
- * Test #5: check if dup2(2) allows to dup fd to itself.
- * Test #6: check if dup2(2) returned a fd we asked for.
- * Test #7: check if dup2(2) did not clear close-on-exec flag for duped fd.
- * Test #8: check if fcntl(F_DUPFD) works.
- * Test #9: check if fcntl(F_DUPFD) cleared close-on-exec flag for duped fd.
- * Test #10: check if dup2() to a fd > current maximum number of open files
- * limit work.
- * Test #11: check if fcntl(F_DUP2FD) works.
- * Test #12: check if fcntl(F_DUP2FD) returned a fd we asked for.
- * Test #13: check if fcntl(F_DUP2FD) cleared close-on-exec flag for duped fd.
- * Test #14: check if fcntl(F_DUP2FD) allows to dup fd to itself.
- * Test #15: check if fcntl(F_DUP2FD) returned a fd we asked for.
- * Test #16: check if fcntl(F_DUP2FD) did not clear close-on-exec flag for
- * duped fd.
- * Test #17: check if fcntl(F_DUP2FD) to a fd > current maximum number of open
- * files limit work.
- * Test #18: check if fcntl(F_DUPFD_CLOEXEC) works.
- * Test #19: check if fcntl(F_DUPFD_CLOEXEC) set close-on-exec flag for duped
- * fd.
- * Test #20: check if fcntl(F_DUP2FD_CLOEXEC) works.
- * Test #21: check if fcntl(F_DUP2FD_CLOEXEC) returned a fd we asked for.
- * Test #22: check if fcntl(F_DUP2FD_CLOEXEC) set close-on-exec flag for duped
- * fd.
- * Test #23: check if fcntl(F_DUP2FD_CLOEXEC) to a fd > current maximum number
- * of open files limit work.
- * Test #24: check if dup3(O_CLOEXEC) works.
- * Test #25: check if dup3(O_CLOEXEC) returned a fd we asked for.
- * Test #26: check if dup3(O_CLOEXEC) set close-on-exec flag for duped fd.
- * Test #27: check if dup3(0) works.
- * Test #28: check if dup3(0) returned a fd we asked for.
- * Test #29: check if dup3(0) cleared close-on-exec flag for duped fd.
- * Test #30: check if dup3(O_CLOEXEC) fails if oldfd == newfd.
- * Test #31: check if dup3(0) fails if oldfd == newfd.
- * Test #32: check if dup3(O_CLOEXEC) to a fd > current maximum number of
- * open files limit work.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static int getafile(void);
-
-static int
-getafile(void)
-{
- int fd;
-
- char temp[] = "/tmp/dup2XXXXXXXXX";
- if ((fd = mkstemp(temp)) < 0)
- err(1, "mkstemp");
- remove(temp);
- if (ftruncate(fd, 1024) != 0)
- err(1, "ftruncate");
- return (fd);
-}
-
-int
-main(int __unused argc, char __unused *argv[])
-{
- struct rlimit rlp;
- int orgfd, fd1, fd2, test = 0;
-
- orgfd = getafile();
-
- printf("1..32\n");
-
- /* If dup(2) ever work? */
- if ((fd1 = dup(orgfd)) < 0)
- err(1, "dup");
- printf("ok %d - dup(2) works\n", ++test);
-
- /* Set close-on-exec */
- if (fcntl(fd1, F_SETFD, 1) != 0)
- err(1, "fcntl(F_SETFD)");
-
- /* If dup2(2) ever work? */
- if ((fd2 = dup2(fd1, fd1 + 1)) < 0)
- err(1, "dup2");
- printf("ok %d - dup2(2) works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1 + 1)
- printf("no ok %d - dup2(2) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - dup2(2) returned a correct fd\n", test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) != 0)
- printf("not ok %d - dup2(2) didn't clear close-on-exec\n",
- test);
- else
- printf("ok %d - dup2(2) cleared close-on-exec\n", test);
-
- /*
- * Dup to itself.
- *
- * We're testing a small tweak in dup2 semantics.
- * Normally dup and dup2 will clear the close-on-exec
- * flag on the new fd (which appears to be an implementation
- * mistake from start and not some planned behavior).
- * In today's implementations of dup and dup2 we have to make
- * an effort to really clear that flag. But all tested
- * implementations of dup2 have another tweak. If we
- * dup2(old, new) when old == new, the syscall short-circuits
- * and returns early (because there is no need to do all the
- * work (and there is a risk for serious mistakes)).
- * So although the docs say that dup2 should "take 'old',
- * close 'new' perform a dup(2) of 'old' into 'new'"
- * the docs are not really followed because close-on-exec
- * is not cleared on 'new'.
- *
- * Since everyone has this bug, we pretend that this is
- * the way it is supposed to be and test here that it really
- * works that way.
- *
- * This is a fine example on where two separate implementation
- * fuckups take out each other and make the end-result the way
- * it was meant to be.
- */
- if ((fd2 = dup2(fd1, fd1)) < 0)
- err(1, "dup2");
- printf("ok %d - dup2(2) to itself works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1)
- printf("not ok %d - dup2(2) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - dup2(2) to itself returned a correct fd\n",
- test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) == 0)
- printf("not ok %d - dup2(2) cleared close-on-exec\n", test);
- else
- printf("ok %d - dup2(2) didn't clear close-on-exec\n", test);
-
- /* Does fcntl(F_DUPFD) work? */
- if ((fd2 = fcntl(fd1, F_DUPFD, 10)) < 0)
- err(1, "fcntl(F_DUPFD)");
- if (fd2 < 10)
- printf("not ok %d - fcntl(F_DUPFD) returned wrong fd %d\n",
- ++test, fd2);
- else
- printf("ok %d - fcntl(F_DUPFD) works\n", ++test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) != 0)
- printf(
- "not ok %d - fcntl(F_DUPFD) didn't clear close-on-exec\n",
- test);
- else
- printf("ok %d - fcntl(F_DUPFD) cleared close-on-exec\n", test);
-
- ++test;
- if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
- err(1, "getrlimit");
- if ((fd2 = dup2(fd1, rlp.rlim_cur + 1)) >= 0)
- printf("not ok %d - dup2(2) bypassed NOFILE limit\n", test);
- else
- printf("ok %d - dup2(2) didn't bypass NOFILE limit\n", test);
-
- /* If fcntl(F_DUP2FD) ever work? */
- if ((fd2 = fcntl(fd1, F_DUP2FD, fd1 + 1)) < 0)
- err(1, "fcntl(F_DUP2FD)");
- printf("ok %d - fcntl(F_DUP2FD) works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1 + 1)
- printf(
- "no ok %d - fcntl(F_DUP2FD) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD) returned a correct fd\n",
- test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) != 0)
- printf(
- "not ok %d - fcntl(F_DUP2FD) didn't clear close-on-exec\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD) cleared close-on-exec\n",
- test);
-
- /* Dup to itself */
- if ((fd2 = fcntl(fd1, F_DUP2FD, fd1)) < 0)
- err(1, "fcntl(F_DUP2FD)");
- printf("ok %d - fcntl(F_DUP2FD) to itself works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1)
- printf(
- "not ok %d - fcntl(F_DUP2FD) didn't give us the right fd\n",
- test);
- else
- printf(
- "ok %d - fcntl(F_DUP2FD) to itself returned a correct fd\n",
- test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) == 0)
- printf("not ok %d - fcntl(F_DUP2FD) cleared close-on-exec\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD) didn't clear close-on-exec\n",
- test);
-
- ++test;
- if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
- err(1, "getrlimit");
- if ((fd2 = fcntl(fd1, F_DUP2FD, rlp.rlim_cur + 1)) >= 0)
- printf("not ok %d - fcntl(F_DUP2FD) bypassed NOFILE limit\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD) didn't bypass NOFILE limit\n",
- test);
-
- /* Does fcntl(F_DUPFD_CLOEXEC) work? */
- if ((fd2 = fcntl(fd1, F_DUPFD_CLOEXEC, 10)) < 0)
- err(1, "fcntl(F_DUPFD_CLOEXEC)");
- if (fd2 < 10)
- printf("not ok %d - fcntl(F_DUPFD_CLOEXEC) returned wrong fd %d\n",
- ++test, fd2);
- else
- printf("ok %d - fcntl(F_DUPFD_CLOEXEC) works\n", ++test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) != 1)
- printf(
- "not ok %d - fcntl(F_DUPFD_CLOEXEC) didn't set close-on-exec\n",
- test);
- else
- printf("ok %d - fcntl(F_DUPFD_CLOEXEC) set close-on-exec\n",
- test);
-
- /* If fcntl(F_DUP2FD_CLOEXEC) ever work? */
- if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, fd1 + 1)) < 0)
- err(1, "fcntl(F_DUP2FD_CLOEXEC)");
- printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1 + 1)
- printf(
- "no ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) returned a correct fd\n",
- test);
-
- /* Was close-on-exec set? */
- ++test;
- if (fcntl(fd2, F_GETFD) != FD_CLOEXEC)
- printf(
- "not ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't set close-on-exec\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) set close-on-exec\n",
- test);
-
- /*
- * It is unclear what F_DUP2FD_CLOEXEC should do when duplicating a
- * file descriptor onto itself.
- */
-
- ++test;
- if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
- err(1, "getrlimit");
- if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, rlp.rlim_cur + 1)) >= 0)
- printf("not ok %d - fcntl(F_DUP2FD_CLOEXEC) bypassed NOFILE limit\n",
- test);
- else
- printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't bypass NOFILE limit\n",
- test);
-
- /* Does dup3(O_CLOEXEC) ever work? */
- if ((fd2 = dup3(fd1, fd1 + 1, O_CLOEXEC)) < 0)
- err(1, "dup3(O_CLOEXEC)");
- printf("ok %d - dup3(O_CLOEXEC) works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1 + 1)
- printf(
- "no ok %d - dup3(O_CLOEXEC) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - dup3(O_CLOEXEC) returned a correct fd\n",
- test);
-
- /* Was close-on-exec set? */
- ++test;
- if (fcntl(fd2, F_GETFD) != FD_CLOEXEC)
- printf(
- "not ok %d - dup3(O_CLOEXEC) didn't set close-on-exec\n",
- test);
- else
- printf("ok %d - dup3(O_CLOEXEC) set close-on-exec\n",
- test);
-
- /* Does dup3(0) ever work? */
- if ((fd2 = dup3(fd1, fd1 + 1, 0)) < 0)
- err(1, "dup3(0)");
- printf("ok %d - dup3(0) works\n", ++test);
-
- /* Do we get the right fd? */
- ++test;
- if (fd2 != fd1 + 1)
- printf(
- "no ok %d - dup3(0) didn't give us the right fd\n",
- test);
- else
- printf("ok %d - dup3(0) returned a correct fd\n",
- test);
-
- /* Was close-on-exec cleared? */
- ++test;
- if (fcntl(fd2, F_GETFD) != 0)
- printf(
- "not ok %d - dup3(0) didn't clear close-on-exec\n",
- test);
- else
- printf("ok %d - dup3(0) cleared close-on-exec\n",
- test);
-
- /* dup3() does not allow duplicating to the same fd */
- ++test;
- if (dup3(fd1, fd1, O_CLOEXEC) != -1)
- printf(
- "not ok %d - dup3(fd1, fd1, O_CLOEXEC) succeeded\n", test);
- else
- printf("ok %d - dup3(fd1, fd1, O_CLOEXEC) failed\n", test);
-
- ++test;
- if (dup3(fd1, fd1, 0) != -1)
- printf(
- "not ok %d - dup3(fd1, fd1, 0) succeeded\n", test);
- else
- printf("ok %d - dup3(fd1, fd1, 0) failed\n", test);
-
- ++test;
- if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
- err(1, "getrlimit");
- if ((fd2 = dup3(fd1, rlp.rlim_cur + 1, O_CLOEXEC)) >= 0)
- printf("not ok %d - dup3(O_CLOEXEC) bypassed NOFILE limit\n",
- test);
- else
- printf("ok %d - dup3(O_CLOEXEC) didn't bypass NOFILE limit\n",
- test);
-
- return (0);
-}
diff --git a/tests/sys/file/fcntlflags_test.c b/tests/sys/file/fcntlflags_test.c
deleted file mode 100644
index bcb3b54..0000000
--- a/tests/sys/file/fcntlflags_test.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * Copyright (c) 2013 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/cdefs.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-
-/*
- * O_ACCMODE is currently defined incorrectly. This is what it should be.
- * Various code depends on the incorrect value.
- */
-#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
-
-static int testnum;
-
-static void
-subtests(const char *path, int omode, const char *omodetext)
-{
- int fd, flags1, flags2, flags3;
-
- fd = open(path, omode);
- if (fd == -1)
- printf("not ok %d - open(\"%s\", %s) failed\n",
- testnum++, path, omodetext);
- else
- printf("ok %d - open(\"%s\", %s) succeeded\n",
- testnum++, path, omodetext);
- flags1 = fcntl(fd, F_GETFL);
- if (flags1 == -1)
- printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
- else if ((flags1 & CORRECT_O_ACCMODE) == omode)
- printf("ok %d - fcntl(F_GETFL) gave correct result\n",
- testnum++);
- else
- printf("not ok %d - fcntl(F_GETFL) gave incorrect result "
- "(%#x & %#x != %#x)\n",
- testnum++, flags1, CORRECT_O_ACCMODE, omode);
- if (fcntl(fd, F_SETFL, flags1) == -1)
- printf("not ok %d - fcntl(F_SETFL) same flags failed\n",
- testnum++);
- else
- printf("ok %d - fcntl(F_SETFL) same flags succeeded\n",
- testnum++);
- flags2 = fcntl(fd, F_GETFL);
- if (flags2 == -1)
- printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
- else if (flags2 == flags1)
- printf("ok %d - fcntl(F_GETFL) gave same result\n",
- testnum++);
- else
- printf("not ok %d - fcntl(F_SETFL) caused fcntl(F_GETFL) to "
- "change from %#x to %#x\n",
- testnum++, flags1, flags2);
- if (fcntl(fd, F_SETFL, flags2 | O_NONBLOCK) == -1)
- printf("not ok %d - fcntl(F_SETFL) O_NONBLOCK failed\n",
- testnum++);
- else
- printf("ok %d - fcntl(F_SETFL) O_NONBLOCK succeeded\n",
- testnum++);
- flags3 = fcntl(fd, F_GETFL);
- if (flags3 == -1)
- printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
- else if (flags3 == (flags2 | O_NONBLOCK))
- printf("ok %d - fcntl(F_GETFL) gave expected result\n",
- testnum++);
- else
- printf("not ok %d - fcntl(F_SETFL) gave unexpected result "
- "(%#x != %#x)\n",
- testnum++, flags3, flags2 | O_NONBLOCK);
- (void)close(fd);
-}
-
-int
-main(int argc __unused, char **argv __unused)
-{
- printf("1..24\n");
- testnum = 1;
- subtests("/dev/null", O_RDONLY, "O_RDONLY");
- subtests("/dev/null", O_WRONLY, "O_WRONLY");
- subtests("/dev/null", O_RDWR, "O_RDWR");
- subtests("/bin/sh", O_EXEC, "O_EXEC");
- return (0);
-}
diff --git a/tests/sys/file/flock_helper.c b/tests/sys/file/flock_helper.c
deleted file mode 100644
index 49e47b8..0000000
--- a/tests/sys/file/flock_helper.c
+++ /dev/null
@@ -1,1598 +0,0 @@
-/*-
- * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
- * Authors: Doug Rabson <dfr@rabson.org>
- * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.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 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/param.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#ifdef __FreeBSD__
-#include <sys/mount.h>
-#endif
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef __FreeBSD__
-#if __FreeBSD_version >= 800028
-#define HAVE_SYSID
-#endif
-#include <sys/cdefs.h>
-#else
-#ifndef nitems
-#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
-#endif
-
-#ifndef __unused
-#ifdef __GNUC__
-#define __unused __attribute__((__unused__))
-#else
-#define __unused
-#endif
-#endif
-#endif
-
-static int verbose = 0;
-
-static int
-make_file(const char *pathname, off_t sz)
-{
- struct stat st;
- const char *template = "/flocktempXXXXXX";
- size_t len;
- char *filename;
- int fd;
-
- if (stat(pathname, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
- fd = open(pathname, O_RDWR);
- if (fd < 0)
- err(1, "open(%s)", pathname);
- if (ftruncate(fd, sz) < 0)
- err(1, "ftruncate");
- return (fd);
- }
- }
-
- len = strlen(pathname) + strlen(template) + 1;
- filename = malloc(len);
- strcpy(filename, pathname);
- strcat(filename, template);
- fd = mkstemp(filename);
- if (fd < 0)
- err(1, "mkstemp");
- if (ftruncate(fd, sz) < 0)
- err(1, "ftruncate");
- if (unlink(filename) < 0)
- err(1, "unlink");
- free(filename);
-
- return (fd);
-}
-
-static void
-ignore_alarm(int __unused sig)
-{
-}
-
-static int
-safe_waitpid(pid_t pid)
-{
- int save_errno;
- int status;
-
- save_errno = errno;
- errno = 0;
- while (waitpid(pid, &status, 0) != pid) {
- if (errno == EINTR)
- continue;
- err(1, "waitpid");
- }
- errno = save_errno;
-
- return (status);
-}
-
-#define FAIL(test) \
- do { \
- if (test) { \
- printf("FAIL (%s)\n", #test); \
- return -1; \
- } \
- } while (0)
-
-#define SUCCEED \
- do { printf("SUCCEED\n"); return 0; } while (0)
-
-/*
- * Test 1 - F_GETLK on unlocked region
- *
- * If no lock is found that would prevent this lock from being
- * created, the structure is left unchanged by this function call
- * except for the lock type which is set to F_UNLCK.
- */
-static int
-test1(int fd, __unused int argc, const __unused char **argv)
-{
- struct flock fl1, fl2;
-
- memset(&fl1, 1, sizeof(fl1));
- fl1.l_type = F_WRLCK;
- fl1.l_whence = SEEK_SET;
- fl2 = fl1;
-
- if (fcntl(fd, F_GETLK, &fl1) < 0)
- err(1, "F_GETLK");
-
- printf("1 - F_GETLK on unlocked region: ");
- FAIL(fl1.l_start != fl2.l_start);
- FAIL(fl1.l_len != fl2.l_len);
- FAIL(fl1.l_pid != fl2.l_pid);
- FAIL(fl1.l_type != F_UNLCK);
- FAIL(fl1.l_whence != fl2.l_whence);
-#ifdef HAVE_SYSID
- FAIL(fl1.l_sysid != fl2.l_sysid);
-#endif
-
- SUCCEED;
-}
-
-/*
- * Test 2 - F_SETLK on locked region
- *
- * If a shared or exclusive lock cannot be set, fcntl returns
- * immediately with EACCES or EAGAIN.
- */
-static int
-test2(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should return -1 with errno set to either EACCES or
- * EAGAIN.
- */
- printf("2 - F_SETLK on locked region: ");
- res = fcntl(fd, F_SETLK, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
- FAIL(res == 0);
- FAIL(errno != EACCES && errno != EAGAIN);
-
- SUCCEED;
-}
-
-/*
- * Test 3 - F_SETLKW on locked region
- *
- * If a shared or exclusive lock is blocked by other locks, the
- * process waits until the request can be satisfied.
- *
- * XXX this test hangs on FreeBSD NFS filesystems due to limitations
- * in FreeBSD's client (and server) lockd implementation.
- */
-static int
-test3(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("3 - F_SETLKW on locked region: ");
-
- alarm(1);
-
- res = fcntl(fd, F_SETLKW, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
- FAIL(res == 0);
- FAIL(errno != EINTR);
-
- SUCCEED;
-}
-
-/*
- * Test 4 - F_GETLK on locked region
- *
- * Get the first lock that blocks the lock.
- */
-static int
-test4(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 99;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should return a lock structure reflecting the lock we
- * made in the child process.
- */
- if (fcntl(fd, F_GETLK, &fl) < 0)
- err(1, "F_GETLK");
-
- printf("4 - F_GETLK on locked region: ");
- FAIL(fl.l_start != 0);
- FAIL(fl.l_len != 99);
- FAIL(fl.l_type != F_WRLCK);
- FAIL(fl.l_pid != pid);
-#ifdef HAVE_SYSID
- FAIL(fl.l_sysid != 0);
-#endif
-
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- SUCCEED;
-}
-
-/*
- * Test 5 - F_SETLKW simple deadlock
- *
- * If a blocking shared lock request would cause a deadlock (i.e. the
- * lock request is blocked by a process which is itself blocked on a
- * lock currently owned by the process making the new request),
- * EDEADLK is returned.
- */
-static int
-test5(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. Because our test relies on the child process being
- * blocked on the parent's lock, we can't easily use a pipe to
- * synchronize so we just sleep in the parent to given the
- * child a chance to setup.
- *
- * To create the deadlock condition, we arrange for the parent
- * to lock the first byte of the file and the child to lock
- * the second byte. After locking the second byte, the child
- * will attempt to lock the first byte of the file, and
- * block. The parent will then attempt to lock the second byte
- * (owned by the child) which should cause deadlock.
- */
- int pid;
- struct flock fl;
- int res;
-
- /*
- * Lock the first byte in the parent.
- */
- fl.l_start = 0;
- fl.l_len = 1;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK 1 (parent)");
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * Lock the second byte in the child and then block on
- * the parent's lock.
- */
- fl.l_start = 1;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- fl.l_start = 0;
- if (fcntl(fd, F_SETLKW, &fl) < 0)
- err(1, "F_SETLKW (child)");
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- sleep(1);
-
- /*
- * fcntl should immediately return -1 with errno set to
- * EDEADLK. If the alarm fires, we failed to detect the
- * deadlock.
- */
- alarm(1);
- printf("5 - F_SETLKW simple deadlock: ");
-
- fl.l_start = 1;
- res = fcntl(fd, F_SETLKW, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
-
- FAIL(res == 0);
- FAIL(errno != EDEADLK);
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_UNLCK");
-
- /*
- * Cancel the alarm to avoid confusing later tests.
- */
- alarm(0);
-
- SUCCEED;
-}
-
-/*
- * Test 6 - F_SETLKW complex deadlock.
- *
- * This test involves three process, P, C1 and C2. We set things up so
- * that P locks byte zero, C1 locks byte 1 and C2 locks byte 2. We
- * also block C2 by attempting to lock byte zero. Lastly, P attempts
- * to lock a range including byte 1 and 2. This represents a deadlock
- * (due to C2's blocking attempt to lock byte zero).
- */
-static int
-test6(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * Because our test relies on the child process being blocked
- * on the parent's lock, we can't easily use a pipe to
- * synchronize so we just sleep in the parent to given the
- * children a chance to setup.
- */
- int pid1, pid2;
- struct flock fl;
- int res;
-
- /*
- * Lock the first byte in the parent.
- */
- fl.l_start = 0;
- fl.l_len = 1;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK 1 (parent)");
-
- pid1 = fork();
- if (pid1 < 0)
- err(1, "fork");
-
- if (pid1 == 0) {
- /*
- * C1
- * Lock the second byte in the child and then sleep
- */
- fl.l_start = 1;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child1)");
- pause();
- exit(0);
- }
-
- pid2 = fork();
- if (pid2 < 0)
- err(1, "fork");
-
- if (pid2 == 0) {
- /*
- * C2
- * Lock the third byte in the child and then block on
- * the parent's lock.
- */
- fl.l_start = 2;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child2)");
- fl.l_start = 0;
- if (fcntl(fd, F_SETLKW, &fl) < 0)
- err(1, "F_SETLKW (child2)");
- exit(0);
- }
-
- /*
- * Wait until the children have set their locks and then
- * perform the test.
- */
- sleep(1);
-
- /*
- * fcntl should immediately return -1 with errno set to
- * EDEADLK. If the alarm fires, we failed to detect the
- * deadlock.
- */
- alarm(1);
- printf("6 - F_SETLKW complex deadlock: ");
-
- fl.l_start = 1;
- fl.l_len = 2;
- res = fcntl(fd, F_SETLKW, &fl);
- kill(pid1, SIGTERM);
- safe_waitpid(pid1);
- kill(pid2, SIGTERM);
- safe_waitpid(pid2);
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_UNLCK");
-
- FAIL(res == 0);
- FAIL(errno != EDEADLK);
-
- /*
- * Cancel the alarm to avoid confusing later tests.
- */
- alarm(0);
-
- SUCCEED;
-}
-
-/*
- * Test 7 - F_SETLK shared lock on exclusive locked region
- *
- * If a shared or exclusive lock cannot be set, fcntl returns
- * immediately with EACCES or EAGAIN.
- */
-static int
-test7(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("7 - F_SETLK shared lock on exclusive locked region: ");
-
- fl.l_type = F_RDLCK;
- res = fcntl(fd, F_SETLK, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- FAIL(res == 0);
- FAIL(errno != EACCES && errno != EAGAIN);
-
- SUCCEED;
-}
-
-/*
- * Test 8 - F_SETLK shared lock on share locked region
- *
- * When a shared lock is set on a segment of a file, other processes
- * shall be able to set shared locks on that segment or a portion of
- * it.
- */
-static int
-test8(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_RDLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("8 - F_SETLK shared lock on share locked region: ");
-
- fl.l_type = F_RDLCK;
- res = fcntl(fd, F_SETLK, &fl);
-
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_UNLCK");
-
- FAIL(res != 0);
-
- SUCCEED;
-}
-
-/*
- * Test 9 - F_SETLK exclusive lock on share locked region
- *
- * If a shared or exclusive lock cannot be set, fcntl returns
- * immediately with EACCES or EAGAIN.
- */
-static int
-test9(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_RDLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("9 - F_SETLK exclusive lock on share locked region: ");
-
- fl.l_type = F_WRLCK;
- res = fcntl(fd, F_SETLK, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- FAIL(res == 0);
- FAIL(errno != EACCES && errno != EAGAIN);
-
- SUCCEED;
-}
-
-/*
- * Test 10 - trying to set bogus pid or sysid values
- *
- * The l_pid and l_sysid fields are only used with F_GETLK to return
- * the process ID of the process holding a blocking lock and the
- * system ID of the system that owns that process
- */
-static int
-test10(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_pid = 9999;
-#ifdef HAVE_SYSID
- fl.l_sysid = 9999;
-#endif
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- printf("10 - trying to set bogus pid or sysid values: ");
-
- if (fcntl(fd, F_GETLK, &fl) < 0)
- err(1, "F_GETLK");
-
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- FAIL(fl.l_pid != pid);
-#ifdef HAVE_SYSID
- FAIL(fl.l_sysid != 0);
-#endif
-
- SUCCEED;
-}
-
-/*
- * Test 11 - remote locks
- *
- * XXX temporary interface which will be removed when the kernel lockd
- * is added.
- */
-static int
-test11(int fd, __unused int argc, const __unused char **argv)
-{
-#ifdef F_SETLK_REMOTE
- struct flock fl;
- int res;
-
- if (geteuid() != 0)
- return 0;
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_pid = 9999;
- fl.l_sysid = 1001;
-
- printf("11 - remote locks: ");
-
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- fl.l_sysid = 1002;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res == 0);
- FAIL(errno != EACCES && errno != EAGAIN);
-
- res = fcntl(fd, F_GETLK, &fl);
- FAIL(res != 0);
- FAIL(fl.l_pid != 9999);
- FAIL(fl.l_sysid != 1001);
-
- fl.l_type = F_UNLCK;
- fl.l_sysid = 1001;
- fl.l_start = 0;
- fl.l_len = 0;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- fl.l_pid = 1234;
- fl.l_sysid = 1001;
- fl.l_start = 0;
- fl.l_len = 1;
- fl.l_whence = SEEK_SET;
- fl.l_type = F_RDLCK;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- fl.l_sysid = 1002;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- fl.l_type = F_UNLCKSYS;
- fl.l_sysid = 1001;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- fl.l_type = F_WRLCK;
- res = fcntl(fd, F_GETLK, &fl);
- FAIL(res != 0);
- FAIL(fl.l_pid != 1234);
- FAIL(fl.l_sysid != 1002);
-
- fl.l_type = F_UNLCKSYS;
- fl.l_sysid = 1002;
- res = fcntl(fd, F_SETLK_REMOTE, &fl);
- FAIL(res != 0);
-
- SUCCEED;
-#else
- return 0;
-#endif
-}
-
-/*
- * Test 12 - F_SETLKW on locked region which is then unlocked
- *
- * If a shared or exclusive lock is blocked by other locks, the
- * process waits until the request can be satisfied.
- */
-static int
-test12(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
-
- sleep(1);
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("12 - F_SETLKW on locked region which is then unlocked: ");
-
- //alarm(1);
-
- res = fcntl(fd, F_SETLKW, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
- FAIL(res != 0);
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_UNLCK");
-
- SUCCEED;
-}
-
-/*
- * Test 13 - F_SETLKW on locked region, race with owner
- *
- * If a shared or exclusive lock is blocked by other locks, the
- * process waits until the request can be satisfied.
- */
-static int
-test13(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int i;
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
- struct itimerval itv;
-
- printf("13 - F_SETLKW on locked region, race with owner: ");
- fflush(stdout);
-
- for (i = 0; i < 100; i++) {
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
-
- usleep(1);
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- while (read(pfd[0], &ch, 1) != 1) {
- if (errno == EINTR)
- continue;
- err(1, "reading from pipe (child)");
- }
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 2;
- setitimer(ITIMER_REAL, &itv, NULL);
-
- res = fcntl(fd, F_SETLKW, &fl);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
- FAIL(!(res == 0 || (res == -1 && errno == EINTR)));
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "F_UNLCK");
- }
- SUCCEED;
-}
-
-/*
- * Test 14 - soak test
- */
-static int
-test14(int fd, int argc, const char **argv)
-{
-#define CHILD_COUNT 20
- /*
- * We create a set of child processes and let each one run
- * through a random sequence of locks and unlocks.
- */
- int i, j, id, id_base;
- int pids[CHILD_COUNT], pid;
- char buf[128];
- char tbuf[128];
- int map[128];
- char outbuf[512];
- struct flock fl;
- struct itimerval itv;
- int status;
-
- id_base = 0;
- if (argc >= 2)
- id_base = strtol(argv[1], NULL, 0);
-
- printf("14 - soak test: ");
- fflush(stdout);
-
- for (i = 0; i < 128; i++)
- map[i] = F_UNLCK;
-
- for (i = 0; i < CHILD_COUNT; i++) {
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
- if (pid) {
- /*
- * Parent - record the pid and continue.
- */
- pids[i] = pid;
- continue;
- }
-
- /*
- * Child - do some work and exit.
- */
- id = id_base + i;
- srandom(getpid());
-
- for (j = 0; j < 50; j++) {
- int start, end, len;
- int set, wrlock;
-
- do {
- start = random() & 127;
- end = random() & 127;
- } while (end <= start);
-
- set = random() & 1;
- wrlock = random() & 1;
-
- len = end - start;
- fl.l_start = start;
- fl.l_len = len;
- fl.l_whence = SEEK_SET;
- if (set)
- fl.l_type = wrlock ? F_WRLCK : F_RDLCK;
- else
- fl.l_type = F_UNLCK;
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 3000;
- setitimer(ITIMER_REAL, &itv, NULL);
-
- if (fcntl(fd, F_SETLKW, &fl) < 0) {
- if (errno == EDEADLK || errno == EINTR) {
- if (verbose) {
- snprintf(outbuf, sizeof(outbuf),
- "%d[%d]: %s [%d .. %d] %s\n",
- id, j,
- set ? (wrlock ? "write lock"
- : "read lock")
- : "unlock", start, end,
- errno == EDEADLK
- ? "deadlock"
- : "interrupted");
- write(1, outbuf,
- strlen(outbuf));
- }
- continue;
- } else {
- perror("fcntl");
- }
- }
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &itv, NULL);
-
- if (verbose) {
- snprintf(outbuf, sizeof(outbuf),
- "%d[%d]: %s [%d .. %d] succeeded\n",
- id, j,
- set ? (wrlock ? "write lock" : "read lock")
- : "unlock", start, end);
- write(1, outbuf, strlen(outbuf));
- }
-
- if (set) {
- if (wrlock) {
- /*
- * We got a write lock - write
- * our ID to each byte that we
- * managed to claim.
- */
- for (i = start; i < end; i++)
- map[i] = F_WRLCK;
- memset(&buf[start], id, len);
- if (pwrite(fd, &buf[start], len,
- start) != len) {
- printf("%d: short write\n", id);
- exit(1);
- }
- } else {
- /*
- * We got a read lock - read
- * the bytes which we claimed
- * so that we can check that
- * they don't change
- * unexpectedly.
- */
- for (i = start; i < end; i++)
- map[i] = F_RDLCK;
- if (pread(fd, &buf[start], len,
- start) != len) {
- printf("%d: short read\n", id);
- exit(1);
- }
- }
- } else {
- for (i = start; i < end; i++)
- map[i] = F_UNLCK;
- }
-
- usleep(1000);
-
- /*
- * Read back the whole region so that we can
- * check that all the bytes we have some kind
- * of claim to have the correct value.
- */
- if (pread(fd, tbuf, sizeof(tbuf), 0) != sizeof(tbuf)) {
- printf("%d: short read\n", id);
- exit(1);
- }
-
- for (i = 0; i < 128; i++) {
- if (map[i] != F_UNLCK && buf[i] != tbuf[i]) {
- snprintf(outbuf, sizeof(outbuf),
- "%d: byte %d expected %d, "
- "got %d\n", id, i, buf[i], tbuf[i]);
- write(1, outbuf, strlen(outbuf));
- exit(1);
- }
- }
- }
- if (verbose)
- printf("%d[%d]: done\n", id, j);
-
- exit(0);
- }
-
- status = 0;
- for (i = 0; i < CHILD_COUNT; i++) {
- status += safe_waitpid(pids[i]);
- }
- if (status)
- FAIL(status != 0);
-
- SUCCEED;
-}
-
-/*
- * Test 15 - flock(2) semantcs
- *
- * When a lock holder has a shared lock and attempts to upgrade that
- * shared lock to exclusive, it must drop the shared lock before
- * blocking on the exclusive lock.
- *
- * To test this, we first arrange for two shared locks on the file,
- * and then attempt to upgrade one of them to exclusive. This should
- * drop one of the shared locks and block. We interrupt the blocking
- * lock request and examine the lock state of the file after dropping
- * the other shared lock - there should be no active locks at this
- * point.
- */
-static int
-test15(int fd, __unused int argc, const __unused char **argv)
-{
-#ifdef LOCK_EX
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- *
- * Since we only have one file descriptors and lock ownership
- * for flock(2) goes with the file descriptor, we use fcntl to
- * set the child's shared lock.
- */
- int pid;
- int pfd[2];
- struct flock fl;
- char ch;
- int res;
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a shared lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_RDLCK;
- fl.l_whence = SEEK_SET;
- if (fcntl(fd, F_SETLK, &fl) < 0)
- err(1, "fcntl(F_SETLK) (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- (void)dup(fd);
- if (flock(fd, LOCK_SH) < 0)
- err(1, "flock shared");
-
- /*
- * flock should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("15 - flock(2) semantics: ");
-
- alarm(1);
- flock(fd, LOCK_EX);
-
- /*
- * Kill the child to force it to drop its locks.
- */
- kill(pid, SIGTERM);
- safe_waitpid(pid);
-
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- res = fcntl(fd, F_GETLK, &fl);
-
- close(pfd[0]);
- close(pfd[1]);
- FAIL(res != 0);
- FAIL(fl.l_type != F_UNLCK);
-
- SUCCEED;
-#else
- return 0;
-#endif
-}
-
-struct test_ctx {
- struct flock tc_fl;
- int tc_fd;
-};
-
-static void *
-test16_func(void *tc_in)
-{
- uintptr_t error;
- struct test_ctx *tc = tc_in;
-
- error = fcntl(tc->tc_fd, F_SETLKW, &tc->tc_fl);
-
- pthread_exit((void *)error);
-}
-
-#define THREADS 10
-
-/*
- * Test 16 - F_SETLKW from two threads
- *
- * If two threads within a process are blocked on a lock and the lock
- * is granted, make sure things are sane.
- */
-static int
-test16(int fd, __unused int argc, const __unused char **argv)
-{
- /*
- * We create a child process to hold the lock which we will
- * test. We use a pipe to communicate with the child.
- */
- int pid;
- int pfd[2];
- struct test_ctx tc = { .tc_fd = fd };
- char ch;
- int i;
- int error;
- pthread_t thr[THREADS];
-
- if (pipe(pfd) < 0)
- err(1, "pipe");
-
- tc.tc_fl.l_start = 0;
- tc.tc_fl.l_len = 0;
- tc.tc_fl.l_type = F_WRLCK;
- tc.tc_fl.l_whence = SEEK_SET;
-
- pid = fork();
- if (pid < 0)
- err(1, "fork");
-
- if (pid == 0) {
- /*
- * We are the child. We set a write lock and then
- * write one byte back to the parent to tell it. The
- * parent will kill us when its done.
- */
- if (fcntl(fd, F_SETLK, &tc.tc_fl) < 0)
- err(1, "F_SETLK (child)");
- if (write(pfd[1], "a", 1) < 0)
- err(1, "writing to pipe (child)");
- pause();
- exit(0);
- }
-
- /*
- * Wait until the child has set its lock and then perform the
- * test.
- */
- if (read(pfd[0], &ch, 1) != 1)
- err(1, "reading from pipe (child)");
-
- /*
- * fcntl should wait until the alarm and then return -1 with
- * errno set to EINTR.
- */
- printf("16 - F_SETLKW on locked region by two threads: ");
-
- for (i = 0; i < THREADS; i++) {
- error = pthread_create(&thr[i], NULL, test16_func, &tc);
- if (error)
- err(1, "pthread_create");
- }
-
- /*
- * Sleep, then kill the child. This makes me a little sad, but it's
- * tricky to tell whether the threads are all really blocked by this
- * point.
- */
- sleep(1);
- kill(pid, SIGTERM);
- safe_waitpid(pid);
- close(pfd[0]);
- close(pfd[1]);
-
- for (i = 0; i < THREADS; i++) {
- void *res;
- error = pthread_join(thr[i], &res);
- if (error)
- err(1, "pthread_join");
- FAIL((uintptr_t)res != 0);
- }
-
- SUCCEED;
-}
-
-struct test {
- int (*testfn)(int, int, const char **); /* function to perform the test */
- int num; /* test number */
- int intr; /* non-zero if the test interrupts a lock */
-};
-
-static struct test tests[] = {
- { test1, 1, 0 },
- { test2, 2, 0 },
- { test3, 3, 1 },
- { test4, 4, 0 },
- { test5, 5, 1 },
- { test6, 6, 1 },
- { test7, 7, 0 },
- { test8, 8, 0 },
- { test9, 9, 0 },
- { test10, 10, 0 },
- { test11, 11, 1 },
- { test12, 12, 0 },
- { test13, 13, 1 },
- { test14, 14, 0 },
- { test15, 15, 1 },
- { test16, 16, 1 },
-};
-
-int
-main(int argc, const char *argv[])
-{
- int testnum;
- int fd;
- int nointr;
- unsigned i;
- struct sigaction sa;
- int test_argc;
- const char **test_argv;
-
- if (argc < 2) {
- errx(1, "usage: flock <directory> [test number] ...");
- }
-
- fd = make_file(argv[1], 1024);
- if (argc >= 3) {
- testnum = strtol(argv[2], NULL, 0);
- test_argc = argc - 2;
- test_argv = argv + 2;
- } else {
- testnum = 0;
- test_argc = 0;
- test_argv = 0;
- }
-
- sa.sa_handler = ignore_alarm;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(SIGALRM, &sa, 0);
-
- nointr = 0;
-#if defined(__FreeBSD__) && __FreeBSD_version < 800040
- {
- /*
- * FreeBSD with userland NLM can't interrupt a blocked
- * lock request on an NFS mounted filesystem.
- */
- struct statfs st;
- fstatfs(fd, &st);
- nointr = !strcmp(st.f_fstypename, "nfs");
- }
-#endif
-
- for (i = 0; i < nitems(tests); i++) {
- if (tests[i].intr && nointr)
- continue;
- if (!testnum || tests[i].num == testnum)
- tests[i].testfn(fd, test_argc, test_argv);
- }
-
- return 0;
-}
diff --git a/tests/sys/file/flock_test.sh b/tests/sys/file/flock_test.sh
deleted file mode 100755
index ac3e799..0000000
--- a/tests/sys/file/flock_test.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2014 EMC Corp.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# 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
-# OWNER 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$
-
-# Testcase # 11 is racy; uses an undocumented kernel interface for testing
-# locking
-# Testcase # 16 is racy/doesn't handle EINTR properly
-last_testcase=16
-
-echo "1..$last_testcase"
-
-for n in `seq 1 $last_testcase`; do
- todomsg=""
-
- if [ $n -eq 11 ]; then
- todomsg=" # TODO: racy testcase"
- # Test 16 fails:
- # F_SETLKW on locked region by two threads: FAIL ((uintptr_t)res != 0)
- elif [ $n -eq 16 ]; then
- todomsg=" # TODO: racy testcase (doesn't handle EINTR properly)"
- fi
-
- $(dirname $0)/flock_helper . $n | grep -q SUCCEED
- if [ $? -eq 0 ]; then
- echo "ok $n$todomsg"
- else
- echo "not ok $n$todomsg"
- fi
-done
diff --git a/tests/sys/file/ftruncate_test.c b/tests/sys/file/ftruncate_test.c
deleted file mode 100644
index 7eaba14..0000000
--- a/tests/sys/file/ftruncate_test.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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$
- */
-
-/*
- * Very simple regression test.
- *
- * Future tests that might be of interest:
- *
- * - Make sure we get EISDIR on a directory.
- */
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <unistd.h>
-
-/*
- * Select various potentially interesting lengths at and around power of 2
- * edges.
- */
-static off_t lengths[] = {0, 1, 2, 3, 4, 127, 128, 129, 511, 512, 513, 1023,
- 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193, 16383,
- 16384, 16385};
-static int lengths_count = sizeof(lengths) / sizeof(off_t);
-
-int
-main(int argc, char *argv[])
-{
- int error, fd, fds[2], i, read_only_fd;
- char path[PATH_MAX];
- struct stat sb;
- ssize_t size;
- off_t len;
- char ch;
-
- /*
- * Tests using a writable temporary file: grow and then shrink a file
- * using ftruncate and various lengths. Make sure that a negative
- * file length is rejected. Make sure that when we grow the file,
- * bytes now in the range of the file size return 0.
- *
- * Save a read-only reference to the file to use later for read-only
- * descriptor tests.
- */
- snprintf(path, PATH_MAX, "/tmp/ftruncate.XXXXXXXXXXXXX");
- fd = mkstemp(path);
- if (fd < 0)
- err(-1, "mkstemp");
- read_only_fd = open(path, O_RDONLY);
- if (read_only_fd < 0) {
- error = errno;
- (void)unlink(path);
- errno = error;
- err(-1, "open(%s, O_RDONLY)", path);
- }
- (void)unlink(path);
-
- if (ftruncate(fd, -1) == 0)
- errx(-1, "ftruncate(fd, -1) succeeded");
- if (errno != EINVAL)
- err(-1, "ftruncate(fd, -1) returned wrong error");
-
- for (i = 0; i < lengths_count; i++) {
- len = lengths[i];
- if (ftruncate(fd, len) < 0)
- err(-1, "ftruncate(%jd) up", (intmax_t)len);
- if (fstat(fd, &sb) < 0)
- err(-1, "stat");
- if (sb.st_size != len)
- errx(-1, "fstat with len=%jd returned len %jd up",
- (intmax_t)len, (intmax_t)sb.st_size);
- if (len != 0) {
- size = pread(fd, &ch, sizeof(ch), len - 1);
- if (size < 0)
- err(-1, "pread on len %jd up", (intmax_t)len);
- if (size != sizeof(ch))
- errx(-1, "pread len %jd size %jd up",
- (intmax_t)len, (intmax_t)size);
- if (ch != 0)
- errx(-1,
- "pread length %jd size %jd ch %d up",
- (intmax_t)len, (intmax_t)size, ch);
- }
- }
-
- for (i = lengths_count - 1; i >= 0; i--) {
- len = lengths[i];
- if (ftruncate(fd, len) < 0)
- err(-1, "ftruncate(%jd) down", (intmax_t)len);
- if (fstat(fd, &sb) < 0)
- err(-1, "stat");
- if (sb.st_size != len)
- errx(-1, "fstat(%jd) returned %jd down", (intmax_t)len,
- sb.st_size);
- }
- close(fd);
-
- /*
- * Make sure that a read-only descriptor can't be truncated.
- */
- if (ftruncate(read_only_fd, 0) == 0)
- errx(-1, "ftruncate(read_only_fd) succeeded");
- if (errno != EINVAL)
- err(-1, "ftruncate(read_only_fd) returned wrong error");
- close(read_only_fd);
-
- /*
- * Make sure that ftruncate on sockets doesn't work.
- */
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- err(-1, "socket(PF_UNIX, SOCK_STREAM, 0)");
- if (ftruncate(fd, 0) == 0)
- errx(-1, "ftruncate(socket) succeeded");
- if (errno != EINVAL)
- err(-1, "ftruncate(socket) returned wrong error");
- close(fd);
-
- /*
- * Make sure that ftruncate on pipes doesn't work.
- */
- if (pipe(fds) < 0)
- err(-1, "pipe");
- if (ftruncate(fds[0], 0) == 0)
- errx(-1, "ftruncate(pipe) succeeded");
- if (errno != EINVAL)
- err(-1, "ftruncate(pipe) returned wrong error");
- close(fds[0]);
- close(fds[1]);
-
- /*
- * Make sure that ftruncate on kqueues doesn't work.
- */
- fd = kqueue();
- if (fd < 0)
- err(-1, "kqueue");
- if (ftruncate(fds[0], 0) == 0)
- errx(-1, "ftruncate(kqueue) succeeded");
- if (errno != EINVAL)
- err(-1, "ftruncate(kqueue) returned wrong error");
- close(fd);
-
- return (0);
-}
diff --git a/tests/sys/file/newfileops_on_fork_test.c b/tests/sys/file/newfileops_on_fork_test.c
deleted file mode 100644
index 8713a82..0000000
--- a/tests/sys/file/newfileops_on_fork_test.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * Copyright (c) 2009 Robert N. M. Watson
- * All rights reserved.
- *
- * This software was developed at the University of Cambridge Computer
- * Laboratory with support from a grant from Google, Inc.
- *
- * 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$
- */
-
-/*
- * When a multi-threaded application calls fork(2) from one thread while
- * another thread is blocked in accept(2), we prefer that the file descriptor
- * to be returned by accept(2) not appear in the child process. Test this by
- * creating a thread blocked in accept(2), then forking a child and seeing if
- * the fd it would have returned is defined in the child or not.
- */
-
-#include <sys/socket.h>
-#include <sys/wait.h>
-
-#include <netinet/in.h>
-
-#include <err.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define PORT 9000
-
-static int listen_fd;
-
-static void *
-do_accept(__unused void *arg)
-{
- int accept_fd;
-
- accept_fd = accept(listen_fd, NULL, NULL);
- if (accept_fd < 0)
- err(-1, "accept");
-
- return (NULL);
-}
-
-static void
-do_fork(void)
-{
- int pid;
-
- pid = fork();
- if (pid < 0)
- err(-1, "fork");
- if (pid > 0) {
- waitpid(pid, NULL, 0);
- exit(0);
- }
-
- /*
- * We will call ftruncate(2) on the next available file descriptor,
- * listen_fd+1, and get back EBADF if it's not a valid descriptor,
- * and EINVAL if it is. This (currently) works fine in practice.
- */
- if (ftruncate(listen_fd + 1, 0 < 0)) {
- if (errno == EBADF)
- exit(0);
- else if (errno == EINVAL)
- errx(-1, "file descriptor still open in child");
- else
- err(-1, "unexpected error");
- } else
- errx(-1, "ftruncate succeeded");
-}
-
-int
-main(__unused int argc, __unused char *argv[])
-{
- struct sockaddr_in sin;
- pthread_t accept_thread;
-
- listen_fd = socket(PF_INET, SOCK_STREAM, 0);
- if (listen_fd < 0)
- err(-1, "socket");
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(PORT);
- if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "bind");
- if (listen(listen_fd, -1) <0)
- err(-1, "listen");
- if (pthread_create(&accept_thread, NULL, do_accept, NULL) != 0)
- err(-1, "pthread_create");
- sleep(1); /* Easier than using a CV. */;
- do_fork();
- exit(0);
-}
diff --git a/tests/sys/kqueue/Makefile b/tests/sys/kqueue/Makefile
deleted file mode 100644
index 43277ca..0000000
--- a/tests/sys/kqueue/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# $FreeBSD$
-#
-# svn://mark.heily.com/libkqueue/trunk/test
-# Last update: r114
-#
-# libkqueue and test suite by Mark Heily <mark@heily.com>
-#
-
-TAP_TESTS_SH= kqueue_test
-
-TESTSDIR= ${TESTSBASE}/sys/kqueue
-BINDIR= ${TESTSDIR}
-
-PROGS= kqtest
-
-SRCS.kqtest= \
- main.c \
- read.c \
- timer.c \
- vnode.c \
- proc.c \
- signal.c \
- user.c
-WARNS?= 2
-
-.include <bsd.test.mk>
diff --git a/tests/sys/kqueue/common.h b/tests/sys/kqueue/common.h
deleted file mode 100644
index aada778..0000000
--- a/tests/sys/kqueue/common.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#ifndef _COMMON_H
-#define _COMMON_H
-
-
-#if HAVE_ERR_H
-# include <err.h>
-#else
-# define err(rc,msg,...) do { perror(msg); exit(rc); } while (0)
-# define errx(rc,msg,...) do { puts(msg); exit(rc); } while (0)
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <sys/event.h>
-
-#include "config.h"
-
-extern char *cur_test_id;
-int vnode_fd;
-
-extern const char * kevent_to_str(struct kevent *);
-struct kevent * kevent_get(int);
-
-
-void kevent_cmp(struct kevent *, struct kevent *);
-
-void
-kevent_add(int kqfd, struct kevent *kev,
- uintptr_t ident,
- short filter,
- u_short flags,
- u_int fflags,
- intptr_t data,
- void *udata);
-
-/* DEPRECATED: */
-#define KEV_CMP(kev,_ident,_filter,_flags) do { \
- if (kev.ident != (_ident) || \
- kev.filter != (_filter) || \
- kev.flags != (_flags)) \
- err(1, "kevent mismatch: got [%d,%d,%d] but expecting [%d,%d,%d]", \
- (int)_ident, (int)_filter, (int)_flags,\
- (int)kev.ident, kev.filter, kev.flags);\
-} while (0);
-
-/* Checks if any events are pending, which is an error. */
-extern void test_no_kevents(void);
-
-extern void test_begin(const char *);
-extern void success(void);
-
-#endif /* _COMMON_H */
diff --git a/tests/sys/kqueue/config.h b/tests/sys/kqueue/config.h
deleted file mode 100644
index a204092..0000000
--- a/tests/sys/kqueue/config.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $FreeBSD$ */
-
-#define HAVE_ERR_H 1
-#define HAVE_SYS_EVENT_H 1
-#define HAVE_EV_DISPATCH 1
-#define HAVE_EV_RECEIPT 1
-#undef HAVE_NOTE_TRUNCATE
-#define HAVE_EVFILT_TIMER 1
-#define HAVE_EVFILT_USER 1
-#define PROGRAM "libkqueue-test"
-#define VERSION "0.1"
-#define TARGET "freebsd"
-#define CFLAGS "-g -O0 -Wall -Werror"
diff --git a/tests/sys/kqueue/kqueue_test.sh b/tests/sys/kqueue/kqueue_test.sh
deleted file mode 100755
index 62a7e23..0000000
--- a/tests/sys/kqueue/kqueue_test.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-cd $(dirname $0)
-i=1
-./kqtest | while read line; do
- echo $line | grep -q passed
- if [ $? -eq 0 ]; then
- echo "ok - $i $line"
- : $(( i += 1 ))
- fi
-
- echo $line | grep -q 'tests completed'
- if [ $? -eq 0 ]; then
- echo -n "1.."
- echo $line | cut -d' ' -f3
- fi
-done
diff --git a/tests/sys/kqueue/main.c b/tests/sys/kqueue/main.c
deleted file mode 100644
index f76c4e2..0000000
--- a/tests/sys/kqueue/main.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-
-#include "config.h"
-#include "common.h"
-
-int testnum = 1;
-char *cur_test_id = NULL;
-int kqfd;
-
-extern void test_evfilt_read();
-extern void test_evfilt_signal();
-extern void test_evfilt_vnode();
-extern void test_evfilt_timer();
-extern void test_evfilt_proc();
-#if HAVE_EVFILT_USER
-extern void test_evfilt_user();
-#endif
-
-/* Checks if any events are pending, which is an error. */
-void
-test_no_kevents(void)
-{
- int nfds;
- struct timespec timeo;
- struct kevent kev;
-
- puts("confirming that there are no events pending");
- memset(&timeo, 0, sizeof(timeo));
- nfds = kevent(kqfd, NULL, 0, &kev, 1, &timeo);
- if (nfds != 0) {
- puts("\nUnexpected event:");
- puts(kevent_to_str(&kev));
- errx(1, "%d event(s) pending, but none expected:", nfds);
- }
-}
-
-/* Retrieve a single kevent */
-struct kevent *
-kevent_get(int kqfd)
-{
- int nfds;
- struct kevent *kev;
-
- if ((kev = calloc(1, sizeof(*kev))) == NULL)
- err(1, "out of memory");
-
- nfds = kevent(kqfd, NULL, 0, kev, 1, NULL);
- if (nfds < 1)
- err(1, "kevent(2)");
-
- return (kev);
-}
-
-char *
-kevent_fflags_dump(struct kevent *kev)
-{
- char *buf;
-
-#define KEVFFL_DUMP(attrib) \
- if (kev->fflags & attrib) \
- strncat(buf, #attrib" ", 64);
-
- if ((buf = calloc(1, 1024)) == NULL)
- abort();
-
- /* Not every filter has meaningful fflags */
- if (kev->filter != EVFILT_VNODE) {
- snprintf(buf, 1024, "fflags = %d", kev->fflags);
- return (buf);
- }
-
- snprintf(buf, 1024, "fflags = %d (", kev->fflags);
- KEVFFL_DUMP(NOTE_DELETE);
- KEVFFL_DUMP(NOTE_WRITE);
- KEVFFL_DUMP(NOTE_EXTEND);
-#if HAVE_NOTE_TRUNCATE
- KEVFFL_DUMP(NOTE_TRUNCATE);
-#endif
- KEVFFL_DUMP(NOTE_ATTRIB);
- KEVFFL_DUMP(NOTE_LINK);
- KEVFFL_DUMP(NOTE_RENAME);
-#if HAVE_NOTE_REVOKE
- KEVFFL_DUMP(NOTE_REVOKE);
-#endif
- buf[strlen(buf) - 1] = ')';
-
- return (buf);
-}
-
-char *
-kevent_flags_dump(struct kevent *kev)
-{
- char *buf;
-
-#define KEVFL_DUMP(attrib) \
- if (kev->flags & attrib) \
- strncat(buf, #attrib" ", 64);
-
- if ((buf = calloc(1, 1024)) == NULL)
- abort();
-
- snprintf(buf, 1024, "flags = %d (", kev->flags);
- KEVFL_DUMP(EV_ADD);
- KEVFL_DUMP(EV_ENABLE);
- KEVFL_DUMP(EV_DISABLE);
- KEVFL_DUMP(EV_DELETE);
- KEVFL_DUMP(EV_ONESHOT);
- KEVFL_DUMP(EV_CLEAR);
- KEVFL_DUMP(EV_EOF);
- KEVFL_DUMP(EV_ERROR);
-#if HAVE_EV_DISPATCH
- KEVFL_DUMP(EV_DISPATCH);
-#endif
-#if HAVE_EV_RECEIPT
- KEVFL_DUMP(EV_RECEIPT);
-#endif
- buf[strlen(buf) - 1] = ')';
-
- return (buf);
-}
-
-/* Copied from ../kevent.c kevent_dump() and improved */
-const char *
-kevent_to_str(struct kevent *kev)
-{
- char buf[512];
-
- snprintf(&buf[0], sizeof(buf),
- "[ident=%d, filter=%d, %s, %s, data=%d, udata=%p]",
- (u_int) kev->ident,
- kev->filter,
- kevent_flags_dump(kev),
- kevent_fflags_dump(kev),
- (int) kev->data,
- kev->udata);
-
- return (strdup(buf));
-}
-
-void
-kevent_add(int kqfd, struct kevent *kev,
- uintptr_t ident,
- short filter,
- u_short flags,
- u_int fflags,
- intptr_t data,
- void *udata)
-{
- EV_SET(kev, ident, filter, flags, fflags, data, NULL);
- if (kevent(kqfd, kev, 1, NULL, 0, NULL) < 0) {
- printf("Unable to add the following kevent:\n%s\n",
- kevent_to_str(kev));
- err(1, "kevent(): %s", strerror(errno));
- }
-}
-
-void
-kevent_cmp(struct kevent *k1, struct kevent *k2)
-{
-/* XXX-
- Workaround for inconsistent implementation of kevent(2)
- */
-#ifdef __FreeBSD__
- if (k1->flags & EV_ADD)
- k2->flags |= EV_ADD;
-#endif
- if (memcmp(k1, k2, sizeof(*k1)) != 0) {
- printf("kevent_cmp: mismatch:\n %s !=\n %s\n",
- kevent_to_str(k1), kevent_to_str(k2));
- abort();
- }
-}
-
-void
-test_begin(const char *func)
-{
- if (cur_test_id)
- free(cur_test_id);
- cur_test_id = strdup(func);
- if (!cur_test_id)
- err(1, "strdup failed");
-
- printf("\n\nTest %d: %s\n", testnum++, func);
-}
-
-void
-success(void)
-{
- printf("%-70s %s\n", cur_test_id, "passed");
- free(cur_test_id);
- cur_test_id = NULL;
-}
-
-void
-test_kqueue(void)
-{
- test_begin("kqueue()");
- if ((kqfd = kqueue()) < 0)
- err(1, "kqueue()");
- test_no_kevents();
- success();
-}
-
-void
-test_kqueue_close(void)
-{
- test_begin("close(kq)");
- if (close(kqfd) < 0)
- err(1, "close()");
- success();
-}
-
-int
-main(int argc, char **argv)
-{
- int test_proc = 1;
- int test_socket = 1;
- int test_signal = 1;
- int test_vnode = 1;
- int test_timer = 1;
-#ifdef __FreeBSD__
- int test_user = 1;
-#else
- /* XXX-FIXME temporary */
- int test_user = 0;
-#endif
-
- while (argc) {
- if (strcmp(argv[0], "--no-proc") == 0)
- test_proc = 0;
- if (strcmp(argv[0], "--no-socket") == 0)
- test_socket = 0;
- if (strcmp(argv[0], "--no-timer") == 0)
- test_timer = 0;
- if (strcmp(argv[0], "--no-signal") == 0)
- test_signal = 0;
- if (strcmp(argv[0], "--no-vnode") == 0)
- test_vnode = 0;
- if (strcmp(argv[0], "--no-user") == 0)
- test_user = 0;
- argv++;
- argc--;
- }
-
- test_kqueue();
- test_kqueue_close();
-
- if (test_socket)
- test_evfilt_read();
- if (test_signal)
- test_evfilt_signal();
- if (test_vnode)
- test_evfilt_vnode();
-#if HAVE_EVFILT_USER
- if (test_user)
- test_evfilt_user();
-#endif
- if (test_timer)
- test_evfilt_timer();
- if (test_proc)
- test_evfilt_proc();
-
- printf("\n---\n"
- "+OK All %d tests completed.\n", testnum - 1);
- return (0);
-}
diff --git a/tests/sys/kqueue/proc.c b/tests/sys/kqueue/proc.c
deleted file mode 100644
index 6288ee6..0000000
--- a/tests/sys/kqueue/proc.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include <sys/stat.h>
-
-#include <err.h>
-
-#include "config.h"
-#include "common.h"
-
-static int sigusr1_caught = 0;
-
-int kqfd;
-
-static void
-sig_handler(int signum)
-{
- sigusr1_caught = 1;
-}
-
-static void
-add_and_delete(void)
-{
- struct kevent kev;
- pid_t pid;
-
- /* Create a child that waits to be killed and then exits */
- pid = fork();
- if (pid == 0) {
- struct stat s;
- if (fstat(kqfd, &s) != -1)
- errx(1, "kqueue inherited across fork! (%s() at %s:%d)",
- __func__, __FILE__, __LINE__);
-
- pause();
- exit(2);
- }
- printf(" -- child created (pid %d)\n", (int) pid);
-
- test_begin("kevent(EVFILT_PROC, EV_ADD)");
-
- test_no_kevents();
- kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL);
- test_no_kevents();
-
- success();
-
- test_begin("kevent(EVFILT_PROC, EV_DELETE)");
-
- sleep(1);
- test_no_kevents();
- kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_DELETE, 0, 0, NULL);
- if (kill(pid, SIGKILL) < 0)
- err(1, "kill");
- sleep(1);
- test_no_kevents();
-
- success();
-
-}
-
-#ifdef TODO
-static void
-event_trigger(void)
-{
- struct kevent kev;
- pid_t pid;
-
- test_begin("kevent(EVFILT_PROC, wait)");
-
- /* Create a child that waits to be killed and then exits */
- pid = fork();
- if (pid == 0) {
- pause();
- printf(" -- child caught signal, exiting\n");
- exit(2);
- }
- printf(" -- child created (pid %d)\n", (int) pid);
-
- test_no_kevents();
- kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL);
-
- /* Cause the child to exit, then retrieve the event */
- printf(" -- killing process %d\n", (int) pid);
- if (kill(pid, SIGUSR1) < 0)
- err(1, "kill");
- kevent_cmp(&kev, kevent_get(kqfd));
- test_no_kevents();
-
- success();
-}
-
-void
-test_kevent_signal_disable(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGKILL) < 0)
- err(1, "kill");
-
- test_no_kevents();
-
- success();
-}
-
-void
-test_kevent_signal_enable(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- kev.flags = EV_ADD | EV_CLEAR;
-#if LIBKQUEUE
- kev.data = 1; /* WORKAROUND */
-#else
- kev.data = 2; // one extra time from test_kevent_signal_disable()
-#endif
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Delete the watch */
- kev.flags = EV_DELETE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_signal_del(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Delete the kevent */
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- test_no_kevents();
- success();
-}
-
-void
-test_kevent_signal_oneshot(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- kev.flags |= EV_CLEAR;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Send another one and make sure we get no events */
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
- test_no_kevents();
-
- success();
-}
-#endif
-
-void
-test_evfilt_proc()
-{
- kqfd = kqueue();
-
- signal(SIGUSR1, sig_handler);
-
- add_and_delete();
-
-#if TODO
- event_trigger();
-#endif
-
- signal(SIGUSR1, SIG_DFL);
-
-#if TODO
- test_kevent_signal_add();
- test_kevent_signal_del();
- test_kevent_signal_get();
- test_kevent_signal_disable();
- test_kevent_signal_enable();
- test_kevent_signal_oneshot();
-#endif
- close(kqfd);
-}
diff --git a/tests/sys/kqueue/read.c b/tests/sys/kqueue/read.c
deleted file mode 100644
index cc65427..0000000
--- a/tests/sys/kqueue/read.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include "common.h"
-
-int kqfd;
-int sockfd[2];
-
-static void
-kevent_socket_drain(void)
-{
- char buf[1];
-
- /* Drain the read buffer, then make sure there are no more events. */
- puts("draining the read buffer");
- if (read(sockfd[0], &buf[0], 1) < 1)
- err(1, "read(2)");
-}
-
-static void
-kevent_socket_fill(void)
-{
- puts("filling the read buffer");
- if (write(sockfd[1], ".", 1) < 1)
- err(1, "write(2)");
-}
-
-
-void
-test_kevent_socket_add(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_ADD)";
- struct kevent kev;
-
- test_begin(test_id);
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_socket_get(void)
-{
- const char *test_id = "kevent(EVFILT_READ) wait";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kevent_socket_fill();
-
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- kevent_socket_drain();
- test_no_kevents();
-
- kev.flags = EV_DELETE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_socket_clear(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kevent_socket_fill();
- kevent_socket_fill();
-
- kev.data = 2;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* We filled twice, but drain once. Edge-triggered would not generate
- additional events.
- */
- kevent_socket_drain();
- test_no_kevents();
-
- kevent_socket_drain();
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_socket_disable_and_enable(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Add an event, then disable it. */
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DISABLE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kevent_socket_fill();
- test_no_kevents();
-
- /* Re-enable the knote, then see if an event is generated */
- kev.flags = EV_ENABLE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- kev.flags = EV_ADD;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- kevent_socket_drain();
-
- kev.flags = EV_DELETE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_socket_del(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kevent_socket_fill();
- test_no_kevents();
- kevent_socket_drain();
-
- success();
-}
-
-void
-test_kevent_socket_oneshot(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Re-add the watch and make sure no events are pending */
- puts("-- re-adding knote");
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- test_no_kevents();
-
- puts("-- getting one event");
- kevent_socket_fill();
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- puts("-- checking knote disabled");
- test_no_kevents();
-
- /* Try to delete the knote, it should already be deleted */
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
- err(1, "%s", test_id);
-
- kevent_socket_drain();
-
- success();
-}
-
-
-#if HAVE_EV_DISPATCH
-void
-test_kevent_socket_dispatch(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)";
-
- test_begin(test_id);
-
- struct kevent kev;
-
- /* Re-add the watch and make sure no events are pending */
- puts("-- re-adding knote");
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- test_no_kevents();
-
- /* The event will occur only once, even though EV_CLEAR is not
- specified. */
- kevent_socket_fill();
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
- test_no_kevents();
-
- /* Since the knote is disabled, the EV_DELETE operation succeeds. */
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kevent_socket_drain();
-
- success();
-}
-#endif /* HAVE_EV_DISPATCH */
-
-#if BROKEN
-void
-test_kevent_socket_lowat(void)
-{
- const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Re-add the watch and make sure no events are pending */
- puts("-- re-adding knote, setting low watermark to 2 bytes");
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- test_no_kevents();
-
- puts("-- checking that one byte does not trigger an event..");
- kevent_socket_fill();
- test_no_kevents();
-
- puts("-- checking that two bytes triggers an event..");
- kevent_socket_fill();
- if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1)
- err(1, "%s", test_id);
- KEV_CMP(kev, sockfd[0], EVFILT_READ, 0);
- test_no_kevents();
-
- kevent_socket_drain();
- kevent_socket_drain();
-
- success();
-}
-#endif
-
-void
-test_kevent_socket_eof(void)
-{
- const char *test_id = "kevent(EVFILT_READ, EV_EOF)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Re-add the watch and make sure no events are pending */
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- test_no_kevents();
-
- if (close(sockfd[1]) < 0)
- err(1, "close(2)");
-
- kev.flags |= EV_EOF;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Delete the watch */
- EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_evfilt_read()
-{
- /* Create a connected pair of full-duplex sockets for testing socket events */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
- abort();
-
- kqfd = kqueue();
- test_kevent_socket_add();
- test_kevent_socket_del();
- test_kevent_socket_get();
- test_kevent_socket_disable_and_enable();
- test_kevent_socket_oneshot();
- test_kevent_socket_clear();
-#if HAVE_EV_DISPATCH
- test_kevent_socket_dispatch();
-#endif
- test_kevent_socket_eof();
- close(kqfd);
-}
diff --git a/tests/sys/kqueue/signal.c b/tests/sys/kqueue/signal.c
deleted file mode 100644
index 14e751d..0000000
--- a/tests/sys/kqueue/signal.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include "common.h"
-
-int kqfd;
-
-void
-test_kevent_signal_add(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_ADD)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_signal_get(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, wait)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- kev.flags |= EV_CLEAR;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- success();
-}
-
-void
-test_kevent_signal_disable(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_DISABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DISABLE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- test_no_kevents();
-
- success();
-}
-
-void
-test_kevent_signal_enable(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_ENABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ENABLE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- kev.flags = EV_ADD | EV_CLEAR;
-#if LIBKQUEUE
- kev.data = 1; /* WORKAROUND */
-#else
- kev.data = 2; // one extra time from test_kevent_signal_disable()
-#endif
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Delete the watch */
- kev.flags = EV_DELETE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_signal_del(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- /* Delete the kevent */
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_DELETE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- test_no_kevents();
- success();
-}
-
-void
-test_kevent_signal_oneshot(void)
-{
- const char *test_id = "kevent(EVFILT_SIGNAL, EV_ONESHOT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Block SIGUSR1, then send it to ourselves */
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGUSR1);
- if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
- err(1, "sigprocmask");
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
-
- kev.flags |= EV_CLEAR;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Send another one and make sure we get no events */
- if (kill(getpid(), SIGUSR1) < 0)
- err(1, "kill");
- test_no_kevents();
-
- success();
-}
-
-void
-test_evfilt_signal()
-{
- kqfd = kqueue();
- test_kevent_signal_add();
- test_kevent_signal_del();
- test_kevent_signal_get();
- test_kevent_signal_disable();
- test_kevent_signal_enable();
- test_kevent_signal_oneshot();
- close(kqfd);
-}
diff --git a/tests/sys/kqueue/timer.c b/tests/sys/kqueue/timer.c
deleted file mode 100644
index 766125d..0000000
--- a/tests/sys/kqueue/timer.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include "common.h"
-
-int kqfd;
-
-void
-test_kevent_timer_add(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, EV_ADD)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_timer_del(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- test_no_kevents();
-
- success();
-}
-
-void
-test_kevent_timer_get(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, wait)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kev.flags |= EV_CLEAR;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-static void
-test_oneshot(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, EV_ONESHOT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500,NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Retrieve the event */
- kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Check if the event occurs again */
- sleep(3);
- test_no_kevents();
-
-
- success();
-}
-
-static void
-test_periodic(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, periodic)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000,NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Retrieve the event */
- kev.flags = EV_ADD | EV_CLEAR;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Check if the event occurs again */
- sleep(1);
- kevent_cmp(&kev, kevent_get(kqfd));
-
- /* Delete the event */
- kev.flags = EV_DELETE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-static void
-disable_and_enable(void)
-{
- const char *test_id = "kevent(EVFILT_TIMER, EV_DISABLE and EV_ENABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- /* Add the watch and immediately disable it */
- EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 2000,NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- kev.flags = EV_DISABLE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- test_no_kevents();
-
- /* Re-enable and check again */
- kev.flags = EV_ENABLE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT;
- kev.data = 1;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- success();
-}
-
-void
-test_evfilt_timer()
-{
- kqfd = kqueue();
- test_kevent_timer_add();
- test_kevent_timer_del();
- test_kevent_timer_get();
- test_oneshot();
- test_periodic();
- disable_and_enable();
- close(kqfd);
-}
diff --git a/tests/sys/kqueue/user.c b/tests/sys/kqueue/user.c
deleted file mode 100644
index 9ba25f9..0000000
--- a/tests/sys/kqueue/user.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include "common.h"
-
-int kqfd;
-
-static void
-add_and_delete(void)
-{
- const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
- test_no_kevents();
-
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL);
- test_no_kevents();
-
- success();
-}
-
-static void
-event_wait(void)
-{
- const char *test_id = "kevent(EVFILT_USER, wait)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- /* Add the event, and then trigger it */
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL);
- kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
-
- kev.fflags &= ~NOTE_FFCTRLMASK;
- kev.fflags &= ~NOTE_TRIGGER;
- kev.flags = EV_CLEAR;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- test_no_kevents();
-
- success();
-}
-
-static void
-disable_and_enable(void)
-{
- const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL);
-
- /* Trigger the event, but since it is disabled, nothing will happen. */
- kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
- test_no_kevents();
-
- kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL);
- kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
-
- kev.flags = EV_CLEAR;
- kev.fflags &= ~NOTE_FFCTRLMASK;
- kev.fflags &= ~NOTE_TRIGGER;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- success();
-}
-
-static void
-oneshot(void)
-{
- const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)";
- struct kevent kev;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL);
-
- puts(" -- event 1");
- kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
-
- kev.flags = EV_ONESHOT;
- kev.fflags &= ~NOTE_FFCTRLMASK;
- kev.fflags &= ~NOTE_TRIGGER;
- kevent_cmp(&kev, kevent_get(kqfd));
-
- test_no_kevents();
-
- success();
-}
-
-void
-test_evfilt_user()
-{
- kqfd = kqueue();
-
- add_and_delete();
- event_wait();
- disable_and_enable();
- oneshot();
- /* TODO: try different fflags operations */
-
- close(kqfd);
-}
diff --git a/tests/sys/kqueue/vnode.c b/tests/sys/kqueue/vnode.c
deleted file mode 100644
index dfa0b5e..0000000
--- a/tests/sys/kqueue/vnode.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 2009 Mark Heily <mark@heily.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include "common.h"
-
-int kqfd;
-int vnode_fd;
-
-void
-test_kevent_vnode_add(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)";
- const char *testfile = "/tmp/kqueue-test.tmp";
- struct kevent kev;
-
- test_begin(test_id);
-
- system("touch /tmp/kqueue-test.tmp");
- vnode_fd = open(testfile, O_RDONLY);
- if (vnode_fd < 0)
- err(1, "open of %s", testfile);
- else
- printf("vnode_fd = %d\n", vnode_fd);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD,
- NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME | NOTE_DELETE, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_vnode_note_delete(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- if (unlink("/tmp/kqueue-test.tmp") < 0)
- err(1, "unlink");
-
- kevent_cmp(&kev, kevent_get(kqfd));
-
- success();
-}
-
-void
-test_kevent_vnode_note_write(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, NOTE_WRITE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_WRITE, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- if (system("echo hello >> /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
-
- /* BSD kqueue adds NOTE_EXTEND even though it was not requested */
- /* BSD kqueue removes EV_ENABLE */
- kev.flags &= ~EV_ENABLE; // XXX-FIXME compatibility issue
- kev.fflags |= NOTE_EXTEND; // XXX-FIXME compatibility issue
- kevent_cmp(&kev, kevent_get(kqfd));
-
- success();
-}
-
-void
-test_kevent_vnode_note_attrib(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, NOTE_ATTRIB)";
- struct kevent kev;
- int nfds;
-
- test_begin(test_id);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- if (system("touch /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
-
- nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
- if (nfds < 1)
- err(1, "%s", test_id);
- if (kev.ident != vnode_fd ||
- kev.filter != EVFILT_VNODE ||
- kev.fflags != NOTE_ATTRIB)
- err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
- test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
-
- success();
-}
-
-void
-test_kevent_vnode_note_rename(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, NOTE_RENAME)";
- struct kevent kev;
- int nfds;
-
- test_begin(test_id);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_RENAME, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- if (system("mv /tmp/kqueue-test.tmp /tmp/kqueue-test2.tmp") < 0)
- err(1, "system");
-
- nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
- if (nfds < 1)
- err(1, "%s", test_id);
- if (kev.ident != vnode_fd ||
- kev.filter != EVFILT_VNODE ||
- kev.fflags != NOTE_RENAME)
- err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
- test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
-
- if (system("mv /tmp/kqueue-test2.tmp /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
-
- success();
-}
-
-void
-test_kevent_vnode_del(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, EV_DELETE)";
- struct kevent kev;
-
- test_begin(test_id);
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- success();
-}
-
-void
-test_kevent_vnode_disable_and_enable(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)";
- struct kevent kev;
- int nfds;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- /* Add the watch and immediately disable it */
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- kev.flags = EV_DISABLE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- /* Confirm that the watch is disabled */
- if (system("touch /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
- test_no_kevents();
-
- /* Re-enable and check again */
- kev.flags = EV_ENABLE;
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
- if (system("touch /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
- nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
- if (nfds < 1)
- err(1, "%s", test_id);
- if (kev.ident != vnode_fd ||
- kev.filter != EVFILT_VNODE ||
- kev.fflags != NOTE_ATTRIB)
- err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
- test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
-
- success();
-}
-
-#if HAVE_EV_DISPATCH
-void
-test_kevent_vnode_dispatch(void)
-{
- const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)";
- struct kevent kev;
- int nfds;
-
- test_begin(test_id);
-
- test_no_kevents();
-
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "%s", test_id);
-
- if (system("touch /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
-
- nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
- if (nfds < 1)
- err(1, "%s", test_id);
- if (kev.ident != vnode_fd ||
- kev.filter != EVFILT_VNODE ||
- kev.fflags != NOTE_ATTRIB)
- err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
- test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
-
- /* Confirm that the watch is disabled automatically */
- puts("-- checking that watch is disabled");
- if (system("touch /tmp/kqueue-test.tmp") < 0)
- err(1, "system");
- test_no_kevents();
-
- /* Delete the watch */
- EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL);
- if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
- err(1, "remove watch failed: %s", test_id);
-
- success();
-}
-#endif /* HAVE_EV_DISPATCH */
-
-void
-test_evfilt_vnode()
-{
- kqfd = kqueue();
- test_kevent_vnode_add();
- test_kevent_vnode_del();
- test_kevent_vnode_disable_and_enable();
-#if HAVE_EV_DISPATCH
- test_kevent_vnode_dispatch();
-#endif
- test_kevent_vnode_note_write();
- test_kevent_vnode_note_attrib();
- test_kevent_vnode_note_rename();
- test_kevent_vnode_note_delete();
- close(kqfd);
-}
diff --git a/tests/sys/mmap/Makefile b/tests/sys/mmap/Makefile
deleted file mode 100644
index 98809b4..0000000
--- a/tests/sys/mmap/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/mmap
-
-TAP_TESTS_C+= mmap
-
-.include <bsd.test.mk>
diff --git a/tests/sys/mmap/mmap.c b/tests/sys/mmap/mmap.c
deleted file mode 100644
index 7591a09..0000000
--- a/tests/sys/mmap/mmap.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 2009 Simon L. Nielsen <simon@FreeBSD.org>,
- * Bjoern A. Zeeb <bz@FreeBSD.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 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/param.h>
-#include <sys/mman.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-static const struct {
- void *addr;
- int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */
-} tests[] = {
- { (void *)0, { 0, 1 } }, /* Test sysctl. */
- { (void *)1, { 0, 0 } },
- { (void *)(PAGE_SIZE - 1), { 0, 0 } },
- { (void *)PAGE_SIZE, { 1, 1 } },
- { (void *)-1, { 0, 0 } },
- { (void *)(-PAGE_SIZE), { 0, 0 } },
- { (void *)(-1 - PAGE_SIZE), { 0, 0 } },
- { (void *)(-1 - PAGE_SIZE - 1), { 0, 0 } },
- { (void *)(0x1000 * PAGE_SIZE), { 1, 1 } },
-};
-
-#define MAP_AT_ZERO "security.bsd.map_at_zero"
-
-int
-main(void)
-{
- void *p;
- size_t len;
- int i, error, mib[3], map_at_zero;
-
- error = 0;
-
- /* Get the current sysctl value of security.bsd.map_at_zero. */
- len = sizeof(mib) / sizeof(*mib);
- if (sysctlnametomib(MAP_AT_ZERO, mib, &len) == -1) {
- printf("1..0 # SKIP: sysctlnametomib(\"%s\") failed: %s\n",
- MAP_AT_ZERO, strerror(errno));
- return (0);
- }
-
- len = sizeof(map_at_zero);
- if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1) {
- printf("1..0 # SKIP: sysctl for %s failed: %s\n", MAP_AT_ZERO,
- strerror(errno));
- return (0);
- }
-
- /* Normalize to 0 or 1 for array access. */
- map_at_zero = !!map_at_zero;
-
- printf("1..%zu\n", nitems(tests));
- for (i = 0; i < (int)nitems(tests); i++) {
- p = mmap((void *)tests[i].addr, PAGE_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED,
- -1, 0);
- if (p == MAP_FAILED) {
- if (tests[i].ok[map_at_zero] != 0)
- error++;
- printf("%sok %d # mmap(%p, ...) failed\n",
- tests[i].ok[map_at_zero] == 0 ? "" : "not ",
- i + 1,
- tests[i].addr);
- } else {
- if (tests[i].ok[map_at_zero] != 1)
- error++;
- printf("%sok %d # mmap(%p, ...) succeeded: p=%p\n",
- tests[i].ok[map_at_zero] == 1 ? "" : "not ",
- i + 1,
- tests[i].addr, p);
- }
- }
-
- return (error != 0);
-}
diff --git a/tests/sys/mqueue/Makefile b/tests/sys/mqueue/Makefile
deleted file mode 100644
index 230fcb7..0000000
--- a/tests/sys/mqueue/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/mqueue
-
-ATF_TESTS_SH= mqueue_test
-
-BINDIR= ${TESTSDIR}
-
-PROGS+= mqtest1
-PROGS+= mqtest2
-PROGS+= mqtest3
-PROGS+= mqtest4
-PROGS+= mqtest5
-
-LDADD+= -lrt
-DPADD+= ${LIBRT}
-
-WARNS?= 6
-
-.include <bsd.test.mk>
diff --git a/tests/sys/mqueue/mqtest1.c b/tests/sys/mqueue/mqtest1.c
deleted file mode 100644
index 5590b87..0000000
--- a/tests/sys/mqueue/mqtest1.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $FreeBSD$ */
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <signal.h>
-#include <stdio.h>
-
-#define MQNAME "/mytstqueue1"
-
-int
-main(void)
-{
- struct mq_attr attr, attr2;
- struct sigevent sigev;
- mqd_t mq;
- int status;
-
- attr.mq_maxmsg = 2;
- attr.mq_msgsize = 100;
- mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
- if (mq == (mqd_t)-1)
- err(1, "mq_open");
- status = mq_unlink(MQNAME);
- if (status)
- err(1, "mq_unlink");
- status = mq_getattr(mq, &attr2);
- if (status)
- err(1, "mq_getattr");
- if (attr.mq_maxmsg != attr2.mq_maxmsg)
- err(1, "mq_maxmsg changed");
- if (attr.mq_msgsize != attr2.mq_msgsize)
- err(1, "mq_msgsize changed");
-
- sigev.sigev_notify = SIGEV_SIGNAL;
- sigev.sigev_signo = SIGRTMIN;
- status = mq_notify(mq, &sigev);
- if (status)
- err(1, "mq_notify");
- status = mq_notify(mq, &sigev);
- if (status == 0)
- err(1, "mq_notify 2");
- else if (errno != EBUSY)
- err(1, "mq_notify 3");
- status = mq_notify(mq, NULL);
- if (status)
- err(1, "mq_notify 4");
- status = mq_close(mq);
- if (status)
- err(1, "mq_close");
- return (0);
-}
diff --git a/tests/sys/mqueue/mqtest2.c b/tests/sys/mqueue/mqtest2.c
deleted file mode 100644
index aaef43b..0000000
--- a/tests/sys/mqueue/mqtest2.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* $FreeBSD$ */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <err.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define MQNAME "/mytstqueue2"
-#define LOOPS 1000
-#define PRIO 10
-
-static void
-alarmhandler(int sig __unused)
-{
- write(1, "timeout\n", 8);
- _exit(1);
-}
-
-int
-main(void)
-{
- struct mq_attr attr;
- mqd_t mq;
- int status;
- pid_t pid;
-
- mq_unlink(MQNAME);
-
- attr.mq_maxmsg = 5;
- attr.mq_msgsize = 128;
- mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
- if (mq == (mqd_t)-1)
- err(1, "mq_open");
- status = mq_getattr(mq, &attr);
- if (status)
- err(1, "mq_getattr");
- pid = fork();
- if (pid == 0) { /* child */
- char *buf;
- int j, i;
- unsigned int prio;
-
- mq_close(mq);
-
- signal(SIGALRM, alarmhandler);
-
- mq = mq_open(MQNAME, O_RDWR);
- if (mq == (mqd_t)-1)
- err(1, "child: mq_open");
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- alarm(3);
- status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
- if (status == -1)
- err(2, "child: mq_receive");
- for (i = 0; i < attr.mq_msgsize; ++i)
- if (buf[i] != i)
- err(3, "child: message data corrupted");
- if (prio != PRIO)
- err(4, "child: priority is incorrect: %d",
- prio);
- }
- alarm(0);
- free(buf);
- mq_close(mq);
- return (0);
- } else if (pid == -1) {
- err(1, "fork()");
- } else {
- char *buf;
- int i, j;
-
- signal(SIGALRM, alarmhandler);
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- for (i = 0; i < attr.mq_msgsize; ++i)
- buf[i] = i;
- alarm(3);
- status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
- if (status)
- err(1, "mq_send");
- }
- alarm(3);
- wait(&status);
- alarm(0);
- }
- status = mq_close(mq);
- if (status)
- err(1, "mq_close");
- mq_unlink(MQNAME);
- return (0);
-}
diff --git a/tests/sys/mqueue/mqtest3.c b/tests/sys/mqueue/mqtest3.c
deleted file mode 100644
index 4ee812c..0000000
--- a/tests/sys/mqueue/mqtest3.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* $FreeBSD$ */
-
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <err.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define MQNAME "/mytstqueue3"
-#define LOOPS 1000
-#define PRIO 10
-
-static void
-sighandler(int sig __unused)
-{
- write(1, "timeout\n", 8);
- _exit(1);
-}
-
-int
-main(void)
-{
- fd_set set;
- struct mq_attr attr;
- int status;
- mqd_t mq;
- pid_t pid;
-
- mq_unlink(MQNAME);
-
- attr.mq_maxmsg = 5;
- attr.mq_msgsize = 128;
- mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
- if (mq == (mqd_t)-1)
- err(1, "mq_open()");
- status = mq_getattr(mq, &attr);
- if (status)
- err(1, "mq_getattr()");
-
- pid = fork();
- if (pid == 0) { /* child */
- char *buf;
- int j, i;
- unsigned int prio;
-
- mq_close(mq);
-
- signal(SIGALRM, sighandler);
-
- mq = mq_open(MQNAME, O_RDWR);
- if (mq == (mqd_t)-1)
- err(1, "child process: mq_open");
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- FD_ZERO(&set);
- FD_SET(__mq_oshandle(mq), &set);
- alarm(3);
- status = select(__mq_oshandle(mq)+1, &set, NULL, NULL, NULL);
- if (status != 1)
- err(1, "child process: select()");
- status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
- if (status == -1)
- err(2, "child process: mq_receive");
- for (i = 0; i < attr.mq_msgsize; ++i)
- if (buf[i] != i)
- err(3, "message data corrupted");
- if (prio != PRIO)
- err(4, "priority is incorrect: %d", prio);
- }
- alarm(0);
- free(buf);
- mq_close(mq);
- return (0);
- } else if (pid == -1) {
- err(1, "fork()");
- } else {
- char *buf;
- int i, j;
-
- signal(SIGALRM, sighandler);
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- for (i = 0; i < attr.mq_msgsize; ++i) {
- buf[i] = i;
- }
- alarm(3);
- FD_ZERO(&set);
- FD_SET(__mq_oshandle(mq), &set);
- status = select(__mq_oshandle(mq)+1, NULL, &set, NULL, NULL);
- if (status != 1)
- err(1, "select()");
- status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
- if (status) {
- kill(pid, SIGKILL);
- err(2, "mq_send()");
- }
- }
- alarm(3);
- wait(&status);
- alarm(0);
- }
- status = mq_close(mq);
- if (status)
- err(1, "mq_close");
- mq_unlink(MQNAME);
- return (0);
-}
diff --git a/tests/sys/mqueue/mqtest4.c b/tests/sys/mqueue/mqtest4.c
deleted file mode 100644
index d249cf6..0000000
--- a/tests/sys/mqueue/mqtest4.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $FreeBSD$ */
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <err.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define MQNAME "/mytstqueue4"
-#define LOOPS 1000
-#define PRIO 10
-
-static void
-sighandler(int sig __unused)
-{
- write(1, "timeout\n", 8);
- _exit(1);
-}
-
-int
-main(void)
-{
- struct kevent kev;
- struct mq_attr attr;
- mqd_t mq;
- int kq, status;
- pid_t pid;
-
- mq_unlink(MQNAME);
-
- attr.mq_maxmsg = 5;
- attr.mq_msgsize = 128;
- mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
- if (mq == (mqd_t) -1)
- err(1, "mq_open()");
- status = mq_getattr(mq, &attr);
- if (status)
- err(1, "mq_getattr()");
- pid = fork();
- if (pid == 0) { /* child */
- char *buf;
- int j, i;
- unsigned int prio;
-
- mq_close(mq);
- kq = kqueue();
- mq = mq_open(MQNAME, O_RDWR);
- if (mq == (mqd_t)-1)
- err(1, "child: mq_open");
- EV_SET(&kev, __mq_oshandle(mq), EVFILT_READ, EV_ADD, 0, 0, 0);
- status = kevent(kq, &kev, 1, NULL, 0, NULL);
- if (status == -1)
- err(1, "child: kevent");
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- alarm(3);
- status = kevent(kq, NULL, 0, &kev, 1, NULL);
- if (status != 1)
- err(1, "child: kevent 2");
- status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
- if (status == -1)
- err(2, "child: mq_receive");
- for (i = 0; i < attr.mq_msgsize; ++i)
- if (buf[i] != i)
- err(3, "child: message data corrupted");
- if (prio != PRIO)
- err(4, "child: priority is incorrect: %d",
- prio);
- }
- alarm(0);
- free(buf);
- mq_close(mq);
- return (0);
- } else if (pid == -1) {
- err(1, "fork()");
- } else {
- char *buf;
- int i, j;
-
- signal(SIGALRM, sighandler);
- kq = kqueue();
- EV_SET(&kev, __mq_oshandle(mq), EVFILT_WRITE, EV_ADD, 0, 0, 0);
- status = kevent(kq, &kev, 1, NULL, 0, NULL);
- if (status == -1)
- err(1, "kevent");
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- for (i = 0; i < attr.mq_msgsize; ++i) {
- buf[i] = i;
- }
- alarm(3);
- status = kevent(kq, NULL, 0, &kev, 1, NULL);
- if (status != 1)
- err(1, "child: kevent 2");
- status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
- if (status) {
- err(2, "mq_send()");
- }
- }
- free(buf);
- alarm(3);
- wait(&status);
- alarm(0);
- }
- status = mq_close(mq);
- if (status)
- err(1, "mq_close");
- mq_unlink(MQNAME);
- return (0);
-}
diff --git a/tests/sys/mqueue/mqtest5.c b/tests/sys/mqueue/mqtest5.c
deleted file mode 100644
index 7f4d554..0000000
--- a/tests/sys/mqueue/mqtest5.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $FreeBSD$ */
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <err.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define MQNAME "/mytstqueue5"
-#define LOOPS 1000
-#define PRIO 10
-
-static void
-sighandler(int sig __unused)
-{
- write(1, "timeout\n", 8);
- _exit(1);
-}
-
-int
-main(void)
-{
- int status;
- struct mq_attr attr;
- struct sigaction sa;
- sigset_t set;
- siginfo_t info;
- mqd_t mq;
- pid_t pid;
-
- mq_unlink(MQNAME);
-
- sigemptyset(&set);
- sigaddset(&set, SIGRTMIN);
- sigprocmask(SIG_BLOCK, &set, NULL);
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = (void *) SIG_DFL;
- sigaction(SIGRTMIN, &sa, NULL);
-
- attr.mq_maxmsg = 5;
- attr.mq_msgsize = 128;
- mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
- if (mq == (mqd_t)-1)
- err(1, "mq_open()");
- status = mq_getattr(mq, &attr);
- if (status)
- err(1, "mq_getattr()");
- pid = fork();
- if (pid == 0) { /* child */
- int prio, j, i;
- char *buf;
- struct sigevent sigev;
-
- signal(SIGALRM, sighandler);
-
- sigev.sigev_notify = SIGEV_SIGNAL;
- sigev.sigev_signo = SIGRTMIN;
- sigev.sigev_value.sival_int = 2;
-
- mq_close(mq);
- mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK);
- if (mq == (mqd_t)-1)
- err(1, "child: mq_open");
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- alarm(3);
- status = mq_notify(mq, &sigev);
- if (status)
- err(1, "child: mq_notify");
- status = sigwaitinfo(&set, &info);
- if (status == -1)
- err(1, "child: sigwaitinfo");
- if (info.si_value.sival_int != 2)
- err(1, "child: sival_int");
- status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
- if (status == -1)
- err(2, "child: mq_receive");
- for (i = 0; i < attr.mq_msgsize; ++i)
- if (buf[i] != i)
- err(3, "child: message data corrupted");
- if (prio != PRIO)
- err(4, "child: priority is incorrect: %d",
- prio);
- }
- alarm(0);
- free(buf);
- mq_close(mq);
- return (0);
- } else if (pid == -1) {
- err(1, "fork()");
- } else {
- char *buf;
- int i, j;
-
- signal(SIGALRM, sighandler);
- buf = malloc(attr.mq_msgsize);
- for (j = 0; j < LOOPS; ++j) {
- for (i = 0; i < attr.mq_msgsize; ++i) {
- buf[i] = i;
- }
- alarm(3);
- status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
- if (status) {
- kill(pid, SIGKILL);
- err(2, "mq_send()");
- }
- }
- alarm(3);
- wait(&status);
- alarm(0);
- }
- status = mq_close(mq);
- if (status)
- err(1, "mq_close");
- mq_unlink(MQNAME);
- return (0);
-}
diff --git a/tests/sys/posixshm/Makefile b/tests/sys/posixshm/Makefile
deleted file mode 100644
index cb27345..0000000
--- a/tests/sys/posixshm/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/posixshm
-
-TAP_TESTS_C= posixshm_test
-SRCS.posixshm_test= posixshm.c test.c
-
-WARNS?= 6
-
-.include <bsd.test.mk>
diff --git a/tests/sys/posixshm/posixshm.c b/tests/sys/posixshm/posixshm.c
deleted file mode 100644
index e21f45a..0000000
--- a/tests/sys/posixshm/posixshm.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/wait.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "test.h"
-
-#define TEST_PATH "/tmp/posixshm_regression_test"
-
-/*
- * Attempt a shm_open() that should fail with an expected error of 'error'.
- */
-static void
-shm_open_should_fail(const char *path, int flags, mode_t mode, int error)
-{
- int fd;
-
- fd = shm_open(path, flags, mode);
- if (fd >= 0) {
- fail_err("shm_open() didn't fail");
- close(fd);
- return;
- }
- if (errno != error) {
- fail_errno("shm_open");
- return;
- }
- pass();
-}
-
-/*
- * Attempt a shm_unlink() that should fail with an expected error of 'error'.
- */
-static void
-shm_unlink_should_fail(const char *path, int error)
-{
-
- if (shm_unlink(path) >= 0) {
- fail_err("shm_unlink() didn't fail");
- return;
- }
- if (errno != error) {
- fail_errno("shm_unlink");
- return;
- }
- pass();
-}
-
-/*
- * Open the test object and write '1' to the first byte. Returns valid fd
- * on success and -1 on failure.
- */
-static int
-scribble_object(void)
-{
- char *page;
- int fd;
-
- fd = shm_open(TEST_PATH, O_CREAT | O_EXCL | O_RDWR, 0777);
- if (fd < 0 && errno == EEXIST) {
- if (shm_unlink(TEST_PATH) < 0) {
- fail_errno("shm_unlink");
- return (-1);
- }
- fd = shm_open(TEST_PATH, O_CREAT | O_EXCL | O_RDWR, 0777);
- }
- if (fd < 0) {
- fail_errno("shm_open");
- return (-1);
- }
- if (ftruncate(fd, getpagesize()) < 0) {
- fail_errno("ftruncate");
- close(fd);
- shm_unlink(TEST_PATH);
- return (-1);
- }
-
- page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd,
- 0);
- if (page == MAP_FAILED) {
- fail_errno("mmap");
- close(fd);
- shm_unlink(TEST_PATH);
- return (-1);
- }
-
- page[0] = '1';
-
- if (munmap(page, getpagesize()) < 0) {
- fail_errno("munmap");
- close(fd);
- shm_unlink(TEST_PATH);
- return (-1);
- }
-
- return (fd);
-}
-
-static void
-remap_object(void)
-{
- char *page;
- int fd;
-
- fd = scribble_object();
- if (fd < 0)
- return;
-
- page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd,
- 0);
- if (page == MAP_FAILED) {
- fail_errno("mmap(2)");
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
-
- if (page[0] != '1') {
- fail_err("missing data");
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
-
- close(fd);
- if (munmap(page, getpagesize()) < 0) {
- fail_errno("munmap");
- shm_unlink(TEST_PATH);
- return;
- }
-
- if (shm_unlink(TEST_PATH) < 0) {
- fail_errno("shm_unlink");
- return;
- }
-
- pass();
-}
-TEST(remap_object, "remap object");
-
-static void
-reopen_object(void)
-{
- char *page;
- int fd;
-
- fd = scribble_object();
- if (fd < 0)
- return;
- close(fd);
-
- fd = shm_open(TEST_PATH, O_RDONLY, 0777);
- if (fd < 0) {
- fail_errno("shm_open(2)");
- shm_unlink(TEST_PATH);
- return;
- }
- page = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
- if (page == MAP_FAILED) {
- fail_errno("mmap(2)");
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
-
- if (page[0] != '1') {
- fail_err("missing data");
- munmap(page, getpagesize());
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
-
- munmap(page, getpagesize());
- close(fd);
- shm_unlink(TEST_PATH);
- pass();
-}
-TEST(reopen_object, "reopen object");
-
-static void
-readonly_mmap_write(void)
-{
- char *page;
- int fd;
-
- fd = shm_open(TEST_PATH, O_RDONLY | O_CREAT, 0777);
- if (fd < 0) {
- fail_errno("shm_open");
- return;
- }
-
- /* PROT_WRITE should fail with EACCES. */
- page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd,
- 0);
- if (page != MAP_FAILED) {
- fail_err("mmap(PROT_WRITE) succeeded");
- munmap(page, getpagesize());
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
- if (errno != EACCES) {
- fail_errno("mmap");
- close(fd);
- shm_unlink(TEST_PATH);
- return;
- }
-
- close(fd);
- shm_unlink(TEST_PATH);
- pass();
-}
-TEST(readonly_mmap_write, "RDONLY object");
-
-static void
-open_after_unlink(void)
-{
- int fd;
-
- fd = shm_open(TEST_PATH, O_RDONLY | O_CREAT, 0777);
- if (fd < 0) {
- fail_errno("shm_open(1)");
- return;
- }
- close(fd);
-
- if (shm_unlink(TEST_PATH) < 0) {
- fail_errno("shm_unlink");
- return;
- }
-
- shm_open_should_fail(TEST_PATH, O_RDONLY, 0777, ENOENT);
-}
-TEST(open_after_unlink, "open after unlink");
-
-static void
-open_invalid_path(void)
-{
-
- shm_open_should_fail("blah", O_RDONLY, 0777, EINVAL);
-}
-TEST(open_invalid_path, "open invalid path");
-
-static void
-open_write_only(void)
-{
-
- shm_open_should_fail(TEST_PATH, O_WRONLY, 0777, EINVAL);
-}
-TEST(open_write_only, "open with O_WRONLY");
-
-static void
-open_extra_flags(void)
-{
-
- shm_open_should_fail(TEST_PATH, O_RDONLY | O_DIRECT, 0777, EINVAL);
-}
-TEST(open_extra_flags, "open with extra flags");
-
-static void
-open_anon(void)
-{
- int fd;
-
- fd = shm_open(SHM_ANON, O_RDWR, 0777);
- if (fd < 0) {
- fail_errno("shm_open");
- return;
- }
- close(fd);
- pass();
-}
-TEST(open_anon, "open anonymous object");
-
-static void
-open_anon_readonly(void)
-{
-
- shm_open_should_fail(SHM_ANON, O_RDONLY, 0777, EINVAL);
-}
-TEST(open_anon_readonly, "open SHM_ANON with O_RDONLY");
-
-static void
-open_bad_path_pointer(void)
-{
-
- shm_open_should_fail((char *)1024, O_RDONLY, 0777, EFAULT);
-}
-TEST(open_bad_path_pointer, "open bad path pointer");
-
-static void
-open_path_too_long(void)
-{
- char *page;
-
- page = malloc(MAXPATHLEN + 1);
- memset(page, 'a', MAXPATHLEN);
- page[MAXPATHLEN] = '\0';
- shm_open_should_fail(page, O_RDONLY, 0777, ENAMETOOLONG);
- free(page);
-}
-TEST(open_path_too_long, "open pathname too long");
-
-static void
-open_nonexisting_object(void)
-{
-
- shm_open_should_fail("/notreallythere", O_RDONLY, 0777, ENOENT);
-}
-TEST(open_nonexisting_object, "open nonexistent object");
-
-static void
-exclusive_create_existing_object(void)
-{
- int fd;
-
- fd = shm_open("/tmp/notreallythere", O_RDONLY | O_CREAT, 0777);
- if (fd < 0) {
- fail_errno("shm_open(O_CREAT)");
- return;
- }
- close(fd);
-
- shm_open_should_fail("/tmp/notreallythere", O_RDONLY | O_CREAT | O_EXCL,
- 0777, EEXIST);
-
- shm_unlink("/tmp/notreallythere");
-}
-TEST(exclusive_create_existing_object, "O_EXCL of existing object");
-
-static void
-trunc_resets_object(void)
-{
- struct stat sb;
- int fd;
-
- /* Create object and set size to 1024. */
- fd = shm_open(TEST_PATH, O_RDWR | O_CREAT, 0777);
- if (fd < 0) {
- fail_errno("shm_open(1)");
- return;
- }
- if (ftruncate(fd, 1024) < 0) {
- fail_errno("ftruncate");
- close(fd);
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(1)");
- close(fd);
- return;
- }
- if (sb.st_size != 1024) {
- fail_err("size %d != 1024", (int)sb.st_size);
- close(fd);
- return;
- }
- close(fd);
-
- /* Open with O_TRUNC which should reset size to 0. */
- fd = shm_open(TEST_PATH, O_RDWR | O_TRUNC, 0777);
- if (fd < 0) {
- fail_errno("shm_open(2)");
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(2)");
- close(fd);
- return;
- }
- if (sb.st_size != 0) {
- fail_err("size after O_TRUNC %d != 0", (int)sb.st_size);
- close(fd);
- return;
- }
- close(fd);
- if (shm_unlink(TEST_PATH) < 0) {
- fail_errno("shm_unlink");
- return;
- }
- pass();
-}
-TEST(trunc_resets_object, "O_TRUNC resets size");
-
-static void
-unlink_bad_path_pointer(void)
-{
-
- shm_unlink_should_fail((char *)1024, EFAULT);
-}
-TEST(unlink_bad_path_pointer, "unlink bad path pointer");
-
-static void
-unlink_path_too_long(void)
-{
- char *page;
-
- page = malloc(MAXPATHLEN + 1);
- memset(page, 'a', MAXPATHLEN);
- page[MAXPATHLEN] = '\0';
- shm_unlink_should_fail(page, ENAMETOOLONG);
- free(page);
-}
-TEST(unlink_path_too_long, "unlink pathname too long");
-
-static void
-test_object_resize(void)
-{
- pid_t pid;
- struct stat sb;
- char *page;
- int fd, status;
-
- /* Start off with a size of a single page. */
- fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0777);
- if (fd < 0) {
- fail_errno("shm_open");
- return;
- }
- if (ftruncate(fd, getpagesize()) < 0) {
- fail_errno("ftruncate(1)");
- close(fd);
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(1)");
- close(fd);
- return;
- }
- if (sb.st_size != getpagesize()) {
- fail_err("first resize failed");
- close(fd);
- return;
- }
-
- /* Write a '1' to the first byte. */
- page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd,
- 0);
- if (page == MAP_FAILED) {
- fail_errno("mmap(1)");
- close(fd);
- return;
- }
-
- page[0] = '1';
-
- if (munmap(page, getpagesize()) < 0) {
- fail_errno("munmap(1)");
- close(fd);
- return;
- }
-
- /* Grow the object to 2 pages. */
- if (ftruncate(fd, getpagesize() * 2) < 0) {
- fail_errno("ftruncate(2)");
- close(fd);
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(2)");
- close(fd);
- return;
- }
- if (sb.st_size != getpagesize() * 2) {
- fail_err("second resize failed");
- close(fd);
- return;
- }
-
- /* Check for '1' at the first byte. */
- page = mmap(0, getpagesize() * 2, PROT_READ | PROT_WRITE, MAP_SHARED,
- fd, 0);
- if (page == MAP_FAILED) {
- fail_errno("mmap(2)");
- close(fd);
- return;
- }
-
- if (page[0] != '1') {
- fail_err("missing data at 0");
- close(fd);
- return;
- }
-
- /* Write a '2' at the start of the second page. */
- page[getpagesize()] = '2';
-
- /* Shrink the object back to 1 page. */
- if (ftruncate(fd, getpagesize()) < 0) {
- fail_errno("ftruncate(3)");
- close(fd);
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(3)");
- close(fd);
- return;
- }
- if (sb.st_size != getpagesize()) {
- fail_err("third resize failed");
- close(fd);
- return;
- }
-
- /*
- * Fork a child process to make sure the second page is no
- * longer valid.
- */
- pid = fork();
- if (pid < 0) {
- fail_errno("fork");
- close(fd);
- return;
- }
-
- if (pid == 0) {
- struct rlimit lim;
- char c;
-
- /* Don't generate a core dump. */
- getrlimit(RLIMIT_CORE, &lim);
- lim.rlim_cur = 0;
- setrlimit(RLIMIT_CORE, &lim);
-
- /*
- * The previous ftruncate(2) shrunk the backing object
- * so that this address is no longer valid, so reading
- * from it should trigger a SIGSEGV.
- */
- c = page[getpagesize()];
- fprintf(stderr, "child: page 1: '%c'\n", c);
- exit(0);
- }
- if (wait(&status) < 0) {
- fail_errno("wait");
- close(fd);
- return;
- }
- if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGSEGV) {
- fail_err("child terminated with status %x", status);
- close(fd);
- return;
- }
-
- /* Grow the object back to 2 pages. */
- if (ftruncate(fd, getpagesize() * 2) < 0) {
- fail_errno("ftruncate(4)");
- close(fd);
- return;
- }
- if (fstat(fd, &sb) < 0) {
- fail_errno("fstat(4)");
- close(fd);
- return;
- }
- if (sb.st_size != getpagesize() * 2) {
- fail_err("second resize failed");
- close(fd);
- return;
- }
-
- /*
- * Note that the mapping at 'page' for the second page is
- * still valid, and now that the shm object has been grown
- * back up to 2 pages, there is now memory backing this page
- * so the read will work. However, the data should be zero
- * rather than '2' as the old data was thrown away when the
- * object was shrunk and the new pages when an object are
- * grown are zero-filled.
- */
- if (page[getpagesize()] != 0) {
- fail_err("invalid data at %d", getpagesize());
- close(fd);
- return;
- }
-
- close(fd);
- pass();
-}
-TEST(test_object_resize, "object resize");
-
-int
-main(void)
-{
-
- run_tests();
- return (0);
-}
diff --git a/tests/sys/posixshm/test.c b/tests/sys/posixshm/test.c
deleted file mode 100644
index 8583a0d..0000000
--- a/tests/sys/posixshm/test.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*-
- * Copyright (c) 2008 Yahoo!, Inc.
- * All rights reserved.
- * Written by: John Baldwin <jhb@FreeBSD.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.
- * 3. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <stdarg.h>
-#include <stdio.h>
-
-#include "test.h"
-
-static int test_index;
-static struct regression_test *test;
-static int test_acknowleged;
-
-SET_DECLARE(regression_tests_set, struct regression_test);
-
-/*
- * Outputs a test summary of the following:
- *
- * <status> <test #> [name] [# <fmt> [fmt args]]
- */
-static void
-vprint_status(const char *status, const char *fmt, va_list ap)
-{
-
- printf("%s %d", status, test_index);
- if (test->rt_name)
- printf(" - %s", test->rt_name);
- if (fmt) {
- printf(" # ");
- vprintf(fmt, ap);
- }
- printf("\n");
- test_acknowleged = 1;
-}
-
-static void
-print_status(const char *status, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vprint_status(status, fmt, ap);
- va_end(ap);
-}
-
-void
-pass(void)
-{
-
- print_status("ok", NULL);
-}
-
-void
-fail(void)
-{
-
- print_status("not ok", NULL);
-}
-
-void
-fail_err(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vprint_status("not ok", fmt, ap);
- va_end(ap);
-}
-
-void
-skip(const char *reason)
-{
-
- print_status("ok", "skip %s", reason);
-}
-
-void
-todo(const char *reason)
-{
-
- print_status("not ok", "TODO %s", reason);
-}
-
-void
-run_tests(void)
-{
- struct regression_test **testp;
-
- printf("1..%td\n", SET_COUNT(regression_tests_set));
- test_index = 1;
- SET_FOREACH(testp, regression_tests_set) {
- test_acknowleged = 0;
- test = *testp;
- test->rt_function();
- if (!test_acknowleged)
- print_status("not ok", "unknown status");
- test_index++;
- }
-}
diff --git a/tests/sys/posixshm/test.h b/tests/sys/posixshm/test.h
deleted file mode 100644
index 505679b..0000000
--- a/tests/sys/posixshm/test.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 2008 Yahoo!, Inc.
- * All rights reserved.
- * Written by: John Baldwin <jhb@FreeBSD.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.
- * 3. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * 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$
- */
-
-#ifndef __TEST_H__
-#define __TEST_H__
-
-#include <sys/linker_set.h>
-
-struct regression_test {
- void (*rt_function)(void);
- const char *rt_name;
-};
-
-#define TEST(function, name) \
- static struct regression_test _regtest_##function = { \
- (function), \
- (name) \
- }; \
- DATA_SET(regression_tests_set, _regtest_##function)
-
-void fail(void);
-void fail_err(const char *fmt, ...);
-void pass(void);
-void run_tests(void);
-void skip(const char *reason);
-void todo(const char *reason);
-
-#define fail_errno(tag) fail_err("%s: %s", (tag), strerror(errno))
-
-#endif /* !__TEST_H__ */
diff --git a/tests/sys/sockets/Makefile b/tests/sys/sockets/Makefile
deleted file mode 100644
index ac18a8e..0000000
--- a/tests/sys/sockets/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-# $FreeBSD$
-#
-# Some of these tests fail on 11.0-CURRENT @ r280355 with DEBUG bits on
-
-TESTSDIR= ${TESTSBASE}/sys/socket
-
-BINDIR= ${TESTSDIR}
-
-PROGS+= unix_cmsg
-
-TAP_TESTS_C+= accept_fd_leak_test
-# accf_data_attach: not ok 9 - setsockopt() after listen() failed with 2 (No such file or directory)
-TAP_TESTS_C+= accf_data_attach_test
-PLAIN_TESTS_C+= fstat_test
-PLAIN_TESTS_C+= kqueue_test
-PLAIN_TESTS_C+= listen_backlog_test
-PLAIN_TESTS_C+= listenclose_test
-PLAIN_TESTS_C+= pr_atomic_test
-PLAIN_TESTS_C+= reconnect_test
-# rtsocket: socket(PF_ROUTE, SOCK_STREAM, 0): Protocol wrong type for socket
-PLAIN_TESTS_C+= rtsocket_test
-PLAIN_TESTS_C+= sblock_test
-TAP_TESTS_C+= sendfile_test
-PLAIN_TESTS_C+= shutdown_test
-PLAIN_TESTS_C+= sigpipe_test
-TAP_TESTS_C+= so_setfib_test
-PLAIN_TESTS_C+= socketpair_test
-PLAIN_TESTS_C+= unix_bindconnect_test
-PLAIN_TESTS_C+= unix_close_race_test
-# Lots of failures
-TAP_TESTS_SH+= unix_cmsg_test
-# unix_gc: twosome_drop1: sendfd: before 0 after 0
-PLAIN_TESTS_C+= unix_gc_test
-# unix_passfd: test8-rights+creds+payload: recvmsg: 24 bytes received
-PLAIN_TESTS_C+= unix_passfd_test
-PLAIN_TESTS_C+= unix_sendtorace_test
-# unix_socket: socket(PF_LOCAL, SOCK_RAW, 0): Protocol wrong type for socket
-PLAIN_TESTS_C+= unix_socket_test
-PLAIN_TESTS_C+= unix_sorflush_test
-# zerosend: tcp_0write: bind(127.0.0.1, 10001): Address already in use
-PLAIN_TESTS_C+= zerosend_test
-
-DPADD.sendfile_test+= ${LIBMD}
-LDADD.sendfile_test+= -lmd
-
-# XXX: this doesn't work..?
-#WARNS.unix_cmsg= 3
-#WARNS.unix_gc= 3
-#WARNS.unix_passfd= 3
-#WARNS.zerosend= 2
-
-WARNS= 2
-
-.include <bsd.test.mk>
diff --git a/tests/sys/sockets/README.unix_cmsg b/tests/sys/sockets/README.unix_cmsg
deleted file mode 100644
index df51723..0000000
--- a/tests/sys/sockets/README.unix_cmsg
+++ /dev/null
@@ -1,160 +0,0 @@
-$FreeBSD$
-
-About unix_cmsg
-===============
-
-This program is a collection of regression tests for ancillary data
-(control information) for PF_LOCAL sockets (local domain or Unix domain
-sockets). There are tests for stream and datagram sockets.
-
-Usually each test does following steps: creates Server, forks Client,
-Client sends something to Server, Server verifies whether everything is
-correct in received message(s).
-
-It is better to change the owner of unix_cmsg to some safe user
-(eg. nobody:nogroup) and set SUID and SGID bits, else some tests that
-check credentials can give correct results for wrong implementation.
-
-It is better to run this program by a user that belongs to more
-than 16 groups.
-
-Available options
-=================
-
-usage: unix_cmsg [-dh] [-n num] [-s size] [-t type] [-z value] [testno]
-
- Options are:
- -d Output debugging information
- -h Output the help message and exit
- -n num Number of messages to send
- -s size Specify size of data for IPC
- -t type Specify socket type (stream, dgram) for tests
- -z value Do not send data in a message (bit 0x1), do not send
- data array associated with a cmsghdr structure (bit 0x2)
- testno Run one test by its number (require the -t option)
-
-Description
-===========
-
-If Client sends something to Server, then it sends 5 messages by default.
-Number of messages can be changed in the -n command line option. Number
-of messages will be given as N in the following descriptions.
-
-If Client sends something to Server, then it sends some data (few bytes)
-in each message by default. The size of this data can be changed by the -s
-command line option. The "-s 0" command line option means, that Client will
-send zero bytes represented by { NULL, 0 } value of struct iovec{}, referenced
-by the msg_iov field from struct msghdr{}. The "-z 1" or "-z 3" command line
-option means, that Client will send zero bytes represented by the NULL value
-in the msg_iov field from struct msghdr{}.
-
-If Client sends some ancillary data object, then this ancillary data object
-always has associated data array by default. The "-z 2" or "-z 3" option
-means, that Client will not send associated data array if possible.
-
-For SOCK_STREAM sockets:
------------------------
-
- 1: Sending, receiving cmsgcred
-
- Client connects to Server and sends N messages with SCM_CREDS ancillary
- data object. Server should receive N messages, each message should
- have SCM_CREDS ancillary data object followed by struct cmsgcred{}.
-
- 2: Receiving sockcred (listening socket)
-
- Server creates a listening stream socket and sets the LOCAL_CREDS
- socket option for it. Client connects to Server two times, each time
- it sends N messages. Server accepts two connections and receives N
- messages from each connection. The first message from each connection
- should have SCM_CREDS ancillary data object followed by struct sockcred{},
- next messages from the same connection should not have ancillary data.
-
- 3: Receiving sockcred (accepted socket)
-
- Client connects to Server. Server accepts connection and sets the
- LOCAL_CREDS socket option for just accepted socket. Client sends N
- messages to Server. Server should receive N messages, the first
- message should have SCM_CREDS ancillary data object followed by
- struct sockcred{}, next messages should not have ancillary data.
-
- 4: Sending cmsgcred, receiving sockcred
-
- Server creates a listening stream socket and sets the LOCAL_CREDS
- socket option for it. Client connects to Server and sends N messages
- with SCM_CREDS ancillary data object. Server should receive N messages,
- the first message should have SCM_CREDS ancillary data object followed
- by struct sockcred{}, each of next messages should have SCM_CREDS
- ancillary data object followed by struct cmsgcred{}.
-
- 5: Sending, receiving timeval
-
- Client connects to Server and sends message with SCM_TIMESTAMP ancillary
- data object. Server should receive one message with SCM_TIMESTAMP
- ancillary data object followed by struct timeval{}.
-
- 6: Sending, receiving bintime
-
- Client connects to Server and sends message with SCM_BINTIME ancillary
- data object. Server should receive one message with SCM_BINTIME
- ancillary data object followed by struct bintime{}.
-
- 7: Checking cmsghdr.cmsg_len
-
- Client connects to Server and tries to send several messages with
- SCM_CREDS ancillary data object that has wrong cmsg_len field in its
- struct cmsghdr{}. All these attempts should fail, since cmsg_len
- in all requests is less than CMSG_LEN(0).
-
- 8: Check LOCAL_PEERCRED socket option
-
- This test does not use ancillary data, but can be implemented here.
- Client connects to Server. Both Client and Server verify that
- credentials of the peer are correct using LOCAL_PEERCRED socket option.
-
-For SOCK_DGRAM sockets:
-----------------------
-
- 1: Sending, receiving cmsgcred
-
- Client connects to Server and sends N messages with SCM_CREDS ancillary
- data object. Server should receive N messages, each message should
- have SCM_CREDS ancillary data object followed by struct cmsgcred{}.
-
- 2: Receiving sockcred
-
- Server creates datagram socket and sets the LOCAL_CREDS socket option
- for it. Client sends N messages to Server. Server should receive N
- messages, each message should have SCM_CREDS ancillary data object
- followed by struct sockcred{}.
-
- 3: Sending cmsgcred, receiving sockcred
-
- Server creates datagram socket and sets the LOCAL_CREDS socket option
- for it. Client sends N messages with SCM_CREDS ancillary data object
- to Server. Server should receive N messages, the first message should
- have SCM_CREDS ancillary data object followed by struct sockcred{},
- each of next messages should have SCM_CREDS ancillary data object
- followed by struct cmsgcred{}.
-
- 4: Sending, receiving timeval
-
- Client sends one message with SCM_TIMESTAMP ancillary data object
- to Server. Server should receive one message with SCM_TIMESTAMP
- ancillary data object followed by struct timeval{}.
-
- 5: Sending, receiving bintime
-
- Client sends one message with SCM_BINTIME ancillary data object
- to Server. Server should receive one message with SCM_BINTIME
- ancillary data object followed by struct bintime{}.
-
- 6: Checking cmsghdr.cmsg_len
-
- Client tries to send Server several messages with SCM_CREDS ancillary
- data object that has wrong cmsg_len field in its struct cmsghdr{}.
- All these attempts should fail, since cmsg_len in all requests is less
- than CMSG_LEN(0).
-
-- Andrey Simonenko
-andreysimonenko@users.sourceforge.net
diff --git a/tests/sys/sockets/accept_fd_leak_test.c b/tests/sys/sockets/accept_fd_leak_test.c
deleted file mode 100644
index 659c22d..0000000
--- a/tests/sys/sockets/accept_fd_leak_test.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * Copyright (c) 2004 Robert N. M. Watson
- * 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/param.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-
-#include <netinet/in.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>
-
-#define BIND_ATTEMPTS 10
-#define LOOPS 500
-#define NUM_ATTEMPTS 1000
-
-static volatile int quit;
-
-static void
-child_died(int sig __unused)
-{
-
- quit = 1;
-}
-
-/*
- * This test is intended to detect a leak of a file descriptor in the process
- * following a failed non-blocking accept. It measures an available fd
- * baseline, then performs 1000 failing accepts, then checks to see what the
- * next fd is. It relies on sequential fd allocation, and will test for it
- * briefly before beginning (not 100% reliable, but a good start).
- */
-int
-main(void)
-{
- struct sockaddr_in sin;
- socklen_t size;
- pid_t child;
- int fd1, fd2, fd3, i, listen_port, s, status;
-
- printf("1..2\n");
-
- /*
- * Check for sequential fd allocation, and give up early if not.
- */
- fd1 = dup(STDIN_FILENO);
- fd2 = dup(STDIN_FILENO);
- if (fd2 != fd1 + 1)
- errx(-1, "Non-sequential fd allocation\n");
-
- s = socket(PF_INET, SOCK_STREAM, 0);
- if (s == -1)
- errx(-1, "socket: %s", strerror(errno));
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- srandomdev();
-
- for (i = 0; i < BIND_ATTEMPTS; i++) {
- /* Pick a random unprivileged port 1025-65535 */
- listen_port = MAX((int)random() % 65535, 1025);
- sin.sin_port = htons(listen_port);
- if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == 0)
- break;
- warn("bind with %d failed", listen_port);
- usleep(1000);
- }
- if (i >= BIND_ATTEMPTS) {
- printf("Bail out!\n");
- exit(1);
- }
-
- if (listen(s, -1) != 0)
- errx(-1, "listen: %s", strerror(errno));
-
- i = fcntl(s, F_GETFL);
- if (i == -1)
- errx(-1, "ioctl(F_GETFL): %s", strerror(errno));
- i |= O_NONBLOCK;
- if (fcntl(s, F_SETFL, i) != 0)
- errx(-1, "ioctl(F_SETFL): %s", strerror(errno));
- i = fcntl(s, F_GETFL);
- if (i == -1)
- errx(-1, "ioctl(F_GETFL): %s", strerror(errno));
- if ((i & O_NONBLOCK) != O_NONBLOCK)
- errx(-1, "Failed to set O_NONBLOCK (i=0x%x)\n", i);
-
- for (i = 0; i < LOOPS; i++) {
- size = sizeof(sin);
- if (accept(s, (struct sockaddr *)&sin, &size) != -1)
- errx(-1, "accept succeeded\n");
- if (errno != EAGAIN)
- errx(-1, "accept: %s", strerror(errno));
- }
-
- /*
- * Allocate a file descriptor and make sure it's fd2+2. 2 because
- * we allocate an fd for the socket.
- */
- fd3 = dup(STDIN_FILENO);
- if (fd3 != fd2 + 2)
- printf("not ok 1 - (%d, %d, %d)\n", fd1, fd2, fd3);
- else
- printf("ok 1\n");
-
- /*
- * Try failing accept's w/o non-blocking where the destination
- * address pointer is invalid.
- */
- close(fd3);
- signal(SIGCHLD, child_died);
- child = fork();
- if (child < 0)
- errx(-1, "fork: %s", strerror(errno));
-
- /*
- * Child process does `NUM_ATTEMPTS` connects.
- */
- if (child == 0) {
- close(fd1);
- close(fd2);
- close(s);
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(listen_port);
-
- for (i = 0; i < NUM_ATTEMPTS; i++) {
- s = socket(PF_INET, SOCK_STREAM, 0);
- if (s == -1)
- errx(-1, "socket: %s", strerror(errno));
- if (connect(s, (struct sockaddr *)&sin,
- sizeof(sin)) < 0)
- errx(-1, "connect: %s", strerror(errno));
- close(s);
- }
- _exit(0);
- }
-
- /* Reset back to a blocking socket. */
- i = fcntl(s, F_GETFL);
- if (i == -1)
- errx(-1, "ioctl(F_GETFL): %s", strerror(errno));
- i &= ~O_NONBLOCK;
- if (fcntl(s, F_SETFL, i) != 0)
- errx(-1, "ioctl(F_SETFL): %s", strerror(errno));
- i = fcntl(s, F_GETFL);
- if (i == -1)
- errx(-1, "ioctl(F_GETFL): %s", strerror(errno));
- if (i & O_NONBLOCK)
- errx(-1, "Failed to clear O_NONBLOCK (i=0x%x)\n", i);
-
- /* Do `NUM_ATTEMPTS` accepts with an invalid pointer. */
- for (i = 0; !quit && i < NUM_ATTEMPTS; i++) {
- size = sizeof(sin);
- if (accept(s, (struct sockaddr *)(uintptr_t)(0x100),
- &size) != -1)
- errx(-1, "accept succeeded\n");
- if (errno != EFAULT)
- errx(-1, "accept: %s", strerror(errno));
- }
-
- if (waitpid(child, &status, 0) < 0)
- errx(-1, "waitpid: %s", strerror(errno));
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- warnx("child process died");
-
- /*
- * Allocate a file descriptor and make sure it's fd2+2. 2 because
- * we allocate an fd for the socket.
- */
- fd3 = dup(STDIN_FILENO);
- if (fd3 != fd2 + 2)
- printf("not ok 2 - (%d, %d, %d)\n", fd1, fd2, fd3);
- else
- printf("ok 2\n");
-
- return (0);
-}
diff --git a/tests/sys/sockets/accf_data_attach_test.c b/tests/sys/sockets/accf_data_attach_test.c
deleted file mode 100644
index 59ea68c..0000000
--- a/tests/sys/sockets/accf_data_attach_test.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*-
- * Copyright (c) 2004 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ACCF_NAME "dataready"
-
-/*
- * A number of small tests to confirm that attaching ACCF_DATA accept filters
- * to inet4 ports works as expected. We test:
- *
- * - That no accept filter is attached on a newly created socket.
- * - That bind() has no affect on the accept filter state.
- * - That we can't attach an accept filter to a socket that isn't in the
- * listen state.
- * - That after we fail to attach the filter, querying the kernel shows no
- * filter attached.
- * - That we can attach an accept filter to a socket that is in the listen
- * state.
- * - That once an accept filter is attached, we can query to make sure it is
- * attached.
- * - That once an accept filter is attached, we can remove it and query to
- * make sure it is removed.
- */
-int
-main(void)
-{
- struct accept_filter_arg afa;
- struct sockaddr_in sin;
- socklen_t len;
- int lso, ret;
-
- printf("1..11\n");
-
- /*
- * Step 0. Open socket().
- */
- lso = socket(PF_INET, SOCK_STREAM, 0);
- if (lso == -1)
- errx(-1, "not ok 1 - socket: %s", strerror(errno));
- printf("ok 1 - socket\n");
-
- /*
- * Step 1. After socket(). Should return EINVAL, since no accept
- * filter should be attached.
- */
- bzero(&afa, sizeof(afa));
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret != -1)
- errx(-1, "not ok 2 - getsockopt() after socket() succeeded");
- if (errno != EINVAL)
- errx(-1, "not ok 2 - getsockopt() after socket() failed with "
- "%d (%s)", errno, strerror(errno));
- printf("ok 2 - getsockopt\n");
-
- /*
- * Step 2. Bind(). Ideally this will succeed.
- */
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_port = htons(8080);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- if (bind(lso, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- errx(-1, "not ok 3 - bind %s", strerror(errno));
- printf("ok 3 - bind\n");
-
- /*
- * Step 3: After bind(). getsockopt() should return EINVAL, since no
- * accept filter should be attached.
- */
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret != -1)
- errx(-1, "not ok 4 - getsockopt() after bind() succeeded");
- if (errno != EINVAL)
- errx(-1, "not ok 4 - getsockopt() after bind() failed with %d (%s)",
- errno, strerror(errno));
- printf("ok 4 - getsockopt\n");
-
- /*
- * Step 4: Setsockopt() before listen(). Should fail, since it's not
- * yet a listen() socket.
- */
- bzero(&afa, sizeof(afa));
- strcpy(afa.af_name, ACCF_NAME);
- ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa));
- if (ret == 0)
- errx(-1, "not ok 5 - setsockopt() before listen() succeeded");
- printf("ok 5 - setsockopt\n");
-
- /*
- * Step 5: Getsockopt() after pre-listen() setsockopt(). Should
- * fail with EINVAL, since setsockopt() should have failed.
- */
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret == 0)
- errx(-1, "not ok 6 - getsockopt() after pre-listen() setsockopt() "
- "succeeded");
- if (errno != EINVAL)
- errx(-1, "not ok 6 - pre-listen() getsockopt() failed with %d (%s)",
- errno, strerror(errno));
- printf("ok 6 - getsockopt\n");
-
- /*
- * Step 6: listen().
- */
- if (listen(lso, -1) < 0)
- errx(-1, "not ok 7 - listen: %s", strerror(errno));
- printf("ok 7 - listen\n");
-
- /*
- * Step 7: Getsockopt() after listen(). Should fail with EINVAL,
- * since we have not installed accept filter yet.
- */
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret == 0)
- errx(-1, "not ok 8 - getsockopt() after listen() but before "
- "setsockopt() succeeded");
- if (errno != EINVAL)
- errx(-1, "not ok 8 - getsockopt() after listen() but before "
- "setsockopt() failed with %d (%s)", errno, strerror(errno));
- printf("ok 8 - getsockopt\n");
-
- /*
- * Step 8: After listen(). This call to setsockopt() should succeed.
- */
- bzero(&afa, sizeof(afa));
- strcpy(afa.af_name, ACCF_NAME);
- ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa));
- if (ret != 0)
- errx(-1, "not ok 9 - setsockopt() after listen() failed with %d "
- "(%s)", errno, strerror(errno));
- printf("ok 9 - setsockopt\n");
-
- /*
- * Step 9: After setsockopt(). Should succeed and identify
- * ACCF_NAME.
- */
- bzero(&afa, sizeof(afa));
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret != 0)
- errx(-1, "not ok 10 - getsockopt() after listen() setsockopt() "
- "failed with %d (%s)", errno, strerror(errno));
- if (len != sizeof(afa))
- errx(-1, "not ok 10 - getsockopt() after setsockopet() after "
- "listen() returned wrong size (got %d expected %zd)", len,
- sizeof(afa));
- if (strcmp(afa.af_name, ACCF_NAME) != 0)
- errx(-1, "not ok 10 - getsockopt() after setsockopt() after "
- "listen() mismatch (got %s expected %s)", afa.af_name,
- ACCF_NAME);
- printf("ok 10 - getsockopt\n");
-
- /*
- * Step 10: Remove accept filter. After removing the accept filter
- * getsockopt() should fail with EINVAL.
- */
- ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0);
- if (ret != 0)
- errx(-1, "not ok 11 - setsockopt() after listen() "
- "failed with %d (%s)", errno, strerror(errno));
- bzero(&afa, sizeof(afa));
- len = sizeof(afa);
- ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len);
- if (ret == 0)
- errx(-1, "not ok 11 - getsockopt() after removing "
- "the accept filter returns valid accept filter %s",
- afa.af_name);
- if (errno != EINVAL)
- errx(-1, "not ok 11 - getsockopt() after removing the accept"
- "filter failed with %d (%s)", errno, strerror(errno));
- printf("ok 11 - setsockopt\n");
-
- close(lso);
- return (0);
-}
diff --git a/tests/sys/sockets/fstat_test.c b/tests/sys/sockets/fstat_test.c
deleted file mode 100644
index 6ea931d..0000000
--- a/tests/sys/sockets/fstat_test.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 2008 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <unistd.h>
-
-/*
- * Basic test to make sure that fstat(2) returns success on various socket
- * types. In the future we should also validate the fields, confirming
- * expected results such as the effect of shutdown(2) on permissions, etc.
- */
-
-static void
-dotest(int domain, int type, int protocol)
-{
- struct stat sb;
- int sock;
-
- sock = socket(domain, type, protocol);
- if (sock < 0)
- err(-1, "socket(%d, %d, %d)", domain, type, protocol);
-
- if (fstat(sock, &sb) < 0)
- err(-1, "fstat on socket(%d, %d, %d)", domain, type,
- protocol);
-
- close(sock);
-}
-
-int
-main(void)
-{
-
- dotest(PF_INET, SOCK_DGRAM, 0);
- dotest(PF_INET, SOCK_STREAM, 0);
- dotest(PF_INET6, SOCK_DGRAM, 0);
- dotest(PF_INET6, SOCK_STREAM, 0);
- dotest(PF_LOCAL, SOCK_DGRAM, 0);
- dotest(PF_LOCAL, SOCK_STREAM, 0);
-
- return (0);
-}
diff --git a/tests/sys/sockets/kqueue_test.c b/tests/sys/sockets/kqueue_test.c
deleted file mode 100644
index f73704a..0000000
--- a/tests/sys/sockets/kqueue_test.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*-
- * Copyright (c) 2004 Robert N. M. Watson
- * 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/types.h>
-#include <sys/event.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int curtest = 1;
-
-/*-
- * This test uses UNIX domain socket pairs to perform some basic exercising
- * of kqueue functionality on sockets. In particular, testing that for read
- * and write filters, we see the correct detection of whether reads and
- * writes should actually be able to occur.
- *
- * TODO:
- * - Test read/write filters for listen/accept sockets.
- * - Handle the XXXRW below regarding datagram sockets.
- * - Test that watermark/buffer size "data" fields returned by kqueue are
- * correct.
- * - Check that kqueue does something sensible when the remote endpoing is
- * closed.
- */
-
-#define OK(testname) printf("ok %d - %s\n", curtest, testname); \
- curtest++;
-
-static void
-fail(int error, const char *func, const char *socktype, const char *rest)
-{
-
- printf("not ok %d\n", curtest);
-
- if (socktype == NULL)
- printf("# %s(): %s\n", func, strerror(error));
- else if (rest == NULL)
- printf("# %s(%s): %s\n", func, socktype,
- strerror(error));
- else
- printf("# %s(%s, %s): %s\n", func, socktype, rest,
- strerror(error));
- exit(-1);
-}
-
-static void
-fail_assertion(const char *func, const char *socktype, const char *rest,
- const char *assertion)
-{
-
- printf("not ok %d - %s\n", curtest, assertion);
-
- if (socktype == NULL)
- printf("# %s(): assertion %s failed\n", func,
- assertion);
- else if (rest == NULL)
- printf("# %s(%s): assertion %s failed\n", func,
- socktype, assertion);
- else
- printf("# %s(%s, %s): assertion %s failed\n", func,
- socktype, rest, assertion);
- exit(-1);
-}
-
-/*
- * Test read kevent on a socket pair: check to make sure endpoint 0 isn't
- * readable when we start, then write to endpoint 1 and confirm that endpoint
- * 0 is now readable. Drain the write, then check that it's not readable
- * again. Use non-blocking kqueue operations and socket operations.
- */
-static void
-test_evfilt_read(int kq, int fd[2], const char *socktype)
-{
- struct timespec ts;
- struct kevent ke;
- ssize_t len;
- char ch;
- int i;
-
- EV_SET(&ke, fd[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
- if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
- fail(errno, "kevent", socktype, "EVFILT_READ, EV_ADD");
- OK("EVFILT_READ, EV_ADD");
-
- /*
- * Confirm not readable to begin with, no I/O yet.
- */
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- i = kevent(kq, NULL, 0, &ke, 1, &ts);
- if (i == -1)
- fail(errno, "kevent", socktype, "EVFILT_READ");
- OK("EVFILT_READ");
- if (i != 0)
- fail_assertion("kevent", socktype, "EVFILT_READ",
- "empty socket unreadable");
- OK("empty socket unreadable");
-
- /*
- * Write a byte to one end.
- */
- ch = 'a';
- len = write(fd[1], &ch, sizeof(ch));
- if (len == -1)
- fail(errno, "write", socktype, NULL);
- OK("write one byte");
- if (len != sizeof(ch))
- fail_assertion("write", socktype, NULL, "write length");
- OK("write one byte length");
-
- /*
- * Other end should now be readable.
- */
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- i = kevent(kq, NULL, 0, &ke, 1, &ts);
- if (i == -1)
- fail(errno, "kevent", socktype, "EVFILT_READ");
- OK("EVFILT_READ");
- if (i != 1)
- fail_assertion("kevent", socktype, "EVFILT_READ",
- "non-empty socket unreadable");
- OK("non-empty socket unreadable");
-
- /*
- * Read a byte to clear the readable state.
- */
- len = read(fd[0], &ch, sizeof(ch));
- if (len == -1)
- fail(errno, "read", socktype, NULL);
- OK("read one byte");
- if (len != sizeof(ch))
- fail_assertion("read", socktype, NULL, "read length");
- OK("read one byte length");
-
- /*
- * Now re-check for readability.
- */
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- i = kevent(kq, NULL, 0, &ke, 1, &ts);
- if (i == -1)
- fail(errno, "kevent", socktype, "EVFILT_READ");
- OK("EVFILT_READ");
- if (i != 0)
- fail_assertion("kevent", socktype, "EVFILT_READ",
- "empty socket unreadable");
- OK("empty socket unreadable");
-
- EV_SET(&ke, fd[0], EVFILT_READ, EV_DELETE, 0, 0, NULL);
- if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
- fail(errno, "kevent", socktype, "EVFILT_READ, EV_DELETE");
- OK("EVFILT_READ, EV_DELETE");
-}
-
-static void
-test_evfilt_write(int kq, int fd[2], const char *socktype)
-{
- struct timespec ts;
- struct kevent ke;
- ssize_t len;
- char ch;
- int i;
-
- EV_SET(&ke, fd[0], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
- if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
- fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_ADD");
- OK("EVFILE_WRITE, EV_ADD");
-
- /*
- * Confirm writable to begin with, no I/O yet.
- */
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- i = kevent(kq, NULL, 0, &ke, 1, &ts);
- if (i == -1)
- fail(errno, "kevent", socktype, "EVFILT_WRITE");
- OK("EVFILE_WRITE");
- if (i != 1)
- fail_assertion("kevent", socktype, "EVFILT_WRITE",
- "empty socket unwritable");
- OK("empty socket unwritable");
-
- /*
- * Write bytes into the socket until we can't write anymore.
- */
- ch = 'a';
- while ((len = write(fd[0], &ch, sizeof(ch))) == sizeof(ch)) {};
- if (len == -1 && errno != EAGAIN && errno != ENOBUFS)
- fail(errno, "write", socktype, NULL);
- OK("write");
- if (len != -1 && len != sizeof(ch))
- fail_assertion("write", socktype, NULL, "write length");
- OK("write length");
-
- /*
- * Check to make sure the socket is no longer writable.
- */
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- i = kevent(kq, NULL, 0, &ke, 1, &ts);
- if (i == -1)
- fail(errno, "kevent", socktype, "EVFILT_WRITE");
- OK("EVFILT_WRITE");
- if (i != 0)
- fail_assertion("kevent", socktype, "EVFILT_WRITE",
- "full socket writable");
- OK("full socket writable");
-
- EV_SET(&ke, fd[0], EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
- if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
- fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_DELETE");
- OK("EVFILT_WRITE, EV_DELETE");
-}
-
-/*
- * Basic registration exercise for kqueue(2). Create several types/brands of
- * sockets, and confirm that we can register for various events on them.
- */
-int
-main(void)
-{
- int kq, sv[2];
-
- printf("1..49\n");
-
- kq = kqueue();
- if (kq == -1)
- fail(errno, "kqueue", NULL, NULL);
- OK("kqueue()");
-
- /*
- * Create a UNIX domain datagram socket, and attach/test/detach a
- * read filter on it.
- */
- if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
- fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
- OK("socketpair() 1");
-
- if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
- OK("fcntl() 1");
- if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
- OK("fnctl() 2");
-
- test_evfilt_read(kq, sv, "PF_UNIX, SOCK_DGRAM");
-
- if (close(sv[0]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
- OK("close() 1");
- if (close(sv[1]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
- OK("close() 2");
-
-#if 0
- /*
- * XXXRW: We disable the write test in the case of datagram sockets,
- * as kqueue can't tell when the remote socket receive buffer is
- * full, whereas the UNIX domain socket implementation can tell and
- * returns ENOBUFS.
- */
- /*
- * Create a UNIX domain datagram socket, and attach/test/detach a
- * write filter on it.
- */
- if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
- fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
-
- if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
- if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
-
- test_evfilt_write(kq, sv, "PF_UNIX, SOCK_DGRAM");
-
- if (close(sv[0]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
- if (close(sv[1]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
-#endif
-
- /*
- * Create a UNIX domain stream socket, and attach/test/detach a
- * read filter on it.
- */
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
- fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
- OK("socketpair() 2");
-
- if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
- OK("fcntl() 3");
- if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
- OK("fcntl() 4");
-
- test_evfilt_read(kq, sv, "PF_UNIX, SOCK_STREAM");
-
- if (close(sv[0]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
- OK("close() 3");
- if (close(sv[1]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
- OK("close() 4");
-
- /*
- * Create a UNIX domain stream socket, and attach/test/detach a
- * write filter on it.
- */
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
- fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
- OK("socketpair() 3");
-
- if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
- OK("fcntl() 5");
- if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
- fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
- OK("fcntl() 6");
-
- test_evfilt_write(kq, sv, "PF_UNIX, SOCK_STREAM");
-
- if (close(sv[0]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
- OK("close() 5");
- if (close(sv[1]) == -1)
- fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
- OK("close() 6");
-
- if (close(kq) == -1)
- fail(errno, "close", "kq", NULL);
- OK("close() 7");
-
- return (0);
-}
diff --git a/tests/sys/sockets/listen_backlog_test.c b/tests/sys/sockets/listen_backlog_test.c
deleted file mode 100644
index 2276393..0000000
--- a/tests/sys/sockets/listen_backlog_test.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/*
- * This regression test is intended to validate that the backlog parameter
- * set by listen() is properly set, can be retrieved using SO_LISTENQLIMIT,
- * and that it can be updated by later calls to listen(). We also check that
- * SO_LISTENQLIMIT cannot be set.
- *
- * Future things to test:
- *
- * - That if we change the value of kern.ipc.somaxconn, the limits really
- * do change.
- *
- * - That limits are, approximately, enforced and implemented.
- *
- * - All this on multiple socket types -- i.e., PF_LOCAL.
- *
- * - That we also test SO_LISTENQLEN and SO_LISTENINCQLEN.
- */
-
-/*
- * We retrieve kern.ipc.somaxconn before running the tests in order to use a
- * run-time set value of SOMAXCONN, rather than compile-time set. We assume
- * that no other process will be simultaneously frobbing it, and these tests
- * may fail if that assumption is not held.
- */
-static int somaxconn;
-
-/*
- * Retrieve the current socket listen queue limit using SO_LISTENQLIMIT.
- */
-static int
-socket_get_backlog(int sock, int *backlogp, const char *testclass,
- const char *test, const char *testfunc)
-{
- socklen_t len;
- int i;
-
- len = sizeof(i);
- if (getsockopt(sock, SOL_SOCKET, SO_LISTENQLIMIT, &i, &len) < 0) {
- warn("%s: %s: %s: socket_get_backlog: getsockopt("
- "SOL_SOCKET, SO_LISTENQLIMIT)", testclass, test,
- testfunc);
- return (-1);
- }
-
- if (len != sizeof(i)) {
- warnx("%s: %s: %s: socket_get_backlog: getsockopt("
- "SOL_SOCKET, SO_LISTENQLIMIT): returned size %d",
- testclass, test, testfunc, len);
- return (-1);
- }
-
- *backlogp = i;
-
- return (0);
-}
-
-/*
- * Create a socket, check the queue limit on creation, perform a listen(),
- * and make sure that the limit was set as expected by listen().
- */
-static int
-socket_listen(int domain, int type, int protocol, int backlog,
- int create_backlog_assertion, int listen_backlog_assertion, int *sockp,
- const char *domainstring, const char *typestring, const char *testclass,
- const char *test)
-{
- int backlog_retrieved, sock;
-
- sock = socket(domain, type, protocol);
- if (sock < 0) {
- warn("%s: %s: socket_listen: socket(%s, %s)", testclass,
- test, domainstring, typestring);
- close(sock);
- return (-1);
- }
-
- if (socket_get_backlog(sock, &backlog_retrieved, testclass, test,
- "socket_listen") < 0) {
- close(sock);
- return (-1);
- }
-
- if (backlog_retrieved != create_backlog_assertion) {
- warnx("%s: %s: socket_listen: create backlog is %d not %d",
- testclass, test, backlog_retrieved,
- create_backlog_assertion);
- close(sock);
- return (-1);
- }
-
- if (listen(sock, backlog) < 0) {
- warn("%s: %s: socket_listen: listen(, %d)", testclass, test,
- backlog);
- close(sock);
- return (-1);
- }
-
- if (socket_get_backlog(sock, &backlog_retrieved, testclass, test,
- "socket_listen") < 0) {
- close(sock);
- return (-1);
- }
-
- if (backlog_retrieved != listen_backlog_assertion) {
- warnx("%s: %s: socket_listen: listen backlog is %d not %d",
- testclass, test, backlog_retrieved,
- listen_backlog_assertion);
- close(sock);
- return (-1);
- }
-
- *sockp = sock;
- return (0);
-}
-
-/*
- * This test creates sockets and tests default states before and after
- * listen(). Specifically, we expect a queue limit of 0 before listen, and
- * then various settings for after listen(). If the passed backlog was
- * either < 0 or > somaxconn, it should be set to somaxconn; otherwise, the
- * passed queue depth.
- */
-static void
-test_defaults(void)
-{
- int sock;
-
- /*
- * First pass. Confirm the default is 0. Listen with a backlog of
- * 0 and confirm it gets set that way.
- */
- if (socket_listen(PF_INET, SOCK_STREAM, 0, 0, 0, 0, &sock, "PF_INET",
- "SOCK_STREAM", "test_defaults", "default_0_listen_0") < 0)
- exit(-1);
- close(sock);
-
- /*
- * Second pass. Listen with a backlog of -1 and make sure it is set
- * to somaxconn.
- */
- if (socket_listen(PF_INET, SOCK_STREAM, 0, -1, 0, somaxconn, &sock,
- "PF_INET", "SOCK_STREAM", "test_defaults", "default_0_listen_-1")
- < 0)
- exit(-1);
- close(sock);
-
- /*
- * Third pass. Listen with a backlog of 1 and make sure it is set to
- * 1.
- */
- if (socket_listen(PF_INET, SOCK_STREAM, 0, 1, 0, 1, &sock, "PF_INET",
- "SOCK_STREAM", "test_defaults", "default_0_listen_1") < 0)
- exit(-1);
- close(sock);
-
- /*
- * Fourth pass. Listen with a backlog of somaxconn and make sure it
- * is set to somaxconn.
- */
- if (socket_listen(PF_INET, SOCK_STREAM, 0, somaxconn, 0, somaxconn,
- &sock, "PF_INET", "SOCK_STREAM", "test_defaults",
- "default_0_listen_somaxconn") < 0)
- exit(-1);
- close(sock);
-
- /*
- * Fifth pass. Listen with a backlog of somaxconn+1 and make sure it
- * is set to somaxconn.
- */
- if (socket_listen(PF_INET, SOCK_STREAM, 0, somaxconn+1, 0, somaxconn,
- &sock, "PF_INET", "SOCK_STREAM", "test_defaults",
- "default_0_listen_somaxconn+1") < 0)
- exit(-1);
- close(sock);
-}
-
-/*
- * Create a socket, set the initial listen() state, then update the queue
- * depth using listen(). Check that the backlog is as expected after both
- * the first and second listen().
- */
-static int
-socket_listen_update(int domain __unused, int type __unused,
- int protocol __unused, int backlog,
- int update_backlog, int listen_backlog_assertion,
- int update_backlog_assertion, int *sockp, const char *domainstring,
- const char *typestring, const char *testclass, const char *test)
-{
- int backlog_retrieved, sock;
-
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- warn("%s: %s: socket_listen_update: socket(%s, %s)",
- testclass, test, domainstring, typestring);
- return (-1);
- }
-
- if (listen(sock, backlog) < 0) {
- warn("%s: %s: socket_listen_update: initial listen(, %d)",
- testclass, test, backlog);
- close(sock);
- return (-1);
- }
-
- if (socket_get_backlog(sock, &backlog_retrieved, testclass, test,
- "socket_listen_update") < 0) {
- close(sock);
- return (-1);
- }
-
- if (backlog_retrieved != listen_backlog_assertion) {
- warnx("%s: %s: socket_listen_update: initial backlog is %d "
- "not %d", testclass, test, backlog_retrieved,
- listen_backlog_assertion);
- close(sock);
- return (-1);
- }
-
- if (listen(sock, update_backlog) < 0) {
- warn("%s: %s: socket_listen_update: update listen(, %d)",
- testclass, test, update_backlog);
- close(sock);
- return (-1);
- }
-
- if (socket_get_backlog(sock, &backlog_retrieved, testclass, test,
- "socket_listen_update") < 0) {
- close(sock);
- return (-1);
- }
-
- if (backlog_retrieved != update_backlog_assertion) {
- warnx("%s: %s: socket_listen_update: updated backlog is %d "
- "not %d", testclass, test, backlog_retrieved,
- update_backlog_assertion);
- close(sock);
- return (-1);
- }
-
- *sockp = sock;
- return (0);
-}
-
-/*
- * This test tests using listen() to update the queue depth after a socket
- * has already been marked as listening. We test several cases: setting the
- * socket < 0, 0, 1, somaxconn, and somaxconn + 1.
- */
-static void
-test_listen_update(void)
-{
- int sock;
-
- /*
- * Set to 5, update to -1, which should give somaxconn.
- */
- if (socket_listen_update(PF_INET, SOCK_STREAM, 0, 5, -1, 5, somaxconn,
- &sock, "PF_INET", "SOCK_STREAM", "test_listen_update",
- "update_5,-1") < 0)
- exit(-1);
- close(sock);
-
- /*
- * Set to 5, update to 0, which should give 0.
- */
- if (socket_listen_update(PF_INET, SOCK_STREAM, 0, 5, 0, 5, 0, &sock,
- "PF_INET", "SOCK_STREAM", "test_listen_update", "update_5,0")
- < 0)
- exit(-1);
- close(sock);
-
- /*
- * Set to 5, update to 1, which should give 1.
- */
- if (socket_listen_update(PF_INET, SOCK_STREAM, 0, 5, 1, 5, 1, &sock,
- "PF_INET", "SOCK_STREAM", "test_listen_update", "update_5,1")
- < 0)
- exit(-1);
- close(sock);
-
- /*
- * Set to 5, update to somaxconn, which should give somaxconn.
- */
- if (socket_listen_update(PF_INET, SOCK_STREAM, 0, 5, somaxconn, 5,
- somaxconn, &sock, "PF_INET", "SOCK_STREAM", "test_listen_update",
- "update_5,somaxconn") < 0)
- exit(-1);
- close(sock);
-
- /*
- * Set to 5, update to somaxconn+1, which should give somaxconn.
- */
- if (socket_listen_update(PF_INET, SOCK_STREAM, 0, 5, somaxconn+1, 5,
- somaxconn, &sock, "PF_INET", "SOCK_STREAM", "test_listen_update",
- "update_5,somaxconn+1") < 0)
- exit(-1);
- close(sock);
-}
-
-/*
- * SO_LISTENQLIMIT is a read-only socket option, so make sure we get an error
- * if we try to write it.
- */
-static void
-test_set_qlimit(void)
-{
- int i, ret, sock;
-
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- err(-1, "test_set_qlimit: socket(PF_INET, SOCK_STREAM)");
-
- i = 0;
- ret = setsockopt(sock, SOL_SOCKET, SO_LISTENQLIMIT, &i, sizeof(i));
- if (ret < 0 && errno != ENOPROTOOPT) {
- warn("test_set_qlimit: setsockopt(SOL_SOCKET, "
- "SO_LISTENQLIMIT, 0): unexpected error");
- close(sock);
- }
-
- if (ret == 0) {
- warnx("test_set_qlimit: setsockopt(SOL_SOCKET, "
- "SO_LISTENQLIMIT, 0) succeeded");
- close(sock);
- exit(-1);
- }
- close(sock);
-}
-
-int
-main(void)
-{
- size_t len;
-
- len = sizeof(somaxconn);
- if (sysctlbyname("kern.ipc.somaxconn", &somaxconn, &len, NULL, 0)
- < 0)
- err(-1, "sysctlbyname(kern.ipc.somaxconn)");
-
- test_defaults();
- test_listen_update();
- test_set_qlimit();
-
- return (0);
-}
diff --git a/tests/sys/sockets/listenclose_test.c b/tests/sys/sockets/listenclose_test.c
deleted file mode 100644
index f920846..0000000
--- a/tests/sys/sockets/listenclose_test.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * The listenclose regression test is designed to catch kernel bugs that may
- * trigger as a result of performing a close on a listen() socket with as-yet
- * unaccepted connections in its queues. This results in the connections
- * being aborted, which is a not-often-followed code path. To do this, we
- * create a local TCP socket, build a non-blocking connection to it, and then
- * close the accept socket. The connection must be non-blocking or the
- * program will block and as such connect() will not return as accept() is
- * never called.
- */
-
-int
-main(void)
-{
- int listen_sock, connect_sock;
- struct sockaddr_in sin;
- socklen_t len;
- u_short port;
- int arg;
-
- listen_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (listen_sock == -1)
- errx(-1,
- "socket(PF_INET, SOCK_STREAM, 0) for listen socket: %s",
- strerror(errno));
-
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = 0;
-
- if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- errx(-1, "bind(%s, %d) for listen socket: %s",
- inet_ntoa(sin.sin_addr), 0, strerror(errno));
-
- len = sizeof(sin);
- if (getsockname(listen_sock, (struct sockaddr *)&sin, &len) < 0)
- errx(-1, "getsockname() for listen socket: %s",
- strerror(errno));
- port = sin.sin_port;
-
- if (listen(listen_sock, -1) < 0)
- errx(-1, "listen() for listen socket: %s", strerror(errno));
-
- connect_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (connect_sock == -1)
- errx(-1, "socket(PF_INET, SOCK_STREAM, 0) for connect "
- "socket: %s", strerror(errno));
-
- arg = O_NONBLOCK;
- if (fcntl(connect_sock, F_SETFL, &arg) < 0)
- errx(-1, "socket(PF_INET, SOCK_STREAM, 0) for connect socket"
- ": %s", strerror(errno));
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = port;
-
- if (connect(connect_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- errx(-1, "connect() for connect socket: %s", strerror(errno));
- close(connect_sock);
- close(listen_sock);
-
- return (0);
-}
diff --git a/tests/sys/sockets/pr_atomic_test.c b/tests/sys/sockets/pr_atomic_test.c
deleted file mode 100644
index e902cf7..0000000
--- a/tests/sys/sockets/pr_atomic_test.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 2006 Bruce M. Simpson
- * 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$
- */
-
-/*
- * Regression test for uiomove in kernel; specifically for PR kern/38495.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <stdlib.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <string.h>
-#include <err.h>
-#include <errno.h>
-#include <unistd.h>
-
-static char socket_path[] = "tmp.XXXXXX";
-
-static jmp_buf myjmpbuf;
-
-static void handle_sigalrm(int signo __unused)
-{
- longjmp(myjmpbuf, 1);
-}
-
-int
-main(void)
-{
- struct sockaddr_un un;
- pid_t pid;
- int s;
-
- if (mkstemp(socket_path) == -1)
- err(1, "mkstemp");
- s = socket(PF_LOCAL, SOCK_DGRAM, 0);
- if (s == -1)
- errx(-1, "socket");
- memset(&un, 0, sizeof(un));
- un.sun_family = AF_LOCAL;
- unlink(socket_path);
- strcpy(un.sun_path, socket_path);
- if (bind(s, (struct sockaddr *)&un, sizeof(un)) == -1)
- errx(-1, "bind");
- pid = fork();
- if (pid == -1)
- errx(-1, "fork");
- if (pid == 0) {
- int conn;
- char buf[] = "AAAAAAAAA";
-
- close(s);
- conn = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (conn == -1)
- errx(-1,"socket");
- if (sendto(conn, buf, sizeof(buf), 0, (struct sockaddr *)&un,
- sizeof(un)) != sizeof(buf))
- errx(-1,"sendto");
- close(conn);
- _exit(0);
- }
-
- sleep(5);
-
- /* Make sure the data is there when we try to receive it. */
- if (recvfrom(s, (void *)-1, 1, 0, NULL, NULL) != -1)
- errx(-1,"recvfrom succeeded when failure expected");
-
- (void)signal(SIGALRM, handle_sigalrm);
- if (setjmp(myjmpbuf) == 0) {
- /*
- * This recvfrom will panic an unpatched system, and block
- * a patched one.
- */
- alarm(5);
- (void)recvfrom(s, (void *)-1, 1, 0, NULL, NULL);
- }
-
- /* We should reach here via longjmp() and all should be well. */
-
- return (0);
-}
diff --git a/tests/sys/sockets/reconnect_test.c b/tests/sys/sockets/reconnect_test.c
deleted file mode 100644
index 27f32cc..0000000
--- a/tests/sys/sockets/reconnect_test.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*-
- * Copyright (c) 2005 Maxim Sobolev
- * 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$
- */
-
-/*
- * The reconnect regression test is designed to catch kernel bug that may
- * prevent changing association of already associated datagram unix domain
- * socket when server side of connection has been closed.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-
-static char uds_name1[] = "reconnect.XXXXXXXX";
-static char uds_name2[] = "reconnect.XXXXXXXX";
-
-#define sstosa(ss) ((struct sockaddr *)(ss))
-
-static void
-prepare_ifsun(struct sockaddr_un *ifsun, const char *path)
-{
-
- memset(ifsun, '\0', sizeof(*ifsun));
-#if !defined(__linux__) && !defined(__solaris__)
- ifsun->sun_len = strlen(path);
-#endif
- ifsun->sun_family = AF_LOCAL;
- strcpy(ifsun->sun_path, path);
-}
-
-static int
-create_uds_server(const char *path)
-{
- struct sockaddr_un ifsun;
- int sock;
-
- prepare_ifsun(&ifsun, path);
-
- unlink(ifsun.sun_path);
-
- sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
- if (sock == -1)
- err(1, "can't create socket");
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sock, sizeof(sock));
- if (bind(sock, sstosa(&ifsun), sizeof(ifsun)) < 0)
- err(1, "can't bind to a socket");
-
- return sock;
-}
-
-static void
-connect_uds_server(int sock, const char *path)
-{
- struct sockaddr_un ifsun;
- int e;
-
- prepare_ifsun(&ifsun, path);
-
- e = connect(sock, sstosa(&ifsun), sizeof(ifsun));
- if (e < 0)
- err(1, "can't connect to a socket");
-}
-
-static void
-cleanup(void)
-{
-
- unlink(uds_name1);
- unlink(uds_name2);
-}
-
-int
-main()
-{
- int s_sock1, s_sock2, c_sock;
-
- atexit(cleanup);
-
- if (mkstemp(uds_name1) == -1)
- err(1, "mkstemp");
- unlink(uds_name1);
- s_sock1 = create_uds_server(uds_name1);
-
- if (mkstemp(uds_name2) == -1)
- err(1, "mkstemp");
- unlink(uds_name2);
- s_sock2 = create_uds_server(uds_name2);
-
- c_sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
- if (c_sock < 0)
- err(1, "can't create socket");
-
- connect_uds_server(c_sock, uds_name1);
- close(s_sock1);
- connect_uds_server(c_sock, uds_name2);
-
- exit (0);
-}
diff --git a/tests/sys/sockets/rtsocket_test.c b/tests/sys/sockets/rtsocket_test.c
deleted file mode 100644
index b5824b3..0000000
--- a/tests/sys/sockets/rtsocket_test.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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$
- */
-
-/*
- * Simple routing socket regression test: create and destroy a raw routing
- * socket, and make sure that dgram and stream don't work, socketpair, etc.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <net/route.h>
-
-#include <err.h>
-#include <errno.h>
-#include <unistd.h>
-
-int
-main(void)
-{
- int sock, socks[2];
-
- sock = socket(PF_ROUTE, SOCK_STREAM, 0);
- if (sock >= 0) {
- close(sock);
- errx(-1, "socket(PF_ROUTE, SOCK_STREAM, 0) returned %d",
- sock);
- }
-
- if (errno != EPROTONOSUPPORT)
- err(-1, "socket(PF_ROUTE, SOCK_STREAM, 0)");
-
- sock = socket(PF_ROUTE, SOCK_DGRAM, 0);
- if (sock >= 0) {
- close(sock);
- errx(-1, "socket(PF_ROUTE, SOCK_DGRAM, 0) returned %d",
- sock);
- }
-
- if (errno != EPROTONOSUPPORT)
- err(-1, "socket(PF_ROUTE, SOCK_DGRAM, 0)");
-
- sock = socket(PF_ROUTE, SOCK_RAW, 0);
- if (sock < 0)
- err(-1, "socket(PF_ROUTE, SOCK_RAW, 0)");
- close(sock);
-
- if (socketpair(PF_ROUTE, SOCK_STREAM, 0, socks) == 0) {
- close(socks[0]);
- close(socks[1]);
- errx(-1,
- "socketpair(PF_ROUTE, SOCK_STREAM, 0, socks) success");
- }
-
- if (errno != EPROTONOSUPPORT)
- err(-1, "socketpair(PF_ROUTE, SOCK_STREAM, 0, socks)");
-
- if (socketpair(PF_ROUTE, SOCK_DGRAM, 0, socks) == 0) {
- close(socks[0]);
- close(socks[1]);
- errx(-1,
- "socketpair(PF_ROUTE, SOCK_DGRAM, 0, socks) success");
- }
-
- if (errno != EPROTONOSUPPORT)
- err(-1, "socketpair(PF_ROUTE, SOCK_DGRAM, 0, socks)");
-
- if (socketpair(PF_ROUTE, SOCK_RAW, 0, socks) == 0) {
- close(socks[0]);
- close(socks[1]);
- errx(-1,
- "socketpair(PF_ROUTE, SOCK_STREAM, 0, socks) success");
- }
-
- return (0);
-}
diff --git a/tests/sys/sockets/sblock_test.c b/tests/sys/sockets/sblock_test.c
deleted file mode 100644
index 415c4d4..0000000
--- a/tests/sys/sockets/sblock_test.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*-
- * Copyright (c) 2007 Robert N. M. Watson
- * 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$
- */
-
-/*
- * Sockets serialize I/O in each direction in order to avoid interlacing of
- * I/O by multiple processes or threcvs recving or sending the socket. This
- * is done using some form of kernel lock (varies by kernel version), called
- * "sblock" in FreeBSD. However, to avoid unkillable processes waiting on
- * I/O that may be entirely controlled by a remote network endpoint, that
- * lock acquisition must be interruptible.
- *
- * To test this, set up a local domain stream socket pair and a set of three
- * processes. Two processes block in recv(), the first on sbwait (wait for
- * I/O), and the second on the sblock waiting for the first to finish. A
- * third process is responsible for signalling the second process, then
- * writing to the socket. Depending on the error returned in the second
- * process, we can tell whether the sblock wait was interrupted, or if
- * instead the process only woke up when the write was performed.
- */
-
-#include <sys/socket.h>
-
-#include <err.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static int interrupted;
-static void
-signal_handler(int signum __unused)
-{
-
- interrupted++;
-}
-
-/*
- * Process that will perform a blocking recv on a UNIX domain socket. This
- * should return one byte of data.
- */
-static void
-blocking_recver(int fd)
-{
- ssize_t len;
- char ch;
-
- len = recv(fd, &ch, sizeof(ch), 0);
- if (len < 0)
- err(-1, "FAIL: blocking_recver: recv");
- if (len == 0)
- errx(-1, "FAIL: blocking_recver: recv: eof");
- if (len != 1)
- errx(-1, "FAIL: blocking_recver: recv: %zd bytes", len);
- if (interrupted)
- errx(-1, "FAIL: blocking_recver: interrupted wrong pid");
-}
-
-/*
- * Process that will perform a locking recv on a UNIX domain socket.
- *
- * This is where we figure out if the test worked or not. If it has failed,
- * then recv() will return EOF, as the close() arrives before the signal,
- * meaning that the wait for the sblock was not interrupted; if it has
- * succeeded, we get EINTR as the signal interrupts the lock request.
- */
-static void
-locking_recver(int fd)
-{
- ssize_t len;
- char ch;
-
- if (sleep(1) != 0)
- err(-1, "FAIL: locking_recver: sleep");
- len = recv(fd, &ch, sizeof(ch), 0);
- if (len < 0 && errno != EINTR)
- err(-1, "FAIL: locking_recver: recv");
- if (len < 0 && errno == EINTR) {
- fprintf(stderr, "PASS\n");
- exit(0);
- }
- if (len == 0)
- errx(-1, "FAIL: locking_recver: recv: eof");
- if (!interrupted)
- errx(-1, "FAIL: locking_recver: not interrupted");
-}
-
-static void
-signaller(pid_t locking_recver_pid, int fd)
-{
- ssize_t len;
- char ch;
-
- if (sleep(2) != 0) {
- warn("signaller sleep(2)");
- return;
- }
- if (kill(locking_recver_pid, SIGHUP) < 0) {
- warn("signaller kill(%d)", locking_recver_pid);
- return;
- }
- if (sleep(1) != 0) {
- warn("signaller sleep(1)");
- return;
- }
- len = send(fd, &ch, sizeof(ch), 0);
- if (len < 0) {
- warn("signaller send");
- return;
- }
- if (len != sizeof(ch)) {
- warnx("signaller send ret %zd", len);
- return;
- }
- if (close(fd) < 0) {
- warn("signaller close");
- return;
- }
- if (sleep(1) != 0) {
- warn("signaller sleep(1)");
- return;
- }
-}
-
-int
-main(void)
-{
- int error, fds[2], recver_fd, sender_fd;
- pid_t blocking_recver_pid;
- pid_t locking_recver_pid;
- struct sigaction sa;
-
- if (sigaction(SIGHUP, NULL, &sa) < 0)
- err(-1, "FAIL: sigaction(SIGHUP, NULL, &sa)");
-
- sa.sa_handler = signal_handler;
- if (sa.sa_flags & SA_RESTART)
- printf("SIGHUP restartable by default (cleared)\n");
- sa.sa_flags &= ~SA_RESTART;
-
- if (sigaction(SIGHUP, &sa, NULL) < 0)
- err(-1, "FAIL: sigaction(SIGHUP, &sa, NULL)");
-
-#if 0
- if (signal(SIGHUP, signal_handler) == SIG_ERR)
- err(-1, "FAIL: signal(SIGHUP)");
-#endif
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0)
- err(-1, "FAIL: socketpair(PF_LOCAL, SOGK_STREAM, 0)");
-
- sender_fd = fds[0];
- recver_fd = fds[1];
-
- blocking_recver_pid = fork();
- if (blocking_recver_pid < 0)
- err(-1, "FAIL: fork");
- if (blocking_recver_pid == 0) {
- close(sender_fd);
- blocking_recver(recver_fd);
- exit(0);
- }
-
- locking_recver_pid = fork();
- if (locking_recver_pid < 0) {
- error = errno;
- kill(blocking_recver_pid, SIGKILL);
- errno = error;
- err(-1, "FAIL: fork");
- }
- if (locking_recver_pid == 0) {
- close(sender_fd);
- locking_recver(recver_fd);
- exit(0);
- }
-
- signaller(locking_recver_pid, sender_fd);
-
- kill(blocking_recver_pid, SIGKILL);
- kill(locking_recver_pid, SIGKILL);
- exit(0);
-}
diff --git a/tests/sys/sockets/sendfile_test.c b/tests/sys/sockets/sendfile_test.c
deleted file mode 100644
index 18ae9ad..0000000
--- a/tests/sys/sockets/sendfile_test.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <netinet/in.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <md5.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Simple regression test for sendfile. Creates a file sized at four pages
- * and then proceeds to send it over a series of sockets, exercising a number
- * of cases and performing limited validation.
- */
-
-#define FAIL(msg) {printf("# %s\n", msg); \
- return (-1);}
-
-#define FAIL_ERR(msg) {printf("# %s: %s\n", msg, strerror(errno)); \
- return (-1);}
-
-#define TEST_PORT 5678
-#define TEST_MAGIC 0x4440f7bb
-#define TEST_PAGES 4
-#define TEST_SECONDS 30
-
-struct test_header {
- uint32_t th_magic;
- uint32_t th_header_length;
- uint32_t th_offset;
- uint32_t th_length;
- char th_md5[33];
-};
-
-struct sendfile_test {
- uint32_t hdr_length;
- uint32_t offset;
- uint32_t length;
- uint32_t file_size;
-};
-
-static int file_fd;
-static char path[PATH_MAX];
-static int listen_socket;
-static int accept_socket;
-
-static int test_th(struct test_header *th, uint32_t *header_length,
- uint32_t *offset, uint32_t *length);
-static void signal_alarm(int signum);
-static void setup_alarm(int seconds);
-static void cancel_alarm(void);
-static int receive_test(void);
-static void run_child(void);
-static int new_test_socket(int *connect_socket);
-static void init_th(struct test_header *th, uint32_t header_length,
- uint32_t offset, uint32_t length);
-static int send_test(int connect_socket, struct sendfile_test);
-static int write_test_file(size_t file_size);
-static void run_parent(void);
-static void cleanup(void);
-
-
-static int
-test_th(struct test_header *th, uint32_t *header_length, uint32_t *offset,
- uint32_t *length)
-{
-
- if (th->th_magic != htonl(TEST_MAGIC))
- FAIL("magic number not found in header")
- *header_length = ntohl(th->th_header_length);
- *offset = ntohl(th->th_offset);
- *length = ntohl(th->th_length);
- return (0);
-}
-
-static void
-signal_alarm(int signum)
-{
- (void)signum;
-
- printf("# test timeout\n");
-
- if (accept_socket > 0)
- close(accept_socket);
- if (listen_socket > 0)
- close(listen_socket);
-
- _exit(-1);
-}
-
-static void
-setup_alarm(int seconds)
-{
- struct itimerval itv;
- bzero(&itv, sizeof(itv));
- (void)seconds;
- itv.it_value.tv_sec = seconds;
-
- signal(SIGALRM, signal_alarm);
- setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-static void
-cancel_alarm(void)
-{
- struct itimerval itv;
- bzero(&itv, sizeof(itv));
- setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-static int
-receive_test(void)
-{
- uint32_t header_length, offset, length, counter;
- struct test_header th;
- ssize_t len;
- char buf[10240];
- MD5_CTX md5ctx;
- char *rxmd5;
-
- len = read(accept_socket, &th, sizeof(th));
- if (len < 0 || (size_t)len < sizeof(th))
- FAIL_ERR("read")
-
- if (test_th(&th, &header_length, &offset, &length) != 0)
- return (-1);
-
- MD5Init(&md5ctx);
-
- counter = 0;
- while (1) {
- len = read(accept_socket, buf, sizeof(buf));
- if (len < 0 || len == 0)
- break;
- counter += len;
- MD5Update(&md5ctx, buf, len);
- }
-
- rxmd5 = MD5End(&md5ctx, NULL);
-
- if ((counter != header_length+length) ||
- memcmp(th.th_md5, rxmd5, 33) != 0)
- FAIL("receive length mismatch")
-
- free(rxmd5);
- return (0);
-}
-
-static void
-run_child(void)
-{
- struct sockaddr_in sin;
- int rc = 0;
-
- listen_socket = socket(PF_INET, SOCK_STREAM, 0);
- if (listen_socket < 0) {
- printf("# socket: %s\n", strerror(errno));
- rc = -1;
- }
-
- if (!rc) {
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(TEST_PORT);
-
- if (bind(listen_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- printf("# bind: %s\n", strerror(errno));
- rc = -1;
- }
- }
-
- if (!rc && listen(listen_socket, -1) < 0) {
- printf("# listen: %s\n", strerror(errno));
- rc = -1;
- }
-
- if (!rc) {
- accept_socket = accept(listen_socket, NULL, NULL);
- setup_alarm(TEST_SECONDS);
- if (receive_test() != 0)
- rc = -1;
- }
-
- cancel_alarm();
- if (accept_socket > 0)
- close(accept_socket);
- if (listen_socket > 0)
- close(listen_socket);
-
- _exit(rc);
-}
-
-static int
-new_test_socket(int *connect_socket)
-{
- struct sockaddr_in sin;
- int rc = 0;
-
- *connect_socket = socket(PF_INET, SOCK_STREAM, 0);
- if (*connect_socket < 0)
- FAIL_ERR("socket")
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(TEST_PORT);
-
- if (connect(*connect_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- FAIL_ERR("connect")
-
- return (rc);
-}
-
-static void
-init_th(struct test_header *th, uint32_t header_length, uint32_t offset,
- uint32_t length)
-{
- bzero(th, sizeof(*th));
- th->th_magic = htonl(TEST_MAGIC);
- th->th_header_length = htonl(header_length);
- th->th_offset = htonl(offset);
- th->th_length = htonl(length);
-
- MD5FileChunk(path, th->th_md5, offset, length);
-}
-
-static int
-send_test(int connect_socket, struct sendfile_test test)
-{
- struct test_header th;
- struct sf_hdtr hdtr, *hdtrp;
- struct iovec headers;
- char *header;
- ssize_t len;
- int length;
- off_t off;
-
- len = lseek(file_fd, 0, SEEK_SET);
- if (len != 0)
- FAIL_ERR("lseek")
-
- struct stat st;
- if (fstat(file_fd, &st) < 0)
- FAIL_ERR("fstat")
- length = st.st_size - test.offset;
- if (test.length > 0 && test.length < (uint32_t)length)
- length = test.length;
-
- init_th(&th, test.hdr_length, test.offset, length);
-
- len = write(connect_socket, &th, sizeof(th));
- if (len != sizeof(th))
- return (-1);
-
- if (test.hdr_length != 0) {
- header = malloc(test.hdr_length);
- if (header == NULL)
- FAIL_ERR("malloc")
-
- hdtrp = &hdtr;
- bzero(&headers, sizeof(headers));
- headers.iov_base = header;
- headers.iov_len = test.hdr_length;
- bzero(&hdtr, sizeof(hdtr));
- hdtr.headers = &headers;
- hdtr.hdr_cnt = 1;
- hdtr.trailers = NULL;
- hdtr.trl_cnt = 0;
- } else {
- hdtrp = NULL;
- header = NULL;
- }
-
- if (sendfile(file_fd, connect_socket, test.offset, test.length,
- hdtrp, &off, 0) < 0) {
- if (header != NULL)
- free(header);
- FAIL_ERR("sendfile")
- }
-
- if (length == 0) {
- struct stat sb;
-
- if (fstat(file_fd, &sb) == 0)
- length = sb.st_size - test.offset;
- }
-
- if (header != NULL)
- free(header);
-
- if (off != length)
- FAIL("offset != length")
-
- return (0);
-}
-
-static int
-write_test_file(size_t file_size)
-{
- char *page_buffer;
- ssize_t len;
- static size_t current_file_size = 0;
-
- if (file_size == current_file_size)
- return (0);
- else if (file_size < current_file_size) {
- if (ftruncate(file_fd, file_size) != 0)
- FAIL_ERR("ftruncate");
- current_file_size = file_size;
- return (0);
- }
-
- page_buffer = malloc(file_size);
- if (page_buffer == NULL)
- FAIL_ERR("malloc")
- bzero(page_buffer, file_size);
-
- len = write(file_fd, page_buffer, file_size);
- if (len < 0)
- FAIL_ERR("write")
-
- len = lseek(file_fd, 0, SEEK_SET);
- if (len < 0)
- FAIL_ERR("lseek")
- if (len != 0)
- FAIL("len != 0")
-
- free(page_buffer);
- current_file_size = file_size;
- return (0);
-}
-
-static void
-run_parent(void)
-{
- int connect_socket;
- int status;
- int test_num;
- int test_count;
- int pid;
- size_t desired_file_size = 0;
-
- const int pagesize = getpagesize();
-
- struct sendfile_test tests[] = {
- { .hdr_length = 0, .offset = 0, .length = 1 },
- { .hdr_length = 0, .offset = 0, .length = pagesize },
- { .hdr_length = 0, .offset = 1, .length = 1 },
- { .hdr_length = 0, .offset = 1, .length = pagesize },
- { .hdr_length = 0, .offset = pagesize, .length = pagesize },
- { .hdr_length = 0, .offset = 0, .length = 2*pagesize },
- { .hdr_length = 0, .offset = 0, .length = 0 },
- { .hdr_length = 0, .offset = pagesize, .length = 0 },
- { .hdr_length = 0, .offset = 2*pagesize, .length = 0 },
- { .hdr_length = 0, .offset = TEST_PAGES*pagesize, .length = 0 },
- { .hdr_length = 0, .offset = 0, .length = pagesize,
- .file_size = 1 }
- };
-
- test_count = sizeof(tests) / sizeof(tests[0]);
- printf("1..%d\n", test_count);
-
- for (test_num = 1; test_num <= test_count; test_num++) {
-
- desired_file_size = tests[test_num - 1].file_size;
- if (desired_file_size == 0)
- desired_file_size = TEST_PAGES * pagesize;
- if (write_test_file(desired_file_size) != 0) {
- printf("not ok %d\n", test_num);
- continue;
- }
-
- pid = fork();
- if (pid == -1) {
- printf("not ok %d\n", test_num);
- continue;
- }
-
- if (pid == 0)
- run_child();
-
- usleep(250000);
-
- if (new_test_socket(&connect_socket) != 0) {
- printf("not ok %d\n", test_num);
- kill(pid, SIGALRM);
- close(connect_socket);
- continue;
- }
-
- if (send_test(connect_socket, tests[test_num-1]) != 0) {
- printf("not ok %d\n", test_num);
- kill(pid, SIGALRM);
- close(connect_socket);
- continue;
- }
-
- close(connect_socket);
- if (waitpid(pid, &status, 0) == pid) {
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
- printf("%s %d\n", "ok", test_num);
- else
- printf("%s %d\n", "not ok", test_num);
- }
- else {
- printf("not ok %d\n", test_num);
- }
- }
-}
-
-static void
-cleanup(void)
-{
-
- unlink(path);
-}
-
-int
-main(int argc, char *argv[])
-{
- int pagesize;
-
- path[0] = '\0';
-
- pagesize = getpagesize();
-
- if (argc == 1) {
- snprintf(path, sizeof(path), "sendfile.XXXXXXXXXXXX");
- file_fd = mkstemp(path);
- if (file_fd == -1)
- FAIL_ERR("mkstemp");
- } else if (argc == 2) {
- (void)strlcpy(path, argv[1], sizeof(path));
- file_fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0600);
- if (file_fd == -1)
- FAIL_ERR("open");
- } else {
- FAIL("usage: sendfile [path]");
- }
-
- atexit(cleanup);
-
- run_parent();
- return (0);
-}
diff --git a/tests/sys/sockets/shutdown_test.c b/tests/sys/sockets/shutdown_test.c
deleted file mode 100644
index 3d23c94..0000000
--- a/tests/sys/sockets/shutdown_test.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * Copyright (C) 2005 The FreeBSD Project. 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/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-int
-main(void)
-{
- struct sockaddr_in sock;
- socklen_t len;
- int listen_sock, connect_sock;
- u_short port;
-
- listen_sock = -1;
-
- /* Shutdown(2) on an invalid file descriptor has to return EBADF. */
- if ((shutdown(listen_sock, SHUT_RDWR) != -1) && (errno != EBADF))
- errx(-1, "shutdown() for invalid file descriptor does not "
- "return EBADF");
-
- listen_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (listen_sock == -1)
- errx(-1,
- "socket(PF_INET, SOCK_STREAM, 0) for listen socket: %s",
- strerror(errno));
-
- bzero(&sock, sizeof(sock));
- sock.sin_len = sizeof(sock);
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sock.sin_port = 0;
-
- if (bind(listen_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0)
- errx(-1, "bind(%s, %d) for listen socket: %s",
- inet_ntoa(sock.sin_addr), sock.sin_port, strerror(errno));
-
- len = sizeof(sock);
- if (getsockname(listen_sock, (struct sockaddr *)&sock, &len) < 0)
- errx(-1, "getsockname() for listen socket: %s",
- strerror(errno));
- port = sock.sin_port;
-
- if (listen(listen_sock, -1) < 0)
- errx(-1, "listen() for listen socket: %s", strerror(errno));
-
- connect_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (connect_sock == -1)
- errx(-1, "socket(PF_INET, SOCK_STREAM, 0) for connect "
- "socket: %s", strerror(errno));
-
- bzero(&sock, sizeof(sock));
- sock.sin_len = sizeof(sock);
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sock.sin_port = port;
-
- if (connect(connect_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0)
- errx(-1, "connect() for connect socket: %s", strerror(errno));
- /* Try to pass an invalid flags. */
- if ((shutdown(connect_sock, SHUT_RD - 1) != -1) && (errno != EINVAL))
- errx(-1, "shutdown(SHUT_RD - 1) does not return EINVAL");
- if ((shutdown(connect_sock, SHUT_RDWR + 1) != -1) && (errno != EINVAL))
- errx(-1, "shutdown(SHUT_RDWR + 1) does not return EINVAL");
-
- if (shutdown(connect_sock, SHUT_RD) < 0)
- errx(-1, "shutdown(SHUT_RD) for connect socket: %s",
- strerror(errno));
- if (shutdown(connect_sock, SHUT_WR) < 0)
- errx(-1, "shutdown(SHUT_WR) for connect socket: %s",
- strerror(errno));
-
- close(connect_sock);
- close(listen_sock);
-
- return (0);
-}
diff --git a/tests/sys/sockets/sigpipe_test.c b/tests/sys/sockets/sigpipe_test.c
deleted file mode 100644
index 894d9de..0000000
--- a/tests/sys/sockets/sigpipe_test.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-
-#include <err.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * This regression test is intended to verify whether or not SIGPIPE is
- * properly generated in several simple test cases, as well as testing
- * whether SO_NOSIGPIPE disables SIGPIPE, if available on the system.
- * SIGPIPE is generated if a write or send is attempted on a socket that has
- * been shutdown for write. This test runs several test cases with UNIX
- * domain sockets and TCP sockets to confirm that either EPIPE or SIGPIPE is
- * properly returned.
- *
- * For the purposes of testing TCP, an unused port number must be specified.
- */
-static void
-usage(void)
-{
-
- errx(-1, "usage: sigpipe tcpport");
-}
-
-/*
- * Signal catcher. Set a global flag that can be tested by the caller.
- */
-static int signaled;
-static int
-got_signal(void)
-{
-
- return (signaled);
-}
-
-static void
-signal_handler(int signum __unused)
-{
-
- signaled = 1;
-}
-
-static void
-signal_setup(const char *testname)
-{
-
- signaled = 0;
- if (signal(SIGPIPE, signal_handler) == SIG_ERR)
- err(-1, "%s: signal(SIGPIPE)", testname);
-}
-
-static void
-test_send(const char *testname, int sock)
-{
- ssize_t len;
- char ch;
-
- ch = 0;
- len = send(sock, &ch, sizeof(ch), 0);
- if (len < 0) {
- if (errno == EPIPE)
- return;
- err(-1, "%s: send", testname);
- }
- errx(-1, "%s: send: returned %zd", testname, len);
-}
-
-static void
-test_write(const char *testname, int sock)
-{
- ssize_t len;
- char ch;
-
- ch = 0;
- len = write(sock, &ch, sizeof(ch));
- if (len < 0) {
- if (errno == EPIPE)
- return;
- err(-1, "%s: write", testname);
- }
- errx(-1, "%s: write: returned %zd", testname, len);
-}
-
-static void
-test_send_wantsignal(const char *testname, int sock1, int sock2)
-{
-
- if (shutdown(sock2, SHUT_WR) < 0)
- err(-1, "%s: shutdown", testname);
- signal_setup(testname);
- test_send(testname, sock2);
- if (!got_signal())
- errx(-1, "%s: send: didn't receive SIGPIPE", testname);
- close(sock1);
- close(sock2);
-}
-
-#ifdef SO_NOSIGPIPE
-static void
-test_send_dontsignal(const char *testname, int sock1, int sock2)
-{
- int i;
-
- i = 1;
- if (setsockopt(sock2, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0)
- err(-1, "%s: setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", testname);
- if (shutdown(sock2, SHUT_WR) < 0)
- err(-1, "%s: shutdown", testname);
- signal_setup(testname);
- test_send(testname, sock2);
- if (got_signal())
- errx(-1, "%s: send: got SIGPIPE", testname);
- close(sock1);
- close(sock2);
-}
-#endif
-
-static void
-test_write_wantsignal(const char *testname, int sock1, int sock2)
-{
-
- if (shutdown(sock2, SHUT_WR) < 0)
- err(-1, "%s: shutdown", testname);
- signal_setup(testname);
- test_write(testname, sock2);
- if (!got_signal())
- errx(-1, "%s: write: didn't receive SIGPIPE", testname);
- close(sock1);
- close(sock2);
-}
-
-#ifdef SO_NOSIGPIPE
-static void
-test_write_dontsignal(const char *testname, int sock1, int sock2)
-{
- int i;
-
- i = 1;
- if (setsockopt(sock2, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0)
- err(-1, "%s: setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", testname);
- if (shutdown(sock2, SHUT_WR) < 0)
- err(-1, "%s: shutdown", testname);
- signal_setup(testname);
- test_write(testname, sock2);
- if (got_signal())
- errx(-1, "%s: write: got SIGPIPE", testname);
- close(sock1);
- close(sock2);
-}
-#endif
-
-static int listen_sock;
-static void
-tcp_setup(u_short port)
-{
- struct sockaddr_in sin;
-
- listen_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (listen_sock < 0)
- err(-1, "tcp_setup: listen");
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(port);
-
- if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "tcp_setup: bind");
-
- if (listen(listen_sock, -1) < 0)
- err(-1, "tcp_setup: listen");
-}
-
-static void
-tcp_teardown(void)
-{
-
- close(listen_sock);
-}
-
-static void
-tcp_pair(u_short port, int sock[2])
-{
- int accept_sock, connect_sock;
- struct sockaddr_in sin;
- socklen_t len;
-
- connect_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (connect_sock < 0)
- err(-1, "tcp_pair: socket");
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(port);
-
- if (connect(connect_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "tcp_pair: connect");
-
- sleep(1); /* Time for TCP to settle. */
-
- len = sizeof(sin);
- accept_sock = accept(listen_sock, (struct sockaddr *)&sin, &len);
- if (accept_sock < 0)
- err(-1, "tcp_pair: accept");
-
- sleep(1); /* Time for TCP to settle. */
-
- sock[0] = accept_sock;
- sock[1] = connect_sock;
-}
-
-int
-main(int argc, char *argv[])
-{
- char *dummy;
- int sock[2];
- long port;
-
- if (argc != 2)
- usage();
-
- port = strtol(argv[1], &dummy, 10);
- if (port < 0 || port > 65535 || *dummy != '\0')
- usage();
-
-#ifndef SO_NOSIGPIPE
- warnx("sigpipe: SO_NOSIGPIPE not defined, skipping some tests");
-#endif
-
- /*
- * UNIX domain socketpair().
- */
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
- test_send_wantsignal("test_send_wantsignal(PF_LOCAL)", sock[0],
- sock[1]);
-
-#ifdef SO_NOSIGPIPE
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
- test_send_dontsignal("test_send_dontsignal(PF_LOCAL)", sock[0],
- sock[1]);
-#endif
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
- test_write_wantsignal("test_write_wantsignal(PF_LOCAL)", sock[0],
- sock[1]);
-
-#ifdef SO_NOSIGPIPE
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
- test_write_dontsignal("test_write_dontsignal(PF_LOCAL)", sock[0],
- sock[1]);
-#endif
-
- /*
- * TCP.
- */
- tcp_setup(port);
- tcp_pair(port, sock);
- test_send_wantsignal("test_send_wantsignal(PF_INET)", sock[0],
- sock[1]);
-
-#ifdef SO_NOSIGPIPE
- tcp_pair(port, sock);
- test_send_dontsignal("test_send_dontsignal(PF_INET)", sock[0],
- sock[1]);
-#endif
-
- tcp_pair(port, sock);
- test_write_wantsignal("test_write_wantsignal(PF_INET)", sock[0],
- sock[1]);
-
-#ifdef SO_NOSIGPIPE
- tcp_pair(port, sock);
- test_write_dontsignal("test_write_dontsignal(PF_INET)", sock[0],
- sock[1]);
-#endif
- tcp_teardown();
-
- fprintf(stderr, "PASS\n");
- return (0);
-}
diff --git a/tests/sys/sockets/so_setfib_test.c b/tests/sys/sockets/so_setfib_test.c
deleted file mode 100644
index 50cb020..0000000
--- a/tests/sys/sockets/so_setfib_test.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*-
- * Copyright (c) 2012 Cisco Systems, Inc.
- * All rights reserved.
- *
- * This software was developed by Bjoern Zeeb under contract to
- * Cisco Systems, Inc..
- *
- * 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$
- */
-
-/*
- * Regression test on SO_SETFIB setsockopt(2).
- *
- * Check that the expected domain(9) families all handle the socket option
- * correctly and do proper bounds checks.
- *
- * Test plan:
- * 1. Get system wide number of FIBs from sysctl and convert to index (-= 1).
- * 2. For each protocol family (INET, INET6, ROUTE and LOCAL) open socketes of
- * type (STREAM, DGRAM and RAW) as supported.
- * 3. Do a sequence of -2, -1, 0, .. n, n+1, n+2 SO_SETFIB sockopt calls,
- * expecting the first two and last two to fail (valid 0 ... n).
- * 4. Try 3 random numbers. Calculate result based on valid range.
- * 5. Repeat for next domain family and type from (2) on.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static struct t_dom {
- int domain;
- const char *name;
-} t_dom[] = {
-#ifdef INET6
- { .domain = PF_INET6, .name = "PF_INET6" },
-#endif
-#ifdef INET
- { .domain = PF_INET, .name = "PF_INET" },
-#endif
- { .domain = PF_ROUTE, .name = "PF_ROUTE" },
- { .domain = PF_LOCAL, .name = "PF_LOCAL" },
-};
-
-static struct t_type {
- int type;
- const char *name;
-} t_type[] = {
- { .type = SOCK_STREAM, .name = "SOCK_STREAM" },
- { .type = SOCK_DGRAM, .name = "SOCK_DGRAM" },
- { .type = SOCK_RAW, .name = "SOCK_RAW" },
-};
-
-/*
- * Number of FIBs as read from net.fibs sysctl - 1. Initialize to clear out of
- * bounds value to not accidentally run on a limited range.
- */
-static int rt_numfibs = -42;
-
-/* Number of test case. */
-static int testno = 1;
-
-
-/*
- * Try the setsockopt with given FIB number i on socket s.
- * Handle result given on error and valid range and errno.
- */
-static void
-so_setfib(int s, int i, u_int dom, u_int type)
-{
- int error;
-
- error = setsockopt(s, SOL_SOCKET, SO_SETFIB, &i, sizeof(i));
- /* For out of bounds we expect an error. */
- if (error == -1 && (i < 0 || i > rt_numfibs))
- printf("ok %d %s_%s_%d\n", testno, t_dom[dom].name,
- t_type[type].name, i);
- else if (error != -1 && (i < 0 || i > rt_numfibs))
- printf("not ok %d %s_%s_%d # setsockopt(%d, SOL_SOCKET, "
- "SO_SETFIB, %d, ..) unexpectedly succeeded\n", testno,
- t_dom[dom].name, t_type[type].name, i, s, i);
- else if (error == 0)
- printf("ok %d %s_%s_%d\n", testno, t_dom[dom].name,
- t_type[type].name, i);
- else if (errno != EINVAL)
- printf("not ok %d %s_%s_%d # setsockopt(%d, SOL_SOCKET, "
- "SO_SETFIB, %d, ..) unexpected error: %s\n", testno,
- t_dom[dom].name, t_type[type].name, i, s, i,
- strerror(errno));
- else
- printf("not ok %d %s_%s_%d\n", testno, t_dom[dom].name,
- t_type[type].name, i);
-
- /* Test run done, next please. */
- testno++;
-}
-
-/*
- * Main test. Open socket given domain family and type. For each FIB, out of
- * bounds FIB numbers and 3 random FIB numbers set the socket option.
- */
-static void
-t(u_int dom, u_int type)
-{
- int i, s;
-
- /* PF_ROUTE only supports RAW socket types, while PF_LOCAL does not. */
- if (t_dom[dom].domain == PF_ROUTE && t_type[type].type != SOCK_RAW)
- return;
- if (t_dom[dom].domain == PF_LOCAL && t_type[type].type == SOCK_RAW)
- return;
-
- /* Open socket for given combination. */
- s = socket(t_dom[dom].domain, t_type[type].type, 0);
- if (s == -1) {
- printf("not ok %d %s_%s # socket(): %s\n", testno,
- t_dom[dom].name, t_type[type].name, strerror(errno));
- testno++;
- return;
- }
-
- /* Test FIBs -2, -1, 0, .. n, n + 1, n + 2. */
- for (i = -2; i <= (rt_numfibs + 2); i++)
- so_setfib(s, i, dom, type);
-
- /* Test 3 random FIB numbers. */
- for (i = 0; i < 3; i++)
- so_setfib(s, (int)random(), dom, type);
-
- /* Close socket. */
- close(s);
-}
-
-/*
- * Returns 0 if no program error, 1 on sysctlbyname error.
- * Test results are communicated by printf("[not ]ok <n> ..").
- */
-int
-main(int argc __unused, char *argv[] __unused)
-{
- u_int i, j;
- size_t s;
-
- if (geteuid() != 0) {
- printf("1..0 # SKIP: must be root");
- return (0);
- }
-
- /* Initalize randomness. */
- srandomdev();
-
- /* Get number of FIBs supported by kernel. */
- s = sizeof(rt_numfibs);
- if (sysctlbyname("net.fibs", &rt_numfibs, &s, NULL, 0) == -1)
- err(1, "sysctlbyname(net.fibs, ..)");
-
- printf("1..%lu\n",
- (nitems(t_dom) - 1) * nitems(t_type) * (2 + rt_numfibs + 2 + 3));
-
- /* Adjust from number to index. */
- rt_numfibs -= 1;
-
- /* Run tests. */
- for (i = 0; i < sizeof(t_dom) / sizeof(struct t_dom); i++)
- for (j = 0; j < sizeof(t_type) / sizeof(struct t_type); j++)
- t(i, j);
-
- return (0);
-}
-
-/* end */
diff --git a/tests/sys/sockets/socketpair_test.c b/tests/sys/sockets/socketpair_test.c
deleted file mode 100644
index 779878a..0000000
--- a/tests/sys/sockets/socketpair_test.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * Copyright (c) 2004 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Open, then close a set of UNIX domain socket pairs for datagram and
- * stream.
- *
- * Confirm that we can't open INET datagram or stream socket pairs.
- *
- * More tests should be added, including confirming that sending on either
- * endpoint results in data at the other, that the right kind of socket was
- * created (stream vs. datagram), and that message boundaries fall in the
- * right places.
- */
-int
-main(void)
-{
- int fd1, fd2, fd3;
- int sv[2];
-
- /*
- * UNIX domain socket pair, datagram.
- */
- if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM): %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (close(sv[0]) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 0: %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (close(sv[1]) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 1: %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
-
- /*
- * UNIX domain socket pair, stream.
- */
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM): %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (close(sv[0]) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 0: %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (close(sv[1]) != 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 1: "
- "%s\n", strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
-
- /*
- * Confirm that PF_INET datagram socket pair creation fails.
- */
- if (socketpair(PF_INET, SOCK_DGRAM, 0, sv) == 0) {
- fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): opened\n");
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (errno != EOPNOTSUPP) {
- fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- }
-
- /*
- * Confirm that PF_INET stream socket pair creation fails.
- */
- if (socketpair(PF_INET, SOCK_STREAM, 0, sv) == 0) {
- fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): opened\n");
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (errno != EOPNOTSUPP) {
- fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- }
-
- /*
- * Check for sequential fd allocation, and give up early if not.
- */
- fd1 = dup(STDIN_FILENO);
- fd2 = dup(STDIN_FILENO);
- if (fd2 != fd1 + 1) {
- fprintf(stderr, "Non-sequential fd allocation\n");
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
-
- /* Allocate a socketpair using a bad destination address. */
- if (socketpair(PF_UNIX, SOCK_DGRAM, 0, NULL) == 0) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): opened\n");
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
- if (errno != EFAULT) {
- fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): %s\n",
- strerror(errno));
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
-
- /* Allocate a file descriptor and make sure it's fd2+1. */
- fd3 = dup(STDIN_FILENO);
- if (fd3 != fd2 + 1) {
- fprintf(stderr, "socketpair(..., NULL) allocated descriptors\n");
- fprintf(stderr, "FAIL\n");
- exit(-1);
- }
-
- fprintf(stderr, "PASS\n");
- exit(0);
-}
diff --git a/tests/sys/sockets/unix_bindconnect_test.c b/tests/sys/sockets/unix_bindconnect_test.c
deleted file mode 100644
index 079dc4d..0000000
--- a/tests/sys/sockets/unix_bindconnect_test.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * Simple regression test to exercise some error cases relating to the use of
- * bind() and connect() on UNIX domain sockets. In particular, make sure
- * that when two sockets rendezvous using the file system name space, they
- * get the expected success/failure cases.
- *
- * TODO:
- * - Check that the resulting file mode/owner are right.
- * - Do the same tests with UNIX domain sockets.
- * - Check the results of getsockaddr() and getpeeraddr().
- */
-
-#define SOCK_NAME_ONE "socket.1"
-#define SOCK_NAME_TWO "socket.2"
-
-#define UNWIND_MAX 1024
-
-static int unwind_len;
-static struct unwind {
- char u_path[PATH_MAX];
-} unwind_list[UNWIND_MAX];
-
-static void
-push_path(const char *path)
-{
-
- if (unwind_len >= UNWIND_MAX)
- err(-1, "push_path: one path too many (%s)", path);
-
- strlcpy(unwind_list[unwind_len].u_path, path, PATH_MAX);
- unwind_len++;
-}
-
-static void
-unwind(void)
-{
- int i;
-
- for (i = unwind_len - 1; i >= 0; i--) {
- unlink(unwind_list[i].u_path);
- rmdir(unwind_list[i].u_path);
- }
-}
-
-static int
-bind_test(const char *directory_path)
-{
- char socket_path[PATH_MAX];
- struct sockaddr_un sun;
- int sock1, sock2;
-
- sock1 = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock1 < 0) {
- warn("bind_test: socket(PF_UNIX, SOCK_STREAM, 0)");
- return (-1);
- }
-
- if (snprintf(socket_path, sizeof(socket_path), "%s/%s",
- directory_path, SOCK_NAME_ONE) >= PATH_MAX) {
- warn("bind_test: snprintf(socket_path)");
- close(sock1);
- return (-1);
- }
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- if (snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", socket_path)
- >= (int)sizeof(sun.sun_path)) {
- warn("bind_test: snprintf(sun.sun_path)");
- close(sock1);
- return (-1);
- }
-
- if (bind(sock1, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
- warn("bind_test: bind(sun) #1");
- close(sock1);
- return (-1);
- }
-
- push_path(socket_path);
-
- /*
- * Once a STREAM UNIX domain socket has been bound, it can't be
- * rebound. Expected error is EINVAL.
- */
- if (bind(sock1, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- warnx("bind_test: bind(sun) #2 succeeded");
- close(sock1);
- return (-1);
- }
- if (errno != EINVAL) {
- warn("bind_test: bind(sun) #2");
- close(sock1);
- return (-1);
- }
-
- sock2 = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock2 < 0) {
- warn("bind_test: socket(PF_UNIX, SOCK_STREAM, 0)");
- close(sock1);
- return (-1);
- }
-
- /*
- * Since a socket is already bound to the pathname, it can't be bound
- * to a second socket. Expected error is EADDRINUSE.
- */
- if (bind(sock2, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- warnx("bind_test: bind(sun) #3 succeeded");
- close(sock1);
- close(sock2);
- return (-1);
- }
- if (errno != EADDRINUSE) {
- warn("bind_test: bind(sun) #2");
- close(sock1);
- close(sock2);
- return (-1);
- }
-
- close(sock1);
-
- /*
- * The socket bound to the pathname has been closed, but the pathname
- * can't be reused without first being unlinked. Expected error is
- * EADDRINUSE.
- */
- if (bind(sock2, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- warnx("bind_test: bind(sun) #4 succeeded");
- close(sock2);
- return (-1);
- }
- if (errno != EADDRINUSE) {
- warn("bind_test: bind(sun) #4");
- close(sock2);
- return (-1);
- }
-
- unlink(socket_path);
-
- /*
- * The pathname is now free, so the socket should be able to bind to
- * it.
- */
- if (bind(sock2, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
- warn("bind_test: bind(sun) #5");
- close(sock2);
- return (-1);
- }
-
- close(sock2);
- return (0);
-}
-
-static int
-connect_test(const char *directory_path)
-{
- char socket_path[PATH_MAX];
- struct sockaddr_un sun;
- int sock1, sock2;
-
- sock1 = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock1 < 0) {
- warn("connect_test: socket(PF_UNIX, SOCK_STREAM, 0)");
- return (-1);
- }
-
- if (snprintf(socket_path, sizeof(socket_path), "%s/%s",
- directory_path, SOCK_NAME_TWO) >= PATH_MAX) {
- warn("connect_test: snprintf(socket_path)");
- close(sock1);
- return (-1);
- }
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- if (snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", socket_path)
- >= (int)sizeof(sun.sun_path)) {
- warn("connect_test: snprintf(sun.sun_path)");
- close(sock1);
- return (-1);
- }
-
- /*
- * Try connecting to a path that doesn't yet exist. Should fail with
- * ENOENT.
- */
- if (connect(sock1, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- warnx("connect_test: connect(sun) #1 succeeded");
- close(sock1);
- return (-1);
- }
- if (errno != ENOENT) {
- warn("connect_test: connect(sun) #1");
- close(sock1);
- return (-1);
- }
-
- if (bind(sock1, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
- warn("connect_test: bind(sun) #1");
- close(sock1);
- return (-1);
- }
-
- if (listen(sock1, 3) < 0) {
- warn("connect_test: listen(sock1)");
- close(sock1);
- return (-1);
- }
-
- push_path(socket_path);
-
- sock2 = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock2 < 0) {
- warn("socket(PF_UNIX, SOCK_STREAM, 0)");
- close(sock1);
- return (-1);
- }
-
- /*
- * Do a simple connect and make sure that works.
- */
- if (connect(sock2, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
- warn("connect(sun) #2");
- close(sock1);
- return (-1);
- }
-
- close(sock2);
-
- close(sock1);
-
- sock2 = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock2 < 0) {
- warn("socket(PF_UNIX, SOCK_STREAM, 0)");
- return (-1);
- }
-
- /*
- * Confirm that once the listen socket is closed, we get a
- * connection refused (ECONNREFUSED) when attempting to connect to
- * the pathname.
- */
- if (connect(sock2, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- warnx("connect(sun) #3 succeeded");
- close(sock2);
- return (-1);
- }
- if (errno != ECONNREFUSED) {
- warn("connect(sun) #3");
- close(sock2);
- return (-1);
- }
-
- close(sock2);
- unlink(socket_path);
- return (0);
-}
-int
-main(void)
-{
- char directory_path[PATH_MAX];
- int error;
-
- strlcpy(directory_path, "/tmp/unix_bind.XXXXXXX", PATH_MAX);
- if (mkdtemp(directory_path) == NULL)
- err(-1, "mkdtemp");
- push_path(directory_path);
-
- error = bind_test(directory_path);
-
- if (error == 0)
- error = connect_test(directory_path);
-
- unwind();
- return (error);
-}
diff --git a/tests/sys/sockets/unix_close_race_test.c b/tests/sys/sockets/unix_close_race_test.c
deleted file mode 100644
index 89c1b20..0000000
--- a/tests/sys/sockets/unix_close_race_test.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*-
- * Copyright (c) 2010 Mikolaj Golub
- * 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$
- */
-
-/*
- * This regression test attempts to trigger a race that occurs when both
- * endpoints of a connected UNIX domain socket are closed at once. The two
- * close paths may run concurrently leading to a call to sodisconnect() on an
- * already-closed socket in kernel. Before it was fixed, this might lead to
- * ENOTCONN being returned improperly from close().
- *
- * This race is fairly timing-dependent, so it effectively requires SMP, and
- * may not even trigger then.
- */
-
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <strings.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-
-static char socket_path[] = "tmp.XXXXXXXX";
-
-#define USLEEP 100
-#define LOOPS 100000
-
-int
-main(void)
-{
- struct sockaddr_un servaddr;
- int listenfd, connfd, pid;
- u_int counter, ncpus;
- size_t len;
-
- len = sizeof(ncpus);
- if (sysctlbyname("kern.smp.cpus", &ncpus, &len, NULL, 0) < 0)
- err(1, "kern.smp.cpus");
- if (len != sizeof(ncpus))
- errx(1, "kern.smp.cpus: invalid length");
- if (ncpus < 2)
- warnx("SMP not present, test may be unable to trigger race");
-
- if (mkstemp(socket_path) == -1)
- err(1, "mkstemp failed");
- unlink(socket_path);
-
- /*
- * Create a UNIX domain socket that the child will repeatedly
- * accept() from, and that the parent will repeatedly connect() to.
- */
- if ((listenfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
- err(1, "parent: socket error");
- (void)unlink(socket_path);
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sun_family = AF_LOCAL;
- strcpy(servaddr.sun_path, socket_path);
- if (bind(listenfd, (struct sockaddr *) &servaddr,
- sizeof(servaddr)) < 0)
- err(1, "parent: bind error");
- if (listen(listenfd, 1024) < 0)
- err(1, "parent: listen error");
-
- pid = fork();
- if (pid == -1)
- err(1, "fork()");
- if (pid != 0) {
- /*
- * In the parent, repeatedly connect and disconnect from the
- * socket, attempting to induce the race.
- */
- close(listenfd);
- sleep(1);
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sun_family = AF_LOCAL;
- strcpy(servaddr.sun_path, socket_path);
- for (counter = 0; counter < LOOPS; counter++) {
- if ((connfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
- (void)kill(pid, SIGTERM);
- err(1, "parent: socket error");
- }
- if (connect(connfd, (struct sockaddr *)&servaddr,
- sizeof(servaddr)) < 0) {
- (void)kill(pid, SIGTERM);
- err(1, "parent: connect error");
- }
- if (close(connfd) < 0) {
- (void)kill(pid, SIGTERM);
- err(1, "parent: close error");
- }
- usleep(USLEEP);
- }
- (void)kill(pid, SIGTERM);
- } else {
- /*
- * In the child, loop accepting and closing. We may pick up
- * the race here so report errors from close().
- */
- for ( ; ; ) {
- if ((connfd = accept(listenfd,
- (struct sockaddr *)NULL, NULL)) < 0)
- err(1, "child: accept error");
- if (close(connfd) < 0)
- err(1, "child: close error");
- }
- }
- printf("OK\n");
- exit(0);
-}
diff --git a/tests/sys/sockets/unix_cmsg.c b/tests/sys/sockets/unix_cmsg.c
deleted file mode 100644
index d91cef4..0000000
--- a/tests/sys/sockets/unix_cmsg.c
+++ /dev/null
@@ -1,1969 +0,0 @@
-/*-
- * Copyright (c) 2005 Andrey Simonenko
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/ucred.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <paths.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * There are tables with tests descriptions and pointers to test
- * functions. Each t_*() function returns 0 if its test passed,
- * -1 if its test failed, -2 if some system error occurred.
- * If a test function returns -2, then a program exits.
- *
- * If a test function forks a client process, then it waits for its
- * termination. If a return code of a client process is not equal
- * to zero, or if a client process was terminated by a signal, then
- * a test function returns -1 or -2 depending on exit status of
- * a client process.
- *
- * Each function which can block, is run under TIMEOUT. If timeout
- * occurs, then a test function returns -2 or a client process exits
- * with a non-zero return code.
- */
-
-#ifndef LISTENQ
-# define LISTENQ 1
-#endif
-
-#ifndef TIMEOUT
-# define TIMEOUT 2
-#endif
-
-static int t_cmsgcred(void);
-static int t_sockcred_1(void);
-static int t_sockcred_2(void);
-static int t_cmsgcred_sockcred(void);
-static int t_timeval(void);
-static int t_bintime(void);
-static int t_cmsg_len(void);
-static int t_peercred(void);
-
-struct test_func {
- int (*func)(void);
- const char *desc;
-};
-
-static const struct test_func test_stream_tbl[] = {
- {
- .func = NULL,
- .desc = "All tests"
- },
- {
- .func = t_cmsgcred,
- .desc = "Sending, receiving cmsgcred"
- },
- {
- .func = t_sockcred_1,
- .desc = "Receiving sockcred (listening socket)"
- },
- {
- .func = t_sockcred_2,
- .desc = "Receiving sockcred (accepted socket)"
- },
- {
- .func = t_cmsgcred_sockcred,
- .desc = "Sending cmsgcred, receiving sockcred"
- },
- {
- .func = t_timeval,
- .desc = "Sending, receiving timeval"
- },
- {
- .func = t_bintime,
- .desc = "Sending, receiving bintime"
- },
- {
- .func = t_cmsg_len,
- .desc = "Check cmsghdr.cmsg_len"
- },
- {
- .func = t_peercred,
- .desc = "Check LOCAL_PEERCRED socket option"
- }
-};
-
-#define TEST_STREAM_TBL_SIZE \
- (sizeof(test_stream_tbl) / sizeof(test_stream_tbl[0]))
-
-static const struct test_func test_dgram_tbl[] = {
- {
- .func = NULL,
- .desc = "All tests"
- },
- {
- .func = t_cmsgcred,
- .desc = "Sending, receiving cmsgcred"
- },
- {
- .func = t_sockcred_2,
- .desc = "Receiving sockcred"
- },
- {
- .func = t_cmsgcred_sockcred,
- .desc = "Sending cmsgcred, receiving sockcred"
- },
- {
- .func = t_timeval,
- .desc = "Sending, receiving timeval"
- },
- {
- .func = t_bintime,
- .desc = "Sending, receiving bintime"
- },
- {
- .func = t_cmsg_len,
- .desc = "Check cmsghdr.cmsg_len"
- }
-};
-
-#define TEST_DGRAM_TBL_SIZE \
- (sizeof(test_dgram_tbl) / sizeof(test_dgram_tbl[0]))
-
-static bool debug = false;
-static bool server_flag = true;
-static bool send_data_flag = true;
-static bool send_array_flag = true;
-static bool failed_flag = false;
-
-static int sock_type;
-static const char *sock_type_str;
-
-static const char *proc_name;
-
-static char work_dir[] = _PATH_TMP "unix_cmsg.XXXXXXX";
-static int serv_sock_fd;
-static struct sockaddr_un serv_addr_sun;
-
-static struct {
- char *buf_send;
- char *buf_recv;
- size_t buf_size;
- u_int msg_num;
-} ipc_msg;
-
-#define IPC_MSG_NUM_DEF 5
-#define IPC_MSG_NUM_MAX 10
-#define IPC_MSG_SIZE_DEF 7
-#define IPC_MSG_SIZE_MAX 128
-
-static struct {
- uid_t uid;
- uid_t euid;
- gid_t gid;
- gid_t egid;
- gid_t *gid_arr;
- int gid_num;
-} proc_cred;
-
-static pid_t client_pid;
-
-#define SYNC_SERVER 0
-#define SYNC_CLIENT 1
-#define SYNC_RECV 0
-#define SYNC_SEND 1
-
-static int sync_fd[2][2];
-
-#define LOGMSG_SIZE 128
-
-static void logmsg(const char *, ...) __printflike(1, 2);
-static void logmsgx(const char *, ...) __printflike(1, 2);
-static void dbgmsg(const char *, ...) __printflike(1, 2);
-static void output(const char *, ...) __printflike(1, 2);
-
-static void
-usage(bool verbose)
-{
- u_int i;
-
- printf("usage: %s [-dh] [-n num] [-s size] [-t type] "
- "[-z value] [testno]\n", getprogname());
- if (!verbose)
- return;
- printf("\n Options are:\n\
- -d Output debugging information\n\
- -h Output the help message and exit\n\
- -n num Number of messages to send\n\
- -s size Specify size of data for IPC\n\
- -t type Specify socket type (stream, dgram) for tests\n\
- -z value Do not send data in a message (bit 0x1), do not send\n\
- data array associated with a cmsghdr structure (bit 0x2)\n\
- testno Run one test by its number (require the -t option)\n\n");
- printf(" Available tests for stream sockets:\n");
- for (i = 0; i < TEST_STREAM_TBL_SIZE; ++i)
- printf(" %u: %s\n", i, test_stream_tbl[i].desc);
- printf("\n Available tests for datagram sockets:\n");
- for (i = 0; i < TEST_DGRAM_TBL_SIZE; ++i)
- printf(" %u: %s\n", i, test_dgram_tbl[i].desc);
-}
-
-static void
-output(const char *format, ...)
-{
- char buf[LOGMSG_SIZE];
- va_list ap;
-
- va_start(ap, format);
- if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
- err(EXIT_FAILURE, "output: vsnprintf failed");
- write(STDOUT_FILENO, buf, strlen(buf));
- va_end(ap);
-}
-
-static void
-logmsg(const char *format, ...)
-{
- char buf[LOGMSG_SIZE];
- va_list ap;
- int errno_save;
-
- errno_save = errno;
- va_start(ap, format);
- if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
- err(EXIT_FAILURE, "logmsg: vsnprintf failed");
- if (errno_save == 0)
- output("%s: %s\n", proc_name, buf);
- else
- output("%s: %s: %s\n", proc_name, buf, strerror(errno_save));
- va_end(ap);
- errno = errno_save;
-}
-
-static void
-vlogmsgx(const char *format, va_list ap)
-{
- char buf[LOGMSG_SIZE];
-
- if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
- err(EXIT_FAILURE, "logmsgx: vsnprintf failed");
- output("%s: %s\n", proc_name, buf);
-
-}
-
-static void
-logmsgx(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- vlogmsgx(format, ap);
- va_end(ap);
-}
-
-static void
-dbgmsg(const char *format, ...)
-{
- va_list ap;
-
- if (debug) {
- va_start(ap, format);
- vlogmsgx(format, ap);
- va_end(ap);
- }
-}
-
-static int
-run_tests(int type, u_int testno1)
-{
- const struct test_func *tf;
- u_int i, testno2, failed_num;
-
- sock_type = type;
- if (type == SOCK_STREAM) {
- sock_type_str = "SOCK_STREAM";
- tf = test_stream_tbl;
- i = TEST_STREAM_TBL_SIZE - 1;
- } else {
- sock_type_str = "SOCK_DGRAM";
- tf = test_dgram_tbl;
- i = TEST_DGRAM_TBL_SIZE - 1;
- }
- if (testno1 == 0) {
- testno1 = 1;
- testno2 = i;
- } else
- testno2 = testno1;
-
- output("Running tests for %s sockets:\n", sock_type_str);
- failed_num = 0;
- for (i = testno1, tf += testno1; i <= testno2; ++tf, ++i) {
- output(" %u: %s\n", i, tf->desc);
- switch (tf->func()) {
- case -1:
- ++failed_num;
- break;
- case -2:
- logmsgx("some system error or timeout occurred");
- return (-1);
- }
- }
-
- if (failed_num != 0)
- failed_flag = true;
-
- if (testno1 != testno2) {
- if (failed_num == 0)
- output("-- all tests passed!\n");
- else
- output("-- %u test%s failed!\n",
- failed_num, failed_num == 1 ? "" : "s");
- } else {
- if (failed_num == 0)
- output("-- test passed!\n");
- else
- output("-- test failed!\n");
- }
-
- return (0);
-}
-
-static int
-init(void)
-{
- struct sigaction sigact;
- size_t idx;
- int rv;
-
- proc_name = "SERVER";
-
- sigact.sa_handler = SIG_IGN;
- sigact.sa_flags = 0;
- sigemptyset(&sigact.sa_mask);
- if (sigaction(SIGPIPE, &sigact, (struct sigaction *)NULL) < 0) {
- logmsg("init: sigaction");
- return (-1);
- }
-
- if (ipc_msg.buf_size == 0)
- ipc_msg.buf_send = ipc_msg.buf_recv = NULL;
- else {
- ipc_msg.buf_send = malloc(ipc_msg.buf_size);
- ipc_msg.buf_recv = malloc(ipc_msg.buf_size);
- if (ipc_msg.buf_send == NULL || ipc_msg.buf_recv == NULL) {
- logmsg("init: malloc");
- return (-1);
- }
- for (idx = 0; idx < ipc_msg.buf_size; ++idx)
- ipc_msg.buf_send[idx] = (char)idx;
- }
-
- proc_cred.uid = getuid();
- proc_cred.euid = geteuid();
- proc_cred.gid = getgid();
- proc_cred.egid = getegid();
- proc_cred.gid_num = getgroups(0, (gid_t *)NULL);
- if (proc_cred.gid_num < 0) {
- logmsg("init: getgroups");
- return (-1);
- }
- proc_cred.gid_arr = malloc(proc_cred.gid_num *
- sizeof(*proc_cred.gid_arr));
- if (proc_cred.gid_arr == NULL) {
- logmsg("init: malloc");
- return (-1);
- }
- if (getgroups(proc_cred.gid_num, proc_cred.gid_arr) < 0) {
- logmsg("init: getgroups");
- return (-1);
- }
-
- memset(&serv_addr_sun, 0, sizeof(serv_addr_sun));
- rv = snprintf(serv_addr_sun.sun_path, sizeof(serv_addr_sun.sun_path),
- "%s/%s", work_dir, proc_name);
- if (rv < 0) {
- logmsg("init: snprintf");
- return (-1);
- }
- if ((size_t)rv >= sizeof(serv_addr_sun.sun_path)) {
- logmsgx("init: not enough space for socket pathname");
- return (-1);
- }
- serv_addr_sun.sun_family = PF_LOCAL;
- serv_addr_sun.sun_len = SUN_LEN(&serv_addr_sun);
-
- return (0);
-}
-
-static int
-client_fork(void)
-{
- int fd1, fd2;
-
- if (pipe(sync_fd[SYNC_SERVER]) < 0 ||
- pipe(sync_fd[SYNC_CLIENT]) < 0) {
- logmsg("client_fork: pipe");
- return (-1);
- }
- client_pid = fork();
- if (client_pid == (pid_t)-1) {
- logmsg("client_fork: fork");
- return (-1);
- }
- if (client_pid == 0) {
- proc_name = "CLIENT";
- server_flag = false;
- fd1 = sync_fd[SYNC_SERVER][SYNC_RECV];
- fd2 = sync_fd[SYNC_CLIENT][SYNC_SEND];
- } else {
- fd1 = sync_fd[SYNC_SERVER][SYNC_SEND];
- fd2 = sync_fd[SYNC_CLIENT][SYNC_RECV];
- }
- if (close(fd1) < 0 || close(fd2) < 0) {
- logmsg("client_fork: close");
- return (-1);
- }
- return (client_pid != 0);
-}
-
-static void
-client_exit(int rv)
-{
- if (close(sync_fd[SYNC_SERVER][SYNC_SEND]) < 0 ||
- close(sync_fd[SYNC_CLIENT][SYNC_RECV]) < 0) {
- logmsg("client_exit: close");
- rv = -1;
- }
- rv = rv == 0 ? EXIT_SUCCESS : -rv;
- dbgmsg("exit: code %d", rv);
- _exit(rv);
-}
-
-static int
-client_wait(void)
-{
- int status;
- pid_t pid;
-
- dbgmsg("waiting for client");
-
- if (close(sync_fd[SYNC_SERVER][SYNC_RECV]) < 0 ||
- close(sync_fd[SYNC_CLIENT][SYNC_SEND]) < 0) {
- logmsg("client_wait: close");
- return (-1);
- }
-
- pid = waitpid(client_pid, &status, 0);
- if (pid == (pid_t)-1) {
- logmsg("client_wait: waitpid");
- return (-1);
- }
-
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status) != EXIT_SUCCESS) {
- logmsgx("client exit status is %d",
- WEXITSTATUS(status));
- return (-WEXITSTATUS(status));
- }
- } else {
- if (WIFSIGNALED(status))
- logmsgx("abnormal termination of client, signal %d%s",
- WTERMSIG(status), WCOREDUMP(status) ?
- " (core file generated)" : "");
- else
- logmsgx("termination of client, unknown status");
- return (-1);
- }
-
- return (0);
-}
-
-int
-main(int argc, char *argv[])
-{
- const char *errstr;
- u_int testno, zvalue;
- int opt, rv;
- bool dgram_flag, stream_flag;
-
- ipc_msg.buf_size = IPC_MSG_SIZE_DEF;
- ipc_msg.msg_num = IPC_MSG_NUM_DEF;
- dgram_flag = stream_flag = false;
- while ((opt = getopt(argc, argv, "dhn:s:t:z:")) != -1)
- switch (opt) {
- case 'd':
- debug = true;
- break;
- case 'h':
- usage(true);
- return (EXIT_SUCCESS);
- case 'n':
- ipc_msg.msg_num = strtonum(optarg, 1,
- IPC_MSG_NUM_MAX, &errstr);
- if (errstr != NULL)
- errx(EXIT_FAILURE, "option -n: number is %s",
- errstr);
- break;
- case 's':
- ipc_msg.buf_size = strtonum(optarg, 0,
- IPC_MSG_SIZE_MAX, &errstr);
- if (errstr != NULL)
- errx(EXIT_FAILURE, "option -s: number is %s",
- errstr);
- break;
- case 't':
- if (strcmp(optarg, "stream") == 0)
- stream_flag = true;
- else if (strcmp(optarg, "dgram") == 0)
- dgram_flag = true;
- else
- errx(EXIT_FAILURE, "option -t: "
- "wrong socket type");
- break;
- case 'z':
- zvalue = strtonum(optarg, 0, 3, &errstr);
- if (errstr != NULL)
- errx(EXIT_FAILURE, "option -z: number is %s",
- errstr);
- if (zvalue & 0x1)
- send_data_flag = false;
- if (zvalue & 0x2)
- send_array_flag = false;
- break;
- default:
- usage(false);
- return (EXIT_FAILURE);
- }
-
- if (optind < argc) {
- if (optind + 1 != argc)
- errx(EXIT_FAILURE, "too many arguments");
- testno = strtonum(argv[optind], 0, UINT_MAX, &errstr);
- if (errstr != NULL)
- errx(EXIT_FAILURE, "test number is %s", errstr);
- if (stream_flag && testno >= TEST_STREAM_TBL_SIZE)
- errx(EXIT_FAILURE, "given test %u for stream "
- "sockets does not exist", testno);
- if (dgram_flag && testno >= TEST_DGRAM_TBL_SIZE)
- errx(EXIT_FAILURE, "given test %u for datagram "
- "sockets does not exist", testno);
- } else
- testno = 0;
-
- if (!dgram_flag && !stream_flag) {
- if (testno != 0)
- errx(EXIT_FAILURE, "particular test number "
- "can be used with the -t option only");
- dgram_flag = stream_flag = true;
- }
-
- if (mkdtemp(work_dir) == NULL)
- err(EXIT_FAILURE, "mkdtemp(%s)", work_dir);
-
- rv = EXIT_FAILURE;
- if (init() < 0)
- goto done;
-
- if (stream_flag)
- if (run_tests(SOCK_STREAM, testno) < 0)
- goto done;
- if (dgram_flag)
- if (run_tests(SOCK_DGRAM, testno) < 0)
- goto done;
-
- rv = EXIT_SUCCESS;
-done:
- if (rmdir(work_dir) < 0) {
- logmsg("rmdir(%s)", work_dir);
- rv = EXIT_FAILURE;
- }
- return (failed_flag ? EXIT_FAILURE : rv);
-}
-
-static int
-socket_close(int fd)
-{
- int rv;
-
- rv = 0;
- if (close(fd) < 0) {
- logmsg("socket_close: close");
- rv = -1;
- }
- if (server_flag && fd == serv_sock_fd)
- if (unlink(serv_addr_sun.sun_path) < 0) {
- logmsg("socket_close: unlink(%s)",
- serv_addr_sun.sun_path);
- rv = -1;
- }
- return (rv);
-}
-
-static int
-socket_create(void)
-{
- struct timeval tv;
- int fd;
-
- fd = socket(PF_LOCAL, sock_type, 0);
- if (fd < 0) {
- logmsg("socket_create: socket(PF_LOCAL, %s, 0)", sock_type_str);
- return (-1);
- }
- if (server_flag)
- serv_sock_fd = fd;
-
- tv.tv_sec = TIMEOUT;
- tv.tv_usec = 0;
- if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ||
- setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
- logmsg("socket_create: setsockopt(SO_RCVTIMEO/SO_SNDTIMEO)");
- goto failed;
- }
-
- if (server_flag) {
- if (bind(fd, (struct sockaddr *)&serv_addr_sun,
- serv_addr_sun.sun_len) < 0) {
- logmsg("socket_create: bind(%s)",
- serv_addr_sun.sun_path);
- goto failed;
- }
- if (sock_type == SOCK_STREAM) {
- int val;
-
- if (listen(fd, LISTENQ) < 0) {
- logmsg("socket_create: listen");
- goto failed;
- }
- val = fcntl(fd, F_GETFL, 0);
- if (val < 0) {
- logmsg("socket_create: fcntl(F_GETFL)");
- goto failed;
- }
- if (fcntl(fd, F_SETFL, val | O_NONBLOCK) < 0) {
- logmsg("socket_create: fcntl(F_SETFL)");
- goto failed;
- }
- }
- }
-
- return (fd);
-
-failed:
- if (close(fd) < 0)
- logmsg("socket_create: close");
- if (server_flag)
- if (unlink(serv_addr_sun.sun_path) < 0)
- logmsg("socket_close: unlink(%s)",
- serv_addr_sun.sun_path);
- return (-1);
-}
-
-static int
-socket_connect(int fd)
-{
- dbgmsg("connect");
-
- if (connect(fd, (struct sockaddr *)&serv_addr_sun,
- serv_addr_sun.sun_len) < 0) {
- logmsg("socket_connect: connect(%s)", serv_addr_sun.sun_path);
- return (-1);
- }
- return (0);
-}
-
-static int
-sync_recv(void)
-{
- ssize_t ssize;
- int fd;
- char buf;
-
- dbgmsg("sync: wait");
-
- fd = sync_fd[server_flag ? SYNC_SERVER : SYNC_CLIENT][SYNC_RECV];
-
- ssize = read(fd, &buf, 1);
- if (ssize < 0) {
- logmsg("sync_recv: read");
- return (-1);
- }
- if (ssize < 1) {
- logmsgx("sync_recv: read %zd of 1 byte", ssize);
- return (-1);
- }
-
- dbgmsg("sync: received");
-
- return (0);
-}
-
-static int
-sync_send(void)
-{
- ssize_t ssize;
- int fd;
-
- dbgmsg("sync: send");
-
- fd = sync_fd[server_flag ? SYNC_CLIENT : SYNC_SERVER][SYNC_SEND];
-
- ssize = write(fd, "", 1);
- if (ssize < 0) {
- logmsg("sync_send: write");
- return (-1);
- }
- if (ssize < 1) {
- logmsgx("sync_send: sent %zd of 1 byte", ssize);
- return (-1);
- }
-
- return (0);
-}
-
-static int
-message_send(int fd, const struct msghdr *msghdr)
-{
- const struct cmsghdr *cmsghdr;
- size_t size;
- ssize_t ssize;
-
- size = msghdr->msg_iov != 0 ? msghdr->msg_iov->iov_len : 0;
- dbgmsg("send: data size %zu", size);
- dbgmsg("send: msghdr.msg_controllen %u",
- (u_int)msghdr->msg_controllen);
- cmsghdr = CMSG_FIRSTHDR(msghdr);
- if (cmsghdr != NULL)
- dbgmsg("send: cmsghdr.cmsg_len %u",
- (u_int)cmsghdr->cmsg_len);
-
- ssize = sendmsg(fd, msghdr, 0);
- if (ssize < 0) {
- logmsg("message_send: sendmsg");
- return (-1);
- }
- if ((size_t)ssize != size) {
- logmsgx("message_send: sendmsg: sent %zd of %zu bytes",
- ssize, size);
- return (-1);
- }
-
- if (!send_data_flag)
- if (sync_send() < 0)
- return (-1);
-
- return (0);
-}
-
-static int
-message_sendn(int fd, struct msghdr *msghdr)
-{
- u_int i;
-
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
- if (message_send(fd, msghdr) < 0)
- return (-1);
- }
- return (0);
-}
-
-static int
-message_recv(int fd, struct msghdr *msghdr)
-{
- const struct cmsghdr *cmsghdr;
- size_t size;
- ssize_t ssize;
-
- if (!send_data_flag)
- if (sync_recv() < 0)
- return (-1);
-
- size = msghdr->msg_iov != NULL ? msghdr->msg_iov->iov_len : 0;
- ssize = recvmsg(fd, msghdr, MSG_WAITALL);
- if (ssize < 0) {
- logmsg("message_recv: recvmsg");
- return (-1);
- }
- if ((size_t)ssize != size) {
- logmsgx("message_recv: recvmsg: received %zd of %zu bytes",
- ssize, size);
- return (-1);
- }
-
- dbgmsg("recv: data size %zd", ssize);
- dbgmsg("recv: msghdr.msg_controllen %u",
- (u_int)msghdr->msg_controllen);
- cmsghdr = CMSG_FIRSTHDR(msghdr);
- if (cmsghdr != NULL)
- dbgmsg("recv: cmsghdr.cmsg_len %u",
- (u_int)cmsghdr->cmsg_len);
-
- if (memcmp(ipc_msg.buf_recv, ipc_msg.buf_send, size) != 0) {
- logmsgx("message_recv: received message has wrong content");
- return (-1);
- }
-
- return (0);
-}
-
-static int
-socket_accept(int listenfd)
-{
- fd_set rset;
- struct timeval tv;
- int fd, rv, val;
-
- dbgmsg("accept");
-
- FD_ZERO(&rset);
- FD_SET(listenfd, &rset);
- tv.tv_sec = TIMEOUT;
- tv.tv_usec = 0;
- rv = select(listenfd + 1, &rset, (fd_set *)NULL, (fd_set *)NULL, &tv);
- if (rv < 0) {
- logmsg("socket_accept: select");
- return (-1);
- }
- if (rv == 0) {
- logmsgx("socket_accept: select timeout");
- return (-1);
- }
-
- fd = accept(listenfd, (struct sockaddr *)NULL, (socklen_t *)NULL);
- if (fd < 0) {
- logmsg("socket_accept: accept");
- return (-1);
- }
-
- val = fcntl(fd, F_GETFL, 0);
- if (val < 0) {
- logmsg("socket_accept: fcntl(F_GETFL)");
- goto failed;
- }
- if (fcntl(fd, F_SETFL, val & ~O_NONBLOCK) < 0) {
- logmsg("socket_accept: fcntl(F_SETFL)");
- goto failed;
- }
-
- return (fd);
-
-failed:
- if (close(fd) < 0)
- logmsg("socket_accept: close");
- return (-1);
-}
-
-static int
-check_msghdr(const struct msghdr *msghdr, size_t size)
-{
- if (msghdr->msg_flags & MSG_TRUNC) {
- logmsgx("msghdr.msg_flags has MSG_TRUNC");
- return (-1);
- }
- if (msghdr->msg_flags & MSG_CTRUNC) {
- logmsgx("msghdr.msg_flags has MSG_CTRUNC");
- return (-1);
- }
- if (msghdr->msg_controllen < size) {
- logmsgx("msghdr.msg_controllen %u < %zu",
- (u_int)msghdr->msg_controllen, size);
- return (-1);
- }
- if (msghdr->msg_controllen > 0 && size == 0) {
- logmsgx("msghdr.msg_controllen %u > 0",
- (u_int)msghdr->msg_controllen);
- return (-1);
- }
- return (0);
-}
-
-static int
-check_cmsghdr(const struct cmsghdr *cmsghdr, int type, size_t size)
-{
- if (cmsghdr == NULL) {
- logmsgx("cmsghdr is NULL");
- return (-1);
- }
- if (cmsghdr->cmsg_level != SOL_SOCKET) {
- logmsgx("cmsghdr.cmsg_level %d != SOL_SOCKET",
- cmsghdr->cmsg_level);
- return (-1);
- }
- if (cmsghdr->cmsg_type != type) {
- logmsgx("cmsghdr.cmsg_type %d != %d",
- cmsghdr->cmsg_type, type);
- return (-1);
- }
- if (cmsghdr->cmsg_len != CMSG_LEN(size)) {
- logmsgx("cmsghdr.cmsg_len %u != %zu",
- (u_int)cmsghdr->cmsg_len, CMSG_LEN(size));
- return (-1);
- }
- return (0);
-}
-
-static int
-check_groups(const char *gid_arr_str, const gid_t *gid_arr,
- const char *gid_num_str, int gid_num, bool all_gids)
-{
- int i;
-
- for (i = 0; i < gid_num; ++i)
- dbgmsg("%s[%d] %lu", gid_arr_str, i, (u_long)gid_arr[i]);
-
- if (all_gids) {
- if (gid_num != proc_cred.gid_num) {
- logmsgx("%s %d != %d", gid_num_str, gid_num,
- proc_cred.gid_num);
- return (-1);
- }
- } else {
- if (gid_num > proc_cred.gid_num) {
- logmsgx("%s %d > %d", gid_num_str, gid_num,
- proc_cred.gid_num);
- return (-1);
- }
- }
- if (memcmp(gid_arr, proc_cred.gid_arr,
- gid_num * sizeof(*gid_arr)) != 0) {
- logmsgx("%s content is wrong", gid_arr_str);
- for (i = 0; i < gid_num; ++i)
- if (gid_arr[i] != proc_cred.gid_arr[i]) {
- logmsgx("%s[%d] %lu != %lu",
- gid_arr_str, i, (u_long)gid_arr[i],
- (u_long)proc_cred.gid_arr[i]);
- break;
- }
- return (-1);
- }
- return (0);
-}
-
-static int
-check_xucred(const struct xucred *xucred, socklen_t len)
-{
- if (len != sizeof(*xucred)) {
- logmsgx("option value size %zu != %zu",
- (size_t)len, sizeof(*xucred));
- return (-1);
- }
-
- dbgmsg("xucred.cr_version %u", xucred->cr_version);
- dbgmsg("xucred.cr_uid %lu", (u_long)xucred->cr_uid);
- dbgmsg("xucred.cr_ngroups %d", xucred->cr_ngroups);
-
- if (xucred->cr_version != XUCRED_VERSION) {
- logmsgx("xucred.cr_version %u != %d",
- xucred->cr_version, XUCRED_VERSION);
- return (-1);
- }
- if (xucred->cr_uid != proc_cred.euid) {
- logmsgx("xucred.cr_uid %lu != %lu (EUID)",
- (u_long)xucred->cr_uid, (u_long)proc_cred.euid);
- return (-1);
- }
- if (xucred->cr_ngroups == 0) {
- logmsgx("xucred.cr_ngroups == 0");
- return (-1);
- }
- if (xucred->cr_ngroups < 0) {
- logmsgx("xucred.cr_ngroups < 0");
- return (-1);
- }
- if (xucred->cr_ngroups > XU_NGROUPS) {
- logmsgx("xucred.cr_ngroups %hu > %u (max)",
- xucred->cr_ngroups, XU_NGROUPS);
- return (-1);
- }
- if (xucred->cr_groups[0] != proc_cred.egid) {
- logmsgx("xucred.cr_groups[0] %lu != %lu (EGID)",
- (u_long)xucred->cr_groups[0], (u_long)proc_cred.egid);
- return (-1);
- }
- if (check_groups("xucred.cr_groups", xucred->cr_groups,
- "xucred.cr_ngroups", xucred->cr_ngroups, false) < 0)
- return (-1);
- return (0);
-}
-
-static int
-check_scm_creds_cmsgcred(struct cmsghdr *cmsghdr)
-{
- const struct cmsgcred *cmsgcred;
-
- if (check_cmsghdr(cmsghdr, SCM_CREDS, sizeof(*cmsgcred)) < 0)
- return (-1);
-
- cmsgcred = (struct cmsgcred *)CMSG_DATA(cmsghdr);
-
- dbgmsg("cmsgcred.cmcred_pid %ld", (long)cmsgcred->cmcred_pid);
- dbgmsg("cmsgcred.cmcred_uid %lu", (u_long)cmsgcred->cmcred_uid);
- dbgmsg("cmsgcred.cmcred_euid %lu", (u_long)cmsgcred->cmcred_euid);
- dbgmsg("cmsgcred.cmcred_gid %lu", (u_long)cmsgcred->cmcred_gid);
- dbgmsg("cmsgcred.cmcred_ngroups %d", cmsgcred->cmcred_ngroups);
-
- if (cmsgcred->cmcred_pid != client_pid) {
- logmsgx("cmsgcred.cmcred_pid %ld != %ld",
- (long)cmsgcred->cmcred_pid, (long)client_pid);
- return (-1);
- }
- if (cmsgcred->cmcred_uid != proc_cred.uid) {
- logmsgx("cmsgcred.cmcred_uid %lu != %lu",
- (u_long)cmsgcred->cmcred_uid, (u_long)proc_cred.uid);
- return (-1);
- }
- if (cmsgcred->cmcred_euid != proc_cred.euid) {
- logmsgx("cmsgcred.cmcred_euid %lu != %lu",
- (u_long)cmsgcred->cmcred_euid, (u_long)proc_cred.euid);
- return (-1);
- }
- if (cmsgcred->cmcred_gid != proc_cred.gid) {
- logmsgx("cmsgcred.cmcred_gid %lu != %lu",
- (u_long)cmsgcred->cmcred_gid, (u_long)proc_cred.gid);
- return (-1);
- }
- if (cmsgcred->cmcred_ngroups == 0) {
- logmsgx("cmsgcred.cmcred_ngroups == 0");
- return (-1);
- }
- if (cmsgcred->cmcred_ngroups < 0) {
- logmsgx("cmsgcred.cmcred_ngroups %d < 0",
- cmsgcred->cmcred_ngroups);
- return (-1);
- }
- if (cmsgcred->cmcred_ngroups > CMGROUP_MAX) {
- logmsgx("cmsgcred.cmcred_ngroups %d > %d",
- cmsgcred->cmcred_ngroups, CMGROUP_MAX);
- return (-1);
- }
- if (cmsgcred->cmcred_groups[0] != proc_cred.egid) {
- logmsgx("cmsgcred.cmcred_groups[0] %lu != %lu (EGID)",
- (u_long)cmsgcred->cmcred_groups[0], (u_long)proc_cred.egid);
- return (-1);
- }
- if (check_groups("cmsgcred.cmcred_groups", cmsgcred->cmcred_groups,
- "cmsgcred.cmcred_ngroups", cmsgcred->cmcred_ngroups, false) < 0)
- return (-1);
- return (0);
-}
-
-static int
-check_scm_creds_sockcred(struct cmsghdr *cmsghdr)
-{
- const struct sockcred *sockcred;
-
- if (check_cmsghdr(cmsghdr, SCM_CREDS,
- SOCKCREDSIZE(proc_cred.gid_num)) < 0)
- return (-1);
-
- sockcred = (struct sockcred *)CMSG_DATA(cmsghdr);
-
- dbgmsg("sockcred.sc_uid %lu", (u_long)sockcred->sc_uid);
- dbgmsg("sockcred.sc_euid %lu", (u_long)sockcred->sc_euid);
- dbgmsg("sockcred.sc_gid %lu", (u_long)sockcred->sc_gid);
- dbgmsg("sockcred.sc_egid %lu", (u_long)sockcred->sc_egid);
- dbgmsg("sockcred.sc_ngroups %d", sockcred->sc_ngroups);
-
- if (sockcred->sc_uid != proc_cred.uid) {
- logmsgx("sockcred.sc_uid %lu != %lu",
- (u_long)sockcred->sc_uid, (u_long)proc_cred.uid);
- return (-1);
- }
- if (sockcred->sc_euid != proc_cred.euid) {
- logmsgx("sockcred.sc_euid %lu != %lu",
- (u_long)sockcred->sc_euid, (u_long)proc_cred.euid);
- return (-1);
- }
- if (sockcred->sc_gid != proc_cred.gid) {
- logmsgx("sockcred.sc_gid %lu != %lu",
- (u_long)sockcred->sc_gid, (u_long)proc_cred.gid);
- return (-1);
- }
- if (sockcred->sc_egid != proc_cred.egid) {
- logmsgx("sockcred.sc_egid %lu != %lu",
- (u_long)sockcred->sc_egid, (u_long)proc_cred.egid);
- return (-1);
- }
- if (sockcred->sc_ngroups == 0) {
- logmsgx("sockcred.sc_ngroups == 0");
- return (-1);
- }
- if (sockcred->sc_ngroups < 0) {
- logmsgx("sockcred.sc_ngroups %d < 0",
- sockcred->sc_ngroups);
- return (-1);
- }
- if (sockcred->sc_ngroups != proc_cred.gid_num) {
- logmsgx("sockcred.sc_ngroups %d != %u",
- sockcred->sc_ngroups, proc_cred.gid_num);
- return (-1);
- }
- if (check_groups("sockcred.sc_groups", sockcred->sc_groups,
- "sockcred.sc_ngroups", sockcred->sc_ngroups, true) < 0)
- return (-1);
- return (0);
-}
-
-static int
-check_scm_timestamp(struct cmsghdr *cmsghdr)
-{
- const struct timeval *timeval;
-
- if (check_cmsghdr(cmsghdr, SCM_TIMESTAMP, sizeof(struct timeval)) < 0)
- return (-1);
-
- timeval = (struct timeval *)CMSG_DATA(cmsghdr);
-
- dbgmsg("timeval.tv_sec %"PRIdMAX", timeval.tv_usec %"PRIdMAX,
- (intmax_t)timeval->tv_sec, (intmax_t)timeval->tv_usec);
-
- return (0);
-}
-
-static int
-check_scm_bintime(struct cmsghdr *cmsghdr)
-{
- const struct bintime *bintime;
-
- if (check_cmsghdr(cmsghdr, SCM_BINTIME, sizeof(struct bintime)) < 0)
- return (-1);
-
- bintime = (struct bintime *)CMSG_DATA(cmsghdr);
-
- dbgmsg("bintime.sec %"PRIdMAX", bintime.frac %"PRIu64,
- (intmax_t)bintime->sec, bintime->frac);
-
- return (0);
-}
-
-static void
-msghdr_init_generic(struct msghdr *msghdr, struct iovec *iov, void *cmsg_data)
-{
- msghdr->msg_name = NULL;
- msghdr->msg_namelen = 0;
- if (send_data_flag) {
- iov->iov_base = server_flag ?
- ipc_msg.buf_recv : ipc_msg.buf_send;
- iov->iov_len = ipc_msg.buf_size;
- msghdr->msg_iov = iov;
- msghdr->msg_iovlen = 1;
- } else {
- msghdr->msg_iov = NULL;
- msghdr->msg_iovlen = 0;
- }
- msghdr->msg_control = cmsg_data;
- msghdr->msg_flags = 0;
-}
-
-static void
-msghdr_init_server(struct msghdr *msghdr, struct iovec *iov,
- void *cmsg_data, size_t cmsg_size)
-{
- msghdr_init_generic(msghdr, iov, cmsg_data);
- msghdr->msg_controllen = cmsg_size;
- dbgmsg("init: data size %zu", msghdr->msg_iov != NULL ?
- msghdr->msg_iov->iov_len : (size_t)0);
- dbgmsg("init: msghdr.msg_controllen %u",
- (u_int)msghdr->msg_controllen);
-}
-
-static void
-msghdr_init_client(struct msghdr *msghdr, struct iovec *iov,
- void *cmsg_data, size_t cmsg_size, int type, size_t arr_size)
-{
- struct cmsghdr *cmsghdr;
-
- msghdr_init_generic(msghdr, iov, cmsg_data);
- if (cmsg_data != NULL) {
- msghdr->msg_controllen = send_array_flag ?
- cmsg_size : CMSG_SPACE(0);
- cmsghdr = CMSG_FIRSTHDR(msghdr);
- cmsghdr->cmsg_level = SOL_SOCKET;
- cmsghdr->cmsg_type = type;
- cmsghdr->cmsg_len = CMSG_LEN(send_array_flag ? arr_size : 0);
- } else
- msghdr->msg_controllen = 0;
-}
-
-static int
-t_generic(int (*client_func)(int), int (*server_func)(int))
-{
- int fd, rv, rv_client;
-
- switch (client_fork()) {
- case 0:
- fd = socket_create();
- if (fd < 0)
- rv = -2;
- else {
- rv = client_func(fd);
- if (socket_close(fd) < 0)
- rv = -2;
- }
- client_exit(rv);
- break;
- case 1:
- fd = socket_create();
- if (fd < 0)
- rv = -2;
- else {
- rv = server_func(fd);
- rv_client = client_wait();
- if (rv == 0 || (rv == -2 && rv_client != 0))
- rv = rv_client;
- if (socket_close(fd) < 0)
- rv = -2;
- }
- break;
- default:
- rv = -2;
- }
- return (rv);
-}
-
-static int
-t_cmsgcred_client(int fd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- void *cmsg_data;
- size_t cmsg_size;
- int rv;
-
- if (sync_recv() < 0)
- return (-2);
-
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
- msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
- SCM_CREDS, sizeof(struct cmsgcred));
-
- if (socket_connect(fd) < 0)
- goto done;
-
- if (message_sendn(fd, &msghdr) < 0)
- goto done;
-
- rv = 0;
-done:
- free(cmsg_data);
- return (rv);
-}
-
-static int
-t_cmsgcred_server(int fd1)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data;
- size_t cmsg_size;
- u_int i;
- int fd2, rv;
-
- if (sync_send() < 0)
- return (-2);
-
- fd2 = -1;
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- rv = -1;
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
-
- msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
- if (message_recv(fd2, &msghdr) < 0) {
- rv = -2;
- break;
- }
-
- if (check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
- break;
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (check_scm_creds_cmsgcred(cmsghdr) < 0)
- break;
- }
- if (i > ipc_msg.msg_num)
- rv = 0;
-done:
- free(cmsg_data);
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_cmsgcred(void)
-{
- return (t_generic(t_cmsgcred_client, t_cmsgcred_server));
-}
-
-static int
-t_sockcred_client(int type, int fd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- int rv;
-
- if (sync_recv() < 0)
- return (-2);
-
- rv = -2;
-
- msghdr_init_client(&msghdr, iov, NULL, 0, 0, 0);
-
- if (socket_connect(fd) < 0)
- goto done;
-
- if (type == 2)
- if (sync_recv() < 0)
- goto done;
-
- if (message_sendn(fd, &msghdr) < 0)
- goto done;
-
- rv = 0;
-done:
- return (rv);
-}
-
-static int
-t_sockcred_server(int type, int fd1)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data;
- size_t cmsg_size;
- u_int i;
- int fd2, rv, val;
-
- fd2 = -1;
- rv = -2;
-
- cmsg_size = CMSG_SPACE(SOCKCREDSIZE(proc_cred.gid_num));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
-
- if (type == 1) {
- dbgmsg("setting LOCAL_CREDS");
- val = 1;
- if (setsockopt(fd1, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
- logmsg("setsockopt(LOCAL_CREDS)");
- goto done;
- }
- }
-
- if (sync_send() < 0)
- goto done;
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- if (type == 2) {
- dbgmsg("setting LOCAL_CREDS");
- val = 1;
- if (setsockopt(fd2, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
- logmsg("setsockopt(LOCAL_CREDS)");
- goto done;
- }
- if (sync_send() < 0)
- goto done;
- }
-
- rv = -1;
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
-
- msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
- if (message_recv(fd2, &msghdr) < 0) {
- rv = -2;
- break;
- }
-
- if (i > 1 && sock_type == SOCK_STREAM) {
- if (check_msghdr(&msghdr, 0) < 0)
- break;
- } else {
- if (check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
- break;
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (check_scm_creds_sockcred(cmsghdr) < 0)
- break;
- }
- }
- if (i > ipc_msg.msg_num)
- rv = 0;
-done:
- free(cmsg_data);
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_sockcred_1(void)
-{
- u_int i;
- int fd, rv, rv_client;
-
- switch (client_fork()) {
- case 0:
- for (i = 1; i <= 2; ++i) {
- dbgmsg("client #%u", i);
- fd = socket_create();
- if (fd < 0)
- rv = -2;
- else {
- rv = t_sockcred_client(1, fd);
- if (socket_close(fd) < 0)
- rv = -2;
- }
- if (rv != 0)
- break;
- }
- client_exit(rv);
- break;
- case 1:
- fd = socket_create();
- if (fd < 0)
- rv = -2;
- else {
- rv = t_sockcred_server(1, fd);
- if (rv == 0)
- rv = t_sockcred_server(3, fd);
- rv_client = client_wait();
- if (rv == 0 || (rv == -2 && rv_client != 0))
- rv = rv_client;
- if (socket_close(fd) < 0)
- rv = -2;
- }
- break;
- default:
- rv = -2;
- }
-
- return (rv);
-}
-
-static int
-t_sockcred_2_client(int fd)
-{
- return (t_sockcred_client(2, fd));
-}
-
-static int
-t_sockcred_2_server(int fd)
-{
- return (t_sockcred_server(2, fd));
-}
-
-static int
-t_sockcred_2(void)
-{
- return (t_generic(t_sockcred_2_client, t_sockcred_2_server));
-}
-
-static int
-t_cmsgcred_sockcred_server(int fd1)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data, *cmsg1_data, *cmsg2_data;
- size_t cmsg_size, cmsg1_size, cmsg2_size;
- u_int i;
- int fd2, rv, val;
-
- fd2 = -1;
- rv = -2;
-
- cmsg1_size = CMSG_SPACE(SOCKCREDSIZE(proc_cred.gid_num));
- cmsg2_size = CMSG_SPACE(sizeof(struct cmsgcred));
- cmsg1_data = malloc(cmsg1_size);
- cmsg2_data = malloc(cmsg2_size);
- if (cmsg1_data == NULL || cmsg2_data == NULL) {
- logmsg("malloc");
- goto done;
- }
-
- dbgmsg("setting LOCAL_CREDS");
- val = 1;
- if (setsockopt(fd1, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
- logmsg("setsockopt(LOCAL_CREDS)");
- goto done;
- }
-
- if (sync_send() < 0)
- goto done;
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- cmsg_data = cmsg1_data;
- cmsg_size = cmsg1_size;
- rv = -1;
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
-
- msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
- if (message_recv(fd2, &msghdr) < 0) {
- rv = -2;
- break;
- }
-
- if (check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
- break;
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (i == 1 || sock_type == SOCK_DGRAM) {
- if (check_scm_creds_sockcred(cmsghdr) < 0)
- break;
- } else {
- if (check_scm_creds_cmsgcred(cmsghdr) < 0)
- break;
- }
-
- cmsg_data = cmsg2_data;
- cmsg_size = cmsg2_size;
- }
- if (i > ipc_msg.msg_num)
- rv = 0;
-done:
- free(cmsg1_data);
- free(cmsg2_data);
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_cmsgcred_sockcred(void)
-{
- return (t_generic(t_cmsgcred_client, t_cmsgcred_sockcred_server));
-}
-
-static int
-t_timeval_client(int fd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- void *cmsg_data;
- size_t cmsg_size;
- int rv;
-
- if (sync_recv() < 0)
- return (-2);
-
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct timeval));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
- msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
- SCM_TIMESTAMP, sizeof(struct timeval));
-
- if (socket_connect(fd) < 0)
- goto done;
-
- if (message_sendn(fd, &msghdr) < 0)
- goto done;
-
- rv = 0;
-done:
- free(cmsg_data);
- return (rv);
-}
-
-static int
-t_timeval_server(int fd1)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data;
- size_t cmsg_size;
- u_int i;
- int fd2, rv;
-
- if (sync_send() < 0)
- return (-2);
-
- fd2 = -1;
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct timeval));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- rv = -1;
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
-
- msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
- if (message_recv(fd2, &msghdr) < 0) {
- rv = -2;
- break;
- }
-
- if (check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
- break;
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (check_scm_timestamp(cmsghdr) < 0)
- break;
- }
- if (i > ipc_msg.msg_num)
- rv = 0;
-done:
- free(cmsg_data);
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_timeval(void)
-{
- return (t_generic(t_timeval_client, t_timeval_server));
-}
-
-static int
-t_bintime_client(int fd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- void *cmsg_data;
- size_t cmsg_size;
- int rv;
-
- if (sync_recv() < 0)
- return (-2);
-
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct bintime));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
- msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
- SCM_BINTIME, sizeof(struct bintime));
-
- if (socket_connect(fd) < 0)
- goto done;
-
- if (message_sendn(fd, &msghdr) < 0)
- goto done;
-
- rv = 0;
-done:
- free(cmsg_data);
- return (rv);
-}
-
-static int
-t_bintime_server(int fd1)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data;
- size_t cmsg_size;
- u_int i;
- int fd2, rv;
-
- if (sync_send() < 0)
- return (-2);
-
- fd2 = -1;
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct bintime));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- rv = -1;
- for (i = 1; i <= ipc_msg.msg_num; ++i) {
- dbgmsg("message #%u", i);
-
- msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
- if (message_recv(fd2, &msghdr) < 0) {
- rv = -2;
- break;
- }
-
- if (check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
- break;
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (check_scm_bintime(cmsghdr) < 0)
- break;
- }
- if (i > ipc_msg.msg_num)
- rv = 0;
-done:
- free(cmsg_data);
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_bintime(void)
-{
- return (t_generic(t_bintime_client, t_bintime_server));
-}
-
-static int
-t_cmsg_len_client(int fd)
-{
- struct msghdr msghdr;
- struct iovec iov[1];
- struct cmsghdr *cmsghdr;
- void *cmsg_data;
- size_t size, cmsg_size;
- socklen_t socklen;
- int rv;
-
- if (sync_recv() < 0)
- return (-2);
-
- rv = -2;
-
- cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
- cmsg_data = malloc(cmsg_size);
- if (cmsg_data == NULL) {
- logmsg("malloc");
- goto done;
- }
- msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
- SCM_CREDS, sizeof(struct cmsgcred));
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
-
- if (socket_connect(fd) < 0)
- goto done;
-
- size = msghdr.msg_iov != NULL ? msghdr.msg_iov->iov_len : 0;
- rv = -1;
- for (socklen = 0; socklen < CMSG_LEN(0); ++socklen) {
- cmsghdr->cmsg_len = socklen;
- dbgmsg("send: data size %zu", size);
- dbgmsg("send: msghdr.msg_controllen %u",
- (u_int)msghdr.msg_controllen);
- dbgmsg("send: cmsghdr.cmsg_len %u",
- (u_int)cmsghdr->cmsg_len);
- if (sendmsg(fd, &msghdr, 0) < 0)
- continue;
- logmsgx("sent message with cmsghdr.cmsg_len %u < %u",
- (u_int)cmsghdr->cmsg_len, (u_int)CMSG_LEN(0));
- break;
- }
- if (socklen == CMSG_LEN(0))
- rv = 0;
-
- if (sync_send() < 0) {
- rv = -2;
- goto done;
- }
-done:
- free(cmsg_data);
- return (rv);
-}
-
-static int
-t_cmsg_len_server(int fd1)
-{
- int fd2, rv;
-
- if (sync_send() < 0)
- return (-2);
-
- rv = -2;
-
- if (sock_type == SOCK_STREAM) {
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- goto done;
- } else
- fd2 = fd1;
-
- if (sync_recv() < 0)
- goto done;
-
- rv = 0;
-done:
- if (sock_type == SOCK_STREAM && fd2 >= 0)
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_cmsg_len(void)
-{
- return (t_generic(t_cmsg_len_client, t_cmsg_len_server));
-}
-
-static int
-t_peercred_client(int fd)
-{
- struct xucred xucred;
- socklen_t len;
-
- if (sync_recv() < 0)
- return (-1);
-
- if (socket_connect(fd) < 0)
- return (-1);
-
- len = sizeof(xucred);
- if (getsockopt(fd, 0, LOCAL_PEERCRED, &xucred, &len) < 0) {
- logmsg("getsockopt(LOCAL_PEERCRED)");
- return (-1);
- }
-
- if (check_xucred(&xucred, len) < 0)
- return (-1);
-
- return (0);
-}
-
-static int
-t_peercred_server(int fd1)
-{
- struct xucred xucred;
- socklen_t len;
- int fd2, rv;
-
- if (sync_send() < 0)
- return (-2);
-
- fd2 = socket_accept(fd1);
- if (fd2 < 0)
- return (-2);
-
- len = sizeof(xucred);
- if (getsockopt(fd2, 0, LOCAL_PEERCRED, &xucred, &len) < 0) {
- logmsg("getsockopt(LOCAL_PEERCRED)");
- rv = -2;
- goto done;
- }
-
- if (check_xucred(&xucred, len) < 0) {
- rv = -1;
- goto done;
- }
-
- rv = 0;
-done:
- if (socket_close(fd2) < 0)
- rv = -2;
- return (rv);
-}
-
-static int
-t_peercred(void)
-{
- return (t_generic(t_peercred_client, t_peercred_server));
-}
diff --git a/tests/sys/sockets/unix_cmsg_test.sh b/tests/sys/sockets/unix_cmsg_test.sh
deleted file mode 100644
index c4a0b34..0000000
--- a/tests/sys/sockets/unix_cmsg_test.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cmd=`echo $0 | sed -e 's,_test$,,'`
-
-IFS=
-n=0
-
-run()
-{
- result=`${cmd} -t $2 $3 ${5%% *} 2>&1`
- if [ $? -ne 0 ]; then
- echo -n "not "
- fi
- echo "ok $1 - $4 ${5#* }"
- echo ${result} | grep -E "SERVER|CLIENT" | while read line; do
- echo "# ${line}"
- done
-}
-
-echo "1..47"
-
-for t1 in \
- "1 Sending, receiving cmsgcred" \
- "4 Sending cmsgcred, receiving sockcred" \
- "5 Sending, receiving timeval" \
- "6 Sending, receiving bintime" \
- "7 Check cmsghdr.cmsg_len"
-do
- for t2 in \
- "0 " \
- "1 (no data)" \
- "2 (no array)" \
- "3 (no data, array)"
- do
- n=$((n + 1))
- run ${n} stream "-z ${t2%% *}" STREAM "${t1} ${t2#* }"
- done
-done
-
-for t1 in \
- "2 Receiving sockcred (listening socket)" \
- "3 Receiving sockcred (accepted socket)"
-do
- for t2 in \
- "0 " \
- "1 (no data)"
- do
- n=$((n + 1))
- run ${n} stream "-z ${t2%% *}" STREAM "${t1} ${t2#* }"
- done
-done
-
-n=$((n + 1))
-run ${n} stream "-z 0" STREAM "8 Check LOCAL_PEERCRED socket option"
-
-for t1 in \
- "1 Sending, receiving cmsgcred" \
- "3 Sending cmsgcred, receiving sockcred" \
- "4 Sending, receiving timeval" \
- "5 Sending, receiving bintime" \
- "6 Check cmsghdr.cmsg_len"
-do
- for t2 in \
- "0 " \
- "1 (no data)" \
- "2 (no array)" \
- "3 (no data, array)"
- do
- n=$((n + 1))
- run ${n} dgram "-z ${t2%% *}" DGRAM "${t1} ${t2#* }"
- done
-done
-
-for t1 in \
- "2 Receiving sockcred"
-do
- for t2 in \
- "0 " \
- "1 (no data)"
- do
- n=$((n + 1))
- run ${n} dgram "-z ${t2%% *}" DGRAM "${t1} ${t2#* }"
- done
-done
diff --git a/tests/sys/sockets/unix_gc_test.c b/tests/sys/sockets/unix_gc_test.c
deleted file mode 100644
index 8cae2d9..0000000
--- a/tests/sys/sockets/unix_gc_test.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*-
- * Copyright (c) 2007 Robert N. M. Watson
- * 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$
- */
-
-/*
- * A few regression tests for UNIX domain sockets. Run from single-user mode
- * as it checks the openfiles sysctl to look for leaks, and we don't want that
- * changing due to other processes doing stuff.
- */
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-
-#include <netinet/in.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int forcegc = 1;
-static char dpath[PATH_MAX];
-static const char *test;
-
-static int
-getsysctl(const char *name)
-{
- size_t len;
- int i;
-
- len = sizeof(i);
- if (sysctlbyname(name, &i, &len, NULL, 0) < 0)
- err(-1, "%s", name);
- return (i);
-}
-
-static int
-getopenfiles(void)
-{
-
- return (getsysctl("kern.openfiles"));
-}
-
-static int
-getinflight(void)
-{
-
- return (getsysctl("net.local.inflight"));
-}
-
-static int
-getdeferred(void)
-{
-
- return (getsysctl("net.local.deferred"));
-}
-
-static void
-sendfd(int fd, int fdtosend)
-{
- struct msghdr mh;
- struct message { struct cmsghdr msg_hdr; int fd; } m;
- ssize_t len;
- int after_inflight, before_inflight;
-
- before_inflight = getinflight();
-
- bzero(&mh, sizeof(mh));
- bzero(&m, sizeof(m));
- mh.msg_control = &m;
- mh.msg_controllen = sizeof(m);
- m.msg_hdr.cmsg_len = sizeof(m);
- m.msg_hdr.cmsg_level = SOL_SOCKET;
- m.msg_hdr.cmsg_type = SCM_RIGHTS;
- m.fd = fdtosend;
- len = sendmsg(fd, &mh, 0);
- if (len < 0)
- err(-1, "%s: sendmsg", test);
- after_inflight = getinflight();
- if (after_inflight != before_inflight + 1)
- errx(-1, "%s: sendfd: before %d after %d\n", test,
- before_inflight, after_inflight);
-}
-
-static void
-close2(int fd1, int fd2)
-{
-
- close(fd1);
- close(fd2);
-}
-
-static void
-close3(int fd1, int fd2, int fd3)
-{
-
- close2(fd1, fd2);
- close(fd3);
-}
-
-static void
-close4(int fd1, int fd2, int fd3, int fd4)
-{
-
- close2(fd1, fd2);
- close2(fd3, fd4);
-}
-
-static void
-close5(int fd1, int fd2, int fd3, int fd4, int fd5)
-{
-
- close3(fd1, fd2, fd3);
- close2(fd4, fd5);
-}
-
-static int
-my_socket(int domain, int type, int proto)
-{
- int sock;
-
- sock = socket(domain, type, proto);
- if (sock < 0)
- err(-1, "%s: socket", test);
- return (sock);
-}
-
-static void
-my_bind(int sock, struct sockaddr *sa, socklen_t len)
-{
-
- if (bind(sock, sa, len) < 0)
- err(-1, "%s: bind", test);
-}
-
-static void
-my_connect(int sock, struct sockaddr *sa, socklen_t len)
-{
-
- if (connect(sock, sa, len) < 0 && errno != EINPROGRESS)
- err(-1, "%s: connect", test);
-}
-
-static void
-my_listen(int sock, int backlog)
-{
-
- if (listen(sock, backlog) < 0)
- err(-1, "%s: listen", test);
-}
-
-static void
-my_socketpair(int *sv)
-{
-
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0)
- err(-1, "%s: socketpair", test);
-}
-
-static void
-my_getsockname(int s, struct sockaddr *sa, socklen_t *salen)
-{
-
- if (getsockname(s, sa, salen) < 0)
- err(-1, "%s: getsockname", test);
-}
-
-static void
-setnonblock(int s)
-{
-
- if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
- err(-1, "%s: fcntl(F_SETFL, O_NONBLOCK)", test);
-}
-
-static void
-alloc3fds(int *s, int *sv)
-{
-
- if ((*s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- err(-1, "%s: socket", test);
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0)
- err(-1, "%s: socketpair", test);
-}
-
-static void
-alloc5fds(int *s, int *sva, int *svb)
-{
-
- if ((*s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- err(-1, "%s: socket", test);
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sva) < 0)
- err(-1, "%s: socketpair", test);
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, svb) < 0)
- err(-1, "%s: socketpair", test);
-}
-
-static void
-save_sysctls(int *before_inflight, int *before_openfiles)
-{
-
- *before_inflight = getinflight();
- *before_openfiles = getopenfiles();
-}
-
-/*
- * Try hard to make sure that the GC does in fact run before we test the
- * condition of things.
- */
-static void
-trigger_gc(void)
-{
- int s;
-
- if (forcegc) {
- if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- err(-1, "trigger_gc: socket");
- close(s);
- }
- sleep(1);
-}
-
-static void
-test_sysctls(int before_inflight, int before_openfiles)
-{
- int after_inflight, after_openfiles;
-
- trigger_gc();
- after_inflight = getinflight();
- if (after_inflight != before_inflight)
- warnx("%s: before inflight: %d, after inflight: %d",
- test, before_inflight, after_inflight);
-
- after_openfiles = getopenfiles();
- if (after_openfiles != before_openfiles)
- warnx("%s: before: %d, after: %d", test, before_openfiles,
- after_openfiles);
-}
-
-static void
-twosome_nothing(void)
-{
- int inflight, openfiles;
- int sv[2];
-
- /*
- * Create a pair, close in one order.
- */
- test = "twosome_nothing1";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- my_socketpair(sv);
- close2(sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-
- /*
- * Create a pair, close in the other order.
- */
- test = "twosome_nothing2";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- my_socketpair(sv);
- close2(sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * Using a socket pair, send various endpoints over the pair and close in
- * various orders.
- */
-static void
-twosome_drop_work(const char *testname, int sendvia, int tosend, int closefirst)
-{
- int inflight, openfiles;
- int sv[2];
-
- printf("%s\n", testname);
- test = testname;
- save_sysctls(&inflight, &openfiles);
- my_socketpair(sv);
- sendfd(sv[sendvia], sv[tosend]);
- if (closefirst == 0)
- close2(sv[0], sv[1]);
- else
- close2(sv[1], sv[0]);
- test_sysctls(inflight, openfiles);
-}
-
-static void
-twosome_drop(void)
-{
-
- /*
- * In various combations, some wastefully symmetric, create socket
- * pairs and send one or another endpoint over one or another
- * endpoint, closing the endpoints in various orders.
- */
- twosome_drop_work("twosome_drop1", 0, 0, 0);
- twosome_drop_work("twosome_drop2", 0, 0, 1);
- twosome_drop_work("twosome_drop3", 0, 1, 0);
- twosome_drop_work("twosome_drop4", 0, 1, 1);
- twosome_drop_work("twosome_drop5", 1, 0, 0);
- twosome_drop_work("twosome_drop6", 1, 0, 1);
- twosome_drop_work("twosome_drop7", 1, 1, 0);
- twosome_drop_work("twosome_drop8", 1, 1, 1);
-}
-
-static void
-threesome_nothing(void)
-{
- int inflight, openfiles;
- int s, sv[2];
-
- test = "threesome_nothing";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- close3(s, sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * threesome_drop: create a pair and a spare, send the spare over the pair, and
- * close in various orders and make sure all the fds went away.
- */
-static void
-threesome_drop(void)
-{
- int inflight, openfiles;
- int s, sv[2];
-
- /*
- * threesome_drop1: close sent send receive
- */
- test = "threesome_drop1";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- sendfd(sv[0], s);
- close3(s, sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-
- /*
- * threesome_drop2: close sent receive send
- */
- test = "threesome_drop2";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- sendfd(sv[0], s);
- close3(s, sv[1], sv[0]);
- test_sysctls(inflight, openfiles);
-
- /*
- * threesome_drop3: close receive sent send
- */
- test = "threesome_drop3";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- sendfd(sv[0], s);
- close3(sv[1], s, sv[0]);
- test_sysctls(inflight, openfiles);
-
- /*
- * threesome_drop4: close receive send sent
- */
- test = "threesome_drop4";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- sendfd(sv[0], s);
- close3(sv[1], sv[0], s);
- test_sysctls(inflight, openfiles);
-
- /*
- * threesome_drop5: close send receive sent
- */
- test = "threesome_drop5";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- sendfd(sv[0], s);
- close3(sv[0], sv[1], s);
- test_sysctls(inflight, openfiles);
-
- /*
- * threesome_drop6: close send sent receive
- */
- test = "threesome_drop6";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc3fds(&s, sv);
- close3(sv[0], s, sv[1]);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * Fivesome tests: create two socket pairs and a spare, send the spare over
- * the first socket pair, then send the first socket pair over the second
- * socket pair, and GC. Do various closes at various points to exercise
- * various cases.
- */
-static void
-fivesome_nothing(void)
-{
- int inflight, openfiles;
- int spare, sva[2], svb[2];
-
- test = "fivesome_nothing";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc5fds(&spare, sva, svb);
- close5(spare, sva[0], sva[1], svb[0], svb[1]);
- test_sysctls(inflight, openfiles);
-}
-
-static void
-fivesome_drop_work(const char *testname, int close_spare_after_send,
- int close_sva_after_send)
-{
- int inflight, openfiles;
- int spare, sva[2], svb[2];
-
- printf("%s\n", testname);
- test = testname;
- save_sysctls(&inflight, &openfiles);
- alloc5fds(&spare, sva, svb);
-
- /*
- * Send spare over sva.
- */
- sendfd(sva[0], spare);
- if (close_spare_after_send)
- close(spare);
-
- /*
- * Send sva over svb.
- */
- sendfd(svb[0], sva[0]);
- sendfd(svb[0], sva[1]);
- if (close_sva_after_send)
- close2(sva[0], sva[1]);
-
- close2(svb[0], svb[1]);
-
- if (!close_sva_after_send)
- close2(sva[0], sva[1]);
- if (!close_spare_after_send)
- close(spare);
-
- test_sysctls(inflight, openfiles);
-}
-
-static void
-fivesome_drop(void)
-{
-
- fivesome_drop_work("fivesome_drop1", 0, 0);
- fivesome_drop_work("fivesome_drop2", 0, 1);
- fivesome_drop_work("fivesome_drop3", 1, 0);
- fivesome_drop_work("fivesome_drop4", 1, 1);
-}
-
-/*
- * Create a somewhat nasty dual-socket socket intended to upset the garbage
- * collector if mark-and-sweep is wrong.
- */
-static void
-complex_cycles(void)
-{
- int inflight, openfiles;
- int spare, sva[2], svb[2];
-
- test = "complex_cycles";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- alloc5fds(&spare, sva, svb);
- sendfd(sva[0], svb[0]);
- sendfd(sva[0], svb[1]);
- sendfd(svb[0], sva[0]);
- sendfd(svb[0], sva[1]);
- sendfd(svb[0], spare);
- sendfd(sva[0], spare);
- close5(spare, sva[0], sva[1], svb[0], svb[1]);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * Listen sockets can also be passed over UNIX domain sockets, so test
- * various cases, including ones where listen sockets have waiting sockets
- * hanging off them...
- */
-static void
-listen_nothing(void)
-{
- struct sockaddr_un sun;
- struct sockaddr_in sin;
- int inflight, openfiles;
- int s;
-
- test = "listen_nothing_unp";
- printf("%s\n", test);
- bzero(&sun, sizeof(sun));
- sun.sun_family = AF_LOCAL;
- sun.sun_len = sizeof(sun);
- snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
- my_listen(s, -1);
- close(s);
- (void)unlink(sun.sun_path);
- test_sysctls(inflight, openfiles);
-
- test = "listen_nothing_inet";
- printf("%s\n", test);
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(0);
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_INET, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
- my_listen(s, -1);
- close(s);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * Send a listen UDP socket over a UNIX domain socket.
- *
- * Send a listen TCP socket over a UNIX domain socket.
- *
- * Do each twice, with closing of the listen socket vs. socketpair in
- * different orders.
- */
-static void
-listen_drop(void)
-{
- struct sockaddr_un sun;
- struct sockaddr_in sin;
- int inflight, openfiles;
- int s, sv[2];
-
- bzero(&sun, sizeof(sun));
- sun.sun_family = AF_LOCAL;
- sun.sun_len = sizeof(sun);
-
- /*
- * Close listen socket first.
- */
- test = "listen_drop_unp1";
- printf("%s\n", test);
- snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
- my_listen(s, -1);
- my_socketpair(sv);
- sendfd(sv[0], s);
- close3(s, sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-
- /*
- * Close socketpair first.
- */
- test = "listen_drop_unp2";
- printf("%s\n", test);
- snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
- my_listen(s, -1);
- my_socketpair(sv);
- sendfd(sv[0], s);
- close3(sv[0], sv[1], s);
- test_sysctls(inflight, openfiles);
-
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(0);
-
- /*
- * Close listen socket first.
- */
- test = "listen_drop_inet1";
- printf("%s\n", test);
- bzero(&sun, sizeof(sun));
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_INET, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
- my_listen(s, -1);
- my_socketpair(sv);
- sendfd(sv[0], s);
- close3(s, sv[0], sv[1]);
- test_sysctls(inflight, openfiles);
-
- /*
- * Close socketpair first.
- */
- test = "listen_drop_inet2";
- printf("%s\n", test);
- bzero(&sun, sizeof(sun));
- save_sysctls(&inflight, &openfiles);
- s = my_socket(PF_INET, SOCK_STREAM, 0);
- my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
- my_listen(s, -1);
- my_socketpair(sv);
- sendfd(sv[0], s);
- close3(sv[0], sv[1], s);
- test_sysctls(inflight, openfiles);
-}
-
-/*
- * Up things a notch with listen sockets: add connections that can be
- * accepted to the listen queues.
- */
-static void
-listen_connect_nothing(void)
-{
- struct sockaddr_in sin;
- int slisten, sconnect, sv[2];
- int inflight, openfiles;
- socklen_t len;
-
- test = "listen_connect_nothing";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
-
- slisten = my_socket(PF_INET, SOCK_STREAM, 0);
- my_bind(slisten, (struct sockaddr *)&sin, sizeof(sin));
- my_listen(slisten, -1);
-
- my_socketpair(sv);
-
- len = sizeof(sin);
- my_getsockname(slisten, (struct sockaddr *)&sin, &len);
-
- sconnect = my_socket(PF_INET, SOCK_STREAM, 0);
- setnonblock(sconnect);
- my_connect(sconnect, (struct sockaddr *)&sin, len);
-
- sleep(1);
-
- close4(slisten, sconnect, sv[0], sv[1]);
-
- test_sysctls(inflight, openfiles);
-}
-
-static void
-listen_connect_drop(void)
-{
- struct sockaddr_in sin;
- int slisten, sconnect, sv[2];
- int inflight, openfiles;
- socklen_t len;
-
- test = "listen_connect_drop";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
-
- slisten = my_socket(PF_INET, SOCK_STREAM, 0);
- my_bind(slisten, (struct sockaddr *)&sin, sizeof(sin));
- my_listen(slisten, -1);
-
- my_socketpair(sv);
-
- len = sizeof(sin);
- my_getsockname(slisten, (struct sockaddr *)&sin, &len);
-
- sconnect = my_socket(PF_INET, SOCK_STREAM, 0);
- setnonblock(sconnect);
- my_connect(sconnect, (struct sockaddr *)&sin, len);
-
- sleep(1);
- sendfd(sv[0], slisten);
- close3(slisten, sv[0], sv[1]);
- sleep(1);
- close(sconnect);
-
- test_sysctls(inflight, openfiles);
-}
-
-static void
-recursion(void)
-{
- int fd[2], ff[2];
- int inflight, openfiles, deferred, deferred1;
-
- test = "recursion";
- printf("%s\n", test);
- save_sysctls(&inflight, &openfiles);
- deferred = getdeferred();
-
- my_socketpair(fd);
-
- for (;;) {
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, ff) == -1) {
- if (errno == EMFILE || errno == ENFILE)
- break;
- err(-1, "socketpair");
- }
- sendfd(ff[0], fd[0]);
- sendfd(ff[0], fd[1]);
- close2(fd[1], fd[0]);
- fd[0] = ff[0];
- fd[1] = ff[1];
- }
- close2(fd[0], fd[1]);
- sleep(1);
- test_sysctls(inflight, openfiles);
- deferred1 = getdeferred();
- if (deferred != deferred1)
- errx(-1, "recursion: deferred before %d after %d", deferred,
- deferred1);
-}
-
-#define RMDIR "rm -Rf "
-int
-main(int argc, char *argv[])
-{
- char cmd[sizeof(RMDIR) + PATH_MAX];
- int serrno;
- pid_t pid;
-
- strlcpy(dpath, "/tmp/unpgc.XXXXXXXX", sizeof(dpath));
- if (mkdtemp(dpath) == NULL)
- err(-1, "mkdtemp");
-
- /*
- * Set up a parent process to GC temporary storage when we're done.
- */
- pid = fork();
- if (pid < 0) {
- serrno = errno;
- (void)rmdir(dpath);
- errno = serrno;
- err(-1, "fork");
- }
- if (pid > 0) {
- signal(SIGINT, SIG_IGN);
- while (waitpid(pid, NULL, 0) != pid);
- snprintf(cmd, sizeof(cmd), "%s %s", RMDIR, dpath);
- (void)system(cmd);
- exit(0);
- }
-
- printf("Start: inflight %d open %d\n", getinflight(),
- getopenfiles());
-
- twosome_nothing();
- twosome_drop();
-
- threesome_nothing();
- threesome_drop();
-
- fivesome_nothing();
- fivesome_drop();
-
- complex_cycles();
-
- listen_nothing();
- listen_drop();
-
- listen_connect_nothing();
- listen_connect_drop();
-
- recursion();
-
- printf("Finish: inflight %d open %d\n", getinflight(),
- getopenfiles());
- return (0);
-}
diff --git a/tests/sys/sockets/unix_passfd_test.c b/tests/sys/sockets/unix_passfd_test.c
deleted file mode 100644
index 07ef589..0000000
--- a/tests/sys/sockets/unix_passfd_test.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*-
- * Copyright (c) 2005 Robert N. M. Watson
- * 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/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/*
- * UNIX domain sockets allow file descriptors to be passed via "ancillary
- * data", or control messages. This regression test is intended to exercise
- * this facility, both performing some basic tests that it operates, and also
- * causing some kernel edge cases to execute, such as garbage collection when
- * there are cyclic file descriptor references. Right now we test only with
- * stream sockets, but ideally we'd also test with datagram sockets.
- */
-
-static void
-domainsocketpair(const char *test, int *fdp)
-{
-
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdp) < 0)
- err(-1, "%s: socketpair(PF_UNIX, SOCK_STREAM)", test);
-}
-
-static void
-closesocketpair(int *fdp)
-{
-
- close(fdp[0]);
- close(fdp[1]);
-}
-
-static void
-devnull(const char *test, int *fdp)
-{
- int fd;
-
- fd = open("/dev/null", O_RDONLY);
- if (fd < 0)
- err(-1, "%s: open(/dev/null)", test);
- *fdp = fd;
-}
-
-static void
-tempfile(const char *test, int *fdp)
-{
- char path[PATH_MAX];
- int fd;
-
- snprintf(path, PATH_MAX, "/tmp/unix_passfd.XXXXXXXXXXXXXXX");
- fd = mkstemp(path);
- if (fd < 0)
- err(-1, "%s: mkstemp(%s)", test, path);
- (void)unlink(path);
- *fdp = fd;
-}
-
-static void
-dofstat(const char *test, int fd, struct stat *sb)
-{
-
- if (fstat(fd, sb) < 0)
- err(-1, "%s: fstat", test);
-}
-
-static void
-samefile(const char *test, struct stat *sb1, struct stat *sb2)
-{
-
- if (sb1->st_dev != sb2->st_dev)
- errx(-1, "%s: samefile: different device", test);
- if (sb1->st_ino != sb2->st_ino)
- errx(-1, "%s: samefile: different inode", test);
-}
-
-static void
-sendfd_payload(const char *test, int sockfd, int sendfd,
- void *payload, size_t paylen)
-{
- struct iovec iovec;
- char message[CMSG_SPACE(sizeof(int))];
- struct cmsghdr *cmsghdr;
- struct msghdr msghdr;
- ssize_t len;
-
- bzero(&msghdr, sizeof(msghdr));
- bzero(&message, sizeof(message));
-
- msghdr.msg_control = message;
- msghdr.msg_controllen = sizeof(message);
-
- iovec.iov_base = payload;
- iovec.iov_len = paylen;
-
- msghdr.msg_iov = &iovec;
- msghdr.msg_iovlen = 1;
-
- cmsghdr = (struct cmsghdr *)message;
- cmsghdr->cmsg_len = CMSG_LEN(sizeof(int));
- cmsghdr->cmsg_level = SOL_SOCKET;
- cmsghdr->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA(cmsghdr) = sendfd;
-
- len = sendmsg(sockfd, &msghdr, 0);
- if (len < 0)
- err(-1, "%s: sendmsg", test);
- if ((size_t)len != paylen)
- errx(-1, "%s: sendmsg: %zd bytes sent", test, len);
-}
-
-static void
-sendfd(const char *test, int sockfd, int sendfd)
-{
- char ch;
-
- return (sendfd_payload(test, sockfd, sendfd, &ch, sizeof(ch)));
-}
-
-static void
-recvfd_payload(const char *test, int sockfd, int *recvfd,
- void *buf, size_t buflen)
-{
- struct cmsghdr *cmsghdr;
- char message[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + sizeof(int)];
- struct msghdr msghdr;
- struct iovec iovec;
- ssize_t len;
-
- bzero(&msghdr, sizeof(msghdr));
-
- msghdr.msg_control = message;
- msghdr.msg_controllen = sizeof(message);
-
- iovec.iov_base = buf;
- iovec.iov_len = buflen;
-
- msghdr.msg_iov = &iovec;
- msghdr.msg_iovlen = 1;
-
- len = recvmsg(sockfd, &msghdr, 0);
- if (len < 0)
- err(-1, "%s: recvmsg", test);
- if ((size_t)len != buflen)
- errx(-1, "%s: recvmsg: %zd bytes received", test, len);
-
- cmsghdr = CMSG_FIRSTHDR(&msghdr);
- if (cmsghdr == NULL)
- errx(-1, "%s: recvmsg: did not receive control message", test);
- *recvfd = -1;
- for (; cmsghdr != NULL; cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) {
- if (cmsghdr->cmsg_level == SOL_SOCKET &&
- cmsghdr->cmsg_type == SCM_RIGHTS &&
- cmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) {
- *recvfd = *(int *)CMSG_DATA(cmsghdr);
- if (*recvfd == -1)
- errx(-1, "%s: recvmsg: received fd -1", test);
- }
- }
- if (*recvfd == -1)
- errx(-1, "%s: recvmsg: did not receive single-fd message",
- test);
-}
-
-static void
-recvfd(const char *test, int sockfd, int *recvfd)
-{
- char ch;
-
- return (recvfd_payload(test, sockfd, recvfd, &ch, sizeof(ch)));
-}
-
-int
-main(void)
-{
- struct stat putfd_1_stat, putfd_2_stat, getfd_1_stat, getfd_2_stat;
- int fd[2], putfd_1, putfd_2, getfd_1, getfd_2;
- const char *test;
-
- /*
- * First test: put a temporary file into a UNIX domain socket, then
- * take it out and make sure it's the same file. First time around,
- * don't close the reference after sending.
- */
- test = "test1-simplesendfd";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- tempfile(test, &putfd_1);
- dofstat(test, putfd_1, &putfd_1_stat);
- sendfd(test, fd[0], putfd_1);
- recvfd(test, fd[1], &getfd_1);
- dofstat(test, getfd_1, &getfd_1_stat);
- samefile(test, &putfd_1_stat, &getfd_1_stat);
- close(putfd_1);
- close(getfd_1);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Second test: same as first, only close the file reference after
- * sending, so that the only reference is the descriptor in the UNIX
- * domain socket buffer.
- */
- test = "test2-sendandclose";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- tempfile(test, &putfd_1);
- dofstat(test, putfd_1, &putfd_1_stat);
- sendfd(test, fd[0], putfd_1);
- close(putfd_1);
- recvfd(test, fd[1], &getfd_1);
- dofstat(test, getfd_1, &getfd_1_stat);
- samefile(test, &putfd_1_stat, &getfd_1_stat);
- close(getfd_1);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Third test: put a temporary file into a UNIX domain socket, then
- * close both endpoints causing garbage collection to kick off.
- */
- test = "test3-sendandcancel";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- tempfile(test, &putfd_1);
- sendfd(test, fd[0], putfd_1);
- close(putfd_1);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Send two files. Then receive them. Make sure they are returned
- * in the right order, and both get there.
- */
-
- test = "test4-twofile";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- tempfile(test, &putfd_1);
- tempfile(test, &putfd_2);
- dofstat(test, putfd_1, &putfd_1_stat);
- dofstat(test, putfd_2, &putfd_2_stat);
- sendfd(test, fd[0], putfd_1);
- sendfd(test, fd[0], putfd_2);
- close(putfd_1);
- close(putfd_2);
- recvfd(test, fd[1], &getfd_1);
- recvfd(test, fd[1], &getfd_2);
- dofstat(test, getfd_1, &getfd_1_stat);
- dofstat(test, getfd_2, &getfd_2_stat);
- samefile(test, &putfd_1_stat, &getfd_1_stat);
- samefile(test, &putfd_2_stat, &getfd_2_stat);
- close(getfd_1);
- close(getfd_2);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Big bundling test. Send an endpoint of the UNIX domain socket
- * over itself, closing the door behind it.
- */
-
- test = "test5-bundle";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
-
- sendfd(test, fd[0], fd[0]);
- close(fd[0]);
- recvfd(test, fd[1], &getfd_1);
- close(getfd_1);
- close(fd[1]);
-
- printf("%s passed\n", test);
-
- /*
- * Big bundling test part two: Send an endpoint of the UNIX domain
- * socket over itself, close the door behind it, and never remove it
- * from the other end.
- */
-
- test = "test6-bundlecancel";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- sendfd(test, fd[0], fd[0]);
- sendfd(test, fd[1], fd[0]);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Test for PR 151758: Send an character device over the UNIX
- * domain socket and then close both sockets to orphan the
- * device.
- */
-
- test = "test7-devfsorphan";
- printf("beginning %s\n", test);
-
- domainsocketpair(test, fd);
- devnull(test, &putfd_1);
- sendfd(test, fd[0], putfd_1);
- close(putfd_1);
- closesocketpair(fd);
-
- printf("%s passed\n", test);
-
- /*
- * Test for PR 181741. Receiver sets LOCAL_CREDS, and kernel
- * prepends a control message to the data. Sender sends large
- * payload. Payload + SCM_RIGHTS + LOCAL_CREDS hit socket buffer
- * limit, and receiver receives truncated data.
- */
- test = "test8-rights+creds+payload";
- printf("beginning %s\n", test);
-
- {
- const int on = 1;
- u_long sendspace;
- size_t len;
- void *buf;
-
- len = sizeof(sendspace);
- if (sysctlbyname("net.local.stream.sendspace", &sendspace,
- &len, NULL, 0) < 0)
- err(-1, "%s: sysctlbyname(net.local.stream.sendspace)",
- test);
-
- if ((buf = malloc(sendspace)) == NULL)
- err(-1, "%s: malloc", test);
-
- domainsocketpair(test, fd);
- if (setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on)) < 0)
- err(-1, "%s: setsockopt(LOCAL_CREDS)", test);
- tempfile(test, &putfd_1);
- sendfd_payload(test, fd[0], putfd_1, buf, sendspace);
- recvfd_payload(test, fd[1], &getfd_1, buf, sendspace);
- close(putfd_1);
- close(getfd_1);
- closesocketpair(fd);
- }
-
- printf("%s passed\n", test);
-
- return (0);
-}
diff --git a/tests/sys/sockets/unix_sendtorace_test.c b/tests/sys/sockets/unix_sendtorace_test.c
deleted file mode 100644
index 9fd748d..0000000
--- a/tests/sys/sockets/unix_sendtorace_test.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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$
- */
-
-/*
- * Attempts to exercise UNIX domain socket races relating to the non-atomic
- * connect-and-send properties of sendto(). As the result of such a race is
- * a kernel panic, this test simply completes or doesn't.
- *
- * XXX: Despite implementing support for sendto() on stream sockets with
- * implied connect, the appropriate flag isn't set in the FreeBSD kernel so
- * it does not work. For now, don't call the stream test.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ITERATIONS 1000000
-
-static char socket_path[] = "tmp.XXXXXX";
-
-static void
-stream_server(int listenfd)
-{
- int acceptfd;
-
- while (1) {
- acceptfd = accept(listenfd, NULL, NULL);
- if (acceptfd < 0) {
- warn("stream_server: accept");
- continue;
- }
- sleep(1);
- close(acceptfd);
- }
-}
-
-static void
-stream_client(void)
-{
- struct sockaddr_un sun;
- ssize_t len;
- char c = 0;
- int fd, i;
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- strcpy(sun.sun_path, socket_path);
- for (i = 0; i < ITERATIONS; i++) {
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- warn("stream_client: socket");
- return;
- }
- len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,
- sizeof(sun));
- if (len < 0)
- warn("stream_client: sendto");
- close(fd);
- }
-}
-
-static void
-stream_test(void)
-{
- struct sockaddr_un sun;
- pid_t childpid;
- int listenfd;
-
- listenfd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (listenfd < 0)
- err(-1, "stream_test: socket");
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- strcpy(sun.sun_path, socket_path);
-
- if (bind(listenfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
- err(-1, "stream_test: bind");
-
- if (listen(listenfd, -1) < 0)
- err(-1, "stream_test: listen");
-
- childpid = fork();
- if (childpid < 0)
- err(-1, "stream_test: fork");
-
- if (childpid != 0) {
- sleep(1);
- stream_client();
- kill(childpid, SIGTERM);
- sleep(1);
- } else
- stream_server(listenfd);
-
- (void)unlink(socket_path);
-}
-
-static void
-datagram_server(int serverfd)
-{
- ssize_t len;
- char c;
-
- while (1) {
- len = recv(serverfd, &c, sizeof(c), 0);
- if (len < 0)
- warn("datagram_server: recv");
- }
-}
-
-static void
-datagram_client(void)
-{
- struct sockaddr_un sun;
- ssize_t len;
- char c = 0;
- int fd, i;
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- strcpy(sun.sun_path, socket_path);
- for (i = 0; i < ITERATIONS; i++) {
- fd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (fd < 0) {
- warn("datagram_client: socket");
- return;
- }
- len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,
- sizeof(sun));
- if (len < 0)
- warn("datagram_client: sendto");
- close(fd);
- }
-}
-
-static void
-datagram_test(void)
-{
- struct sockaddr_un sun;
- pid_t childpid;
- int serverfd;
-
- serverfd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (serverfd < 0)
- err(-1, "datagram_test: socket");
-
- bzero(&sun, sizeof(sun));
- sun.sun_len = sizeof(sun);
- sun.sun_family = AF_UNIX;
- strcpy(sun.sun_path, socket_path);
-
- if (bind(serverfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
- err(-1, "datagram_test: bind");
-
- childpid = fork();
- if (childpid < 0)
- err(-1, "datagram_test: fork");
-
- if (childpid != 0) {
- sleep(1);
- datagram_client();
- kill(childpid, SIGTERM);
- sleep(1);
- } else
- datagram_server(serverfd);
-
- (void)unlink(socket_path);
-}
-
-int
-main(void)
-{
-
- if (mkstemp(socket_path) == -1)
- err(1, "mkstemp failed");
- (void)unlink(socket_path);
- datagram_test();
- if (0)
- stream_test();
- return (0);
-}
diff --git a/tests/sys/sockets/unix_socket_test.c b/tests/sys/sockets/unix_socket_test.c
deleted file mode 100644
index 085366f..0000000
--- a/tests/sys/sockets/unix_socket_test.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 2006 Robert N. M. Watson
- * 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$
- */
-
-/*
- * Simple UNIX domain socket regression test: create and tear down various
- * supported and unsupported socket types.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <errno.h>
-#include <unistd.h>
-
-int
-main(void)
-{
- int sock, socks[2];
-
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0)
- err(-1, "socket(PF_LOCAL, SOCK_STREAM, 0)");
- close(sock);
-
- sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
- if (sock < 0)
- err(-1, "socket(PF_LOCAL, SOCK_DGRAM, 0)");
- close(sock);
-
- sock = socket(PF_LOCAL, SOCK_RAW, 0);
- if (sock >= 0) {
- close(sock);
- errx(-1, "socket(PF_LOCAL, SOCK_RAW, 0) returned %d", sock);
- }
- if (errno != EPROTONOSUPPORT)
- err(-1, "socket(PF_LOCAL, SOCK_RAW, 0)");
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, socks) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_STREAM, 0, socks)");
- if (socks[0] < 0)
- errx(-1, "socketpair(PF_LOCAL, SOCK_STREAM, 0, socks) [0] < 0");
- if (socks[1] < 0)
- errx(-1, "socketpair(PF_LOCAL, SOCK_STREAM, 0, socks) [1] < 1");
- close(socks[0]);
- close(socks[1]);
-
- if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, socks) < 0)
- err(-1, "socketpair(PF_LOCAL, SOCK_DGRAM, 0, socks)");
- if (socks[0] < 0)
- errx(-1, "socketpair(PF_LOCAL, SOCK_DGRAM, 0, socks) [0] < 0");
- if (socks[1] < 0)
- errx(-1, "socketpair(PF_LOCAL, SOCK_DGRAM, 0, socks) [1] < 1");
- close(socks[0]);
- close(socks[1]);
-
- return (0);
-}
diff --git a/tests/sys/sockets/unix_sorflush_test.c b/tests/sys/sockets/unix_sorflush_test.c
deleted file mode 100644
index e0deb00..0000000
--- a/tests/sys/sockets/unix_sorflush_test.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-
- * Copyright (c) 2008 Robert N. M. Watson
- * 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.
- */
-
-/*
- * Reproduce a race in which:
- *
- * - Process (a) is blocked in read on a socket waiting on data.
- * - Process (b) is blocked in shutdown() on a socket waiting on (a).
- * - Process (c) delivers a signal to (b) interrupting its wait.
- *
- * This race is premised on shutdown() not interrupting (a) properly, and the
- * signal to (b) causing problems in the kernel.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/socket.h>
-
-#include <err.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static void
-receive_and_exit(int s)
-{
- ssize_t ssize;
- char ch;
-
- ssize = recv(s, &ch, sizeof(ch), 0);
- if (ssize < 0)
- err(-1, "receive_and_exit: recv");
- exit(0);
-}
-
-static void
-shutdown_and_exit(int s)
-{
-
- if (shutdown(s, SHUT_RD) < 0)
- err(-1, "shutdown_and_exit: shutdown");
- exit(0);
-}
-
-int
-main(void)
-{
- pid_t pida, pidb;
- int sv[2];
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) < 0)
- err(-1, "socketpair");
-
- pida = fork();
- if (pida < 0)
- err(-1, "fork");
- if (pida == 0)
- receive_and_exit(sv[1]);
- sleep(1);
- pidb = fork();
- if (pidb < 0) {
- warn("fork");
- (void)kill(pida, SIGKILL);
- exit(-1);
- }
- if (pidb == 0)
- shutdown_and_exit(sv[1]);
- sleep(1);
- if (kill(pidb, SIGKILL) < 0)
- err(-1, "kill");
- sleep(1);
- printf("ok 1 - unix_sorflush\n");
- exit(0);
-}
diff --git a/tests/sys/sockets/zerosend_test.c b/tests/sys/sockets/zerosend_test.c
deleted file mode 100644
index 1f3217a..0000000
--- a/tests/sys/sockets/zerosend_test.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*-
- * Copyright (c) 2007 Robert N. M. Watson
- * 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 <sys/socket.h>
-#include <sys/stat.h>
-
-#include <netinet/in.h>
-
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#define PORT1 10001
-#define PORT2 10002
-
-static void
-try_0send(const char *test, int fd)
-{
- ssize_t len;
- char ch;
-
- ch = 0;
- len = send(fd, &ch, 0, 0);
- if (len < 0)
- err(-1, "%s: try_0send", test);
- if (len != 0)
- errx(-1, "%s: try_0send: returned %zd", test, len);
-}
-
-static void
-try_0write(const char *test, int fd)
-{
- ssize_t len;
- char ch;
-
- ch = 0;
- len = write(fd, &ch, 0);
- if (len < 0)
- err(-1, "%s: try_0write", test);
- if (len != 0)
- errx(-1, "%s: try_0write: returned %zd", test, len);
-}
-
-static void
-setup_udp(const char *test, int *fdp)
-{
- struct sockaddr_in sin;
- int sock1, sock2;
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- sin.sin_port = htons(PORT1);
- sock1 = socket(PF_INET, SOCK_DGRAM, 0);
- if (sock1 < 0)
- err(-1, "%s: setup_udp: socket", test);
- if (bind(sock1, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "%s: setup_udp: bind(%s, %d)", test,
- inet_ntoa(sin.sin_addr), PORT1);
- sin.sin_port = htons(PORT2);
- if (connect(sock1, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "%s: setup_udp: connect(%s, %d)", test,
- inet_ntoa(sin.sin_addr), PORT2);
-
- sock2 = socket(PF_INET, SOCK_DGRAM, 0);
- if (sock2 < 0)
- err(-1, "%s: setup_udp: socket", test);
- if (bind(sock2, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "%s: setup_udp: bind(%s, %d)", test,
- inet_ntoa(sin.sin_addr), PORT2);
- sin.sin_port = htons(PORT1);
- if (connect(sock2, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "%s: setup_udp: connect(%s, %d)", test,
- inet_ntoa(sin.sin_addr), PORT1);
-
- fdp[0] = sock1;
- fdp[1] = sock2;
-}
-
-static void
-setup_tcp(const char *test, int *fdp)
-{
- fd_set writefds, exceptfds;
- struct sockaddr_in sin;
- int ret, sock1, sock2, sock3;
- struct timeval tv;
-
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- /*
- * First set up the listen socket.
- */
- sin.sin_port = htons(PORT1);
- sock1 = socket(PF_INET, SOCK_STREAM, 0);
- if (sock1 < 0)
- err(-1, "%s: setup_tcp: socket", test);
- if (bind(sock1, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- err(-1, "%s: bind(%s, %d)", test, inet_ntoa(sin.sin_addr),
- PORT1);
- if (listen(sock1, -1) < 0)
- err(-1, "%s: listen", test);
-
- /*
- * Now connect to it, non-blocking so that we don't deadlock against
- * ourselves.
- */
- sock2 = socket(PF_INET, SOCK_STREAM, 0);
- if (sock2 < 0)
- err(-1, "%s: setup_tcp: socket", test);
- if (fcntl(sock2, F_SETFL, O_NONBLOCK) < 0)
- err(-1, "%s: setup_tcp: fcntl(O_NONBLOCK)", test);
- if (connect(sock2, (struct sockaddr *)&sin, sizeof(sin)) < 0 &&
- errno != EINPROGRESS)
- err(-1, "%s: setup_tcp: connect(%s, %d)", test,
- inet_ntoa(sin.sin_addr), PORT1);
-
- /*
- * Now pick up the connection after sleeping a moment to make sure
- * there's been time for some packets to go back and forth.
- */
- if (sleep(1) < 0)
- err(-1, "%s: sleep(1)", test);
- sock3 = accept(sock1, NULL, NULL);
- if (sock3 < 0)
- err(-1, "%s: accept", test);
- if (sleep(1) < 0)
- err(-1, "%s: sleep(1)", test);
-
- FD_ZERO(&writefds);
- FD_SET(sock2, &writefds);
- FD_ZERO(&exceptfds);
- FD_SET(sock2, &exceptfds);
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- ret = select(sock2 + 1, NULL, &writefds, &exceptfds, &tv);
- if (ret < 0)
- err(-1, "%s: setup_tcp: select", test);
- if (FD_ISSET(sock2, &exceptfds))
- errx(-1, "%s: setup_tcp: select: exception", test);
- if (!FD_ISSET(sock2, &writefds))
- errx(-1, "%s: setup_tcp: select: not writable", test);
-
- close(sock1);
- fdp[0] = sock2;
- fdp[1] = sock3;
-}
-
-static void
-setup_udsstream(const char *test, int *fdp)
-{
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fdp) < 0)
- err(-1, "%s: setup_udsstream: socketpair", test);
-}
-
-static void
-setup_udsdgram(const char *test, int *fdp)
-{
-
- if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fdp) < 0)
- err(-1, "%s: setup_udsdgram: socketpair", test);
-}
-
-static void
-setup_pipe(const char *test, int *fdp)
-{
-
- if (pipe(fdp) < 0)
- err(-1, "%s: setup_pipe: pipe", test);
-}
-
-static void
-setup_fifo(const char *test, int *fdp)
-{
- char path[] = "0send_fifo.XXXXXXX";
- int fd1, fd2;
-
- if (mkstemp(path) == -1)
- err(-1, "%s: setup_fifo: mktemp", test);
- unlink(path);
-
- if (mkfifo(path, 0600) < 0)
- err(-1, "%s: setup_fifo: mkfifo(%s)", test, path);
-
- fd1 = open(path, O_RDONLY | O_NONBLOCK);
- if (fd1 < 0)
- err(-1, "%s: setup_fifo: open(%s, O_RDONLY)", test, path);
-
- fd2 = open(path, O_WRONLY | O_NONBLOCK);
- if (fd2 < 0)
- err(-1, "%s: setup_fifo: open(%s, O_WRONLY)", test, path);
-
- fdp[0] = fd2;
- fdp[1] = fd1;
-}
-
-static void
-close_both(int *fdp)
-{
-
- close(fdp[0]);
- fdp[0] = -1;
- close(fdp[1]);
- fdp[1] = -1;
-}
-
-int
-main(int argc, char *argv[])
-{
- int fd[2];
-
- setup_udp("udp_0send", fd);
- try_0send("udp_0send", fd[0]);
- close_both(fd);
-
- setup_udp("udp_0write", fd);
- try_0write("udp_0write", fd[0]);
- close_both(fd);
-
- setup_tcp("tcp_0send", fd);
- try_0send("tcp_0send", fd[0]);
- close_both(fd);
-
- setup_tcp("tcp_0write", fd);
- try_0write("tcp_0write", fd[0]);
- close_both(fd);
-
- setup_udsstream("udsstream_0send", fd);
- try_0send("udsstream_0send", fd[0]);
- close_both(fd);
-
- setup_udsstream("udsstream_0write", fd);
- try_0write("udsstream_0write", fd[0]);
- close_both(fd);
-
- setup_udsdgram("udsdgram_0send", fd);
- try_0send("udsdgram_0send", fd[0]);
- close_both(fd);
-
- setup_udsdgram("udsdgram_0write", fd);
- try_0write("udsdgram_0write", fd[0]);
- close_both(fd);
-
- setup_pipe("pipe_0write", fd);
- try_0write("pipd_0write", fd[0]);
- close_both(fd);
-
- setup_fifo("fifo_0write", fd);
- try_0write("fifo_0write", fd[0]);
- close_both(fd);
-
- return (0);
-}
diff --git a/tests/sys/vfs/Makefile b/tests/sys/vfs/Makefile
deleted file mode 100644
index 7cd908b..0000000
--- a/tests/sys/vfs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-TESTSDIR= ${TESTSBASE}/sys/vfs
-
-TAP_TESTS_SH+= trailing_slash_test
-
-.include <bsd.test.mk>
diff --git a/tests/sys/vfs/trailing_slash_test.sh b/tests/sys/vfs/trailing_slash_test.sh
deleted file mode 100755
index 28c7f5f..0000000
--- a/tests/sys/vfs/trailing_slash_test.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-# Tests vfs_lookup()'s handling of trailing slashes for symlinks that
-# point to files. See kern/21768 for details. Fixed in r193028.
-#
-
-testfile=$(mktemp tmp.XXXXXX) || exit
-testlink="testlink-$$"
-
-tests="
-$testfile:$testlink:$testfile:0
-$testfile:$testlink:$testfile/:1
-$testfile:$testlink:$testlink:0
-$testfile:$testlink:$testlink/:1
-$testfile/:$testlink:$testlink:1
-$testfile/:$testlink:$testlink/:1
-"
-
-trap "rm $testfile $testlink" EXIT
-
-set $tests
-echo "1..$#"
-n=1
-for testspec ; do
- (
- IFS=:
- set $testspec
- unset IFS
- ln -fs "$1" "$2" || exit 1
- cat "$3" >/dev/null 2>&1
- ret=$?
- if [ "$ret" -eq "$4" ] ; then
- echo "ok $n"
- else
- echo "fail $n - expected $4, got $ret"
- fi
- )
- n=$((n+1))
-done
OpenPOWER on IntegriCloud