svn commit: r290914 - in head: etc/mtree tests/sys/kern tests/sys/kern/pipe tools/regression/pipe

Garrett Cooper ngie at FreeBSD.org
Mon Nov 16 05:38:43 UTC 2015


Author: ngie
Date: Mon Nov 16 05:38:40 2015
New Revision: 290914
URL: https://svnweb.freebsd.org/changeset/base/290914

Log:
  Integrate tools/regression/pipe in to the FreeBSD test suite as
  tests/sys/kern/pipe
  
  - Fix style(9) bugs
  - Fix compiler warnings
  - Use `nitems(x)` instead of `sizeof(x) / sizeof(*x)` pattern
  
  The testcases will be converted over to ATF eventually, but for now will be
  integrated in as plain C tests
  
  MFC after: 1 week
  Sponsored by: EMC / Isilon Storage Division

Added:
  head/tests/sys/kern/pipe/
     - copied from r290913, head/tools/regression/pipe/
  head/tests/sys/kern/pipe/big_pipe_test.c
     - copied, changed from r290911, head/tools/regression/pipe/bigpipetest.c
  head/tests/sys/kern/pipe/pipe_fstat_bug_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-fstatbug.c
  head/tests/sys/kern/pipe/pipe_ino_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-ino.c
  head/tests/sys/kern/pipe/pipe_overcommit1_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-overcommit1.c
  head/tests/sys/kern/pipe/pipe_overcommit2_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-overcommit2.c
  head/tests/sys/kern/pipe/pipe_reverse2_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-reverse2.c
  head/tests/sys/kern/pipe/pipe_reverse_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-reverse.c
  head/tests/sys/kern/pipe/pipe_wraparound_test.c
     - copied, changed from r290911, head/tools/regression/pipe/pipe-wraparound.c
Deleted:
  head/tests/sys/kern/pipe/bigpipetest.c
  head/tests/sys/kern/pipe/bigpipetest.t
  head/tests/sys/kern/pipe/pipe-fstatbug.c
  head/tests/sys/kern/pipe/pipe-ino.c
  head/tests/sys/kern/pipe/pipe-overcommit1.c
  head/tests/sys/kern/pipe/pipe-overcommit2.c
  head/tests/sys/kern/pipe/pipe-reverse.c
  head/tests/sys/kern/pipe/pipe-reverse2.c
  head/tests/sys/kern/pipe/pipe-wraparound.c
  head/tools/regression/pipe/
Modified:
  head/etc/mtree/BSD.tests.dist
  head/tests/sys/kern/Makefile
  head/tests/sys/kern/pipe/Makefile

Modified: head/etc/mtree/BSD.tests.dist
==============================================================================
--- head/etc/mtree/BSD.tests.dist	Mon Nov 16 05:28:14 2015	(r290913)
+++ head/etc/mtree/BSD.tests.dist	Mon Nov 16 05:38:40 2015	(r290914)
@@ -377,6 +377,8 @@
             ..
             execve
             ..
+            pipe
+            ..
         ..
         kqueue
         ..

Modified: head/tests/sys/kern/Makefile
==============================================================================
--- head/tests/sys/kern/Makefile	Mon Nov 16 05:28:14 2015	(r290913)
+++ head/tests/sys/kern/Makefile	Mon Nov 16 05:38:40 2015	(r290914)
@@ -19,6 +19,7 @@ WARNS?=	5
 
 TESTS_SUBDIRS+=	acct
 TESTS_SUBDIRS+=	execve
+TESTS_SUBDIRS+=	pipe
 
 .include <netbsd-tests.test.mk>
 

Modified: head/tests/sys/kern/pipe/Makefile
==============================================================================
--- head/tools/regression/pipe/Makefile	Mon Nov 16 05:28:14 2015	(r290913)
+++ head/tests/sys/kern/pipe/Makefile	Mon Nov 16 05:38:40 2015	(r290914)
@@ -1,16 +1,16 @@
-#
 # $FreeBSD$
-#
-# "make" then "make regress".
-#
-PROG=	bigpipetest
-MAN=
 
-regress:
-	@if ./bigpipetest; then \
-		echo "PASS"; \
-	else \
-		echo "FAIL"; \
-	fi
+TESTSDIR=	${TESTSBASE}/sys/kern/pipe
 
-.include <bsd.prog.mk>
+PLAIN_TESTS_C+= big_pipe_test
+PLAIN_TESTS_C+= pipe_fstat_bug_test
+PLAIN_TESTS_C+= pipe_ino_test
+PLAIN_TESTS_C+= pipe_overcommit1_test
+PLAIN_TESTS_C+= pipe_overcommit2_test
+PLAIN_TESTS_C+= pipe_reverse2_test
+PLAIN_TESTS_C+= pipe_reverse_test
+PLAIN_TESTS_C+= pipe_wraparound_test
+
+WARNS?=		6
+
+.include <bsd.test.mk>

Copied and modified: head/tests/sys/kern/pipe/big_pipe_test.c (from r290911, head/tools/regression/pipe/bigpipetest.c)
==============================================================================
--- head/tools/regression/pipe/bigpipetest.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/big_pipe_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -1,10 +1,11 @@
-#include <stdio.h>
+#include <sys/select.h>
+#include <err.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <sys/select.h>
 #include <string.h>
-#include <errno.h>
+#include <unistd.h>
 
 #define BIG_PIPE_SIZE  64*1024 /* From sys/pipe.h */
 
@@ -15,68 +16,73 @@
  * $FreeBSD$
  */
 
-void write_frame(int fd, char *buf, unsigned long buflen)
+static void
+write_frame(int fd, char *buf, unsigned long buflen)
 {
-    fd_set wfd;
-    int i;
+	fd_set wfd;
+	int i;
 
-    while (buflen) {
-	FD_ZERO(&wfd);
-	FD_SET(fd, &wfd);
-	i = select(fd+1, NULL, &wfd, NULL, NULL);
-	if (i < 0) {
-	    perror("select");
-	    exit(1);
+	while (buflen) {
+		FD_ZERO(&wfd);
+		FD_SET(fd, &wfd);
+		i = select(fd+1, NULL, &wfd, NULL, NULL);
+		if (i < 0)
+			err(1, "select failed");
+		if (i != 1) {
+			errx(1, "select returned unexpected value %d\n", i);
+			exit(1);
+		}
+		i = write(fd, buf, buflen);
+		if (i < 0) {
+			if (errno != EAGAIN)
+				warn("write failed");
+			exit(1);
+		}
+		buf += i;
+		buflen -= i;
 	}
-	if (i != 1) {
-	    fprintf(stderr, "select returned unexpected value %d\n", i);
-	    exit(1);
-	}
-        i = write(fd, buf, buflen);
-	if (i < 0) {
-	    if (errno != EAGAIN)
-		perror("write");
-	    exit(1);
-	}
-        buf += i;
-        buflen -= i;
-    }
 }
 
-int main()
+int
+main(void)
 {
-    char buf[BIG_PIPE_SIZE];	/* any value over PIPE_SIZE should do */
-    int i, flags, fd[2];
-
-    printf("1..1\n");
-
-    if (pipe(fd) < 0) { perror("pipe"); exit(1); }
-
-    flags = fcntl(fd[1], F_GETFL);
-    if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) {
-	perror("fcntl");
-	exit(1);
-    }
+	/* any value over PIPE_SIZE should do */
+	char buf[BIG_PIPE_SIZE];
+	int i, flags, fd[2];
+
+	if (pipe(fd) < 0)
+		errx(1, "pipe failed");
+
+	flags = fcntl(fd[1], F_GETFL);
+	if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) {
+		printf("fcntl failed: %s\n", strerror(errno));
+		exit(1);
+	}
 
-    switch (fork()) {
+	switch (fork()) {
 	case -1:
-	    perror("fork");
-	    exit(1);
+		err(1, "fork failed: %s\n", strerror(errno));
+		break;
 	case 0:
-	    close(fd[1]);
-	    for (;;) {
-		i = read(fd[0], buf, 256); /* any small size should do */
-		if (i == 0) break;
-		if (i < 0) { perror("read"); exit(1); }
-	    }
-	    exit(0);
+		close(fd[1]);
+		for (;;) {
+			/* Any small size should do */
+			i = read(fd[0], buf, 256);
+			if (i == 0)
+				break;
+			if (i < 0)
+				err(1, "read");
+		}
+		exit(0);
 	default:
-	    break;
-    }
+		break;
+	}
+
+	close(fd[0]);
+	memset(buf, 0, sizeof buf);
+	for (i = 0; i < 1000; i++)
+		write_frame(fd[1], buf, sizeof buf);
 
-    close(fd[0]);
-    memset(buf, 0, sizeof buf);
-    for (i = 0; i < 1000; i++) write_frame(fd[1], buf, sizeof buf);
-    printf("ok 1\n");
-    exit(0);
+	printf("ok\n");
+	exit(0);
 }

Copied and modified: head/tests/sys/kern/pipe/pipe_fstat_bug_test.c (from r290911, head/tools/regression/pipe/pipe-fstatbug.c)
==============================================================================
--- head/tools/regression/pipe/pipe-fstatbug.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_fstat_bug_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -23,9 +23,16 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 SUCH DAMAGE.
 */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
-#include <sys/stat.h>
 
 /*
  * $FreeBSD$
@@ -37,46 +44,95 @@ SUCH DAMAGE.
  * for comparison.
  */
 
-int main (void)
+int
+main(void)
 {
-char buffer[32768], buffer2[32768];
-int desc[2];
-int error, successes = 0;
-struct stat status;
-pid_t new_pid;
-
-error = pipe(desc);
-
-if (error)
-	err(0, "Couldn't allocate fds\n");
-
-new_pid = fork();
-
-if (new_pid == 0) {
-	write(desc[1], &buffer, 145);
-	usleep(1000000);
-	write(desc[1], &buffer, 2048);
-	usleep(1000000);
-	write(desc[1], &buffer, 4096);
-	usleep(1000000);
-	write(desc[1], &buffer, 8191);
-	usleep(1000000);
-	write(desc[1], &buffer, 8192);
-	usleep(1000000);
-} else {
+	char buffer[32768], buffer2[32768], go[] = "go", go2[] = "go2";
+	int desc[2], ipc_coord[2];
+	ssize_t error;
+	int successes = 0;
+	struct stat status;
+	pid_t new_pid;
+
+	error = pipe(desc);
+	if (error == -1)
+		err(1, "Couldn't allocate data pipe");
+
+	error = pipe(ipc_coord);
+	if (error == -1)
+		err(1, "Couldn't allocate IPC coordination pipe");
+
+	new_pid = fork();
+	assert(new_pid != -1);
+
+	close(new_pid == 0 ? desc[0] : desc[1]);
+
+#define	SYNC_R(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: waiting for synchronization", __LINE__); \
+	if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+	errno = _error; \
+	} while(0)
+
+#define	SYNC_W(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: sending synchronization", __LINE__); \
+	if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+	errno = _error; \
+	} while(0)
+
+#define	WRITE(s) do { 							\
+	ssize_t _size; 							\
+	if ((_size = write(desc[1], &buffer, s)) != s)			\
+		warn("short write; wrote %zd, expected %d", _size, s);	\
+	} while(0)
+
+	if (new_pid == 0) {
+
+		SYNC_R(0, go);
+		WRITE(145);
+		SYNC_W(0, go2);
+
+		SYNC_R(0, go);
+		WRITE(2048);
+		SYNC_W(0, go2);
+
+		SYNC_R(0, go);
+		WRITE(4096);
+		SYNC_W(0, go2);
+
+		SYNC_R(0, go);
+		WRITE(8191);
+		SYNC_W(0, go2);
+
+		SYNC_R(0, go);
+		SYNC_W(0, go2); /* XXX: why is this required? */
+		WRITE(8192);
+		SYNC_W(0, go2);
+
+		close(ipc_coord[0]);
+		close(ipc_coord[1]);
+
+		_exit(0);
+	}
+
 	while (successes < 5) {
-		usleep(3000);
+		SYNC_W(1, go);
+		SYNC_R(1, go2);
 		fstat(desc[0], &status);
-		error = read(desc[0], &buffer2, 32768);
+		error = read(desc[0], &buffer2, sizeof(buffer2));
+
 		if (status.st_size != error)
-			err(0, "FAILURE: stat size %d read size %d\n", (int)status.st_size, error);
+			err(1, "FAILURE: stat size %jd read size %zd",
+			    (intmax_t)status.st_size, error);
 		if (error > 0) {
-			printf("SUCCESS at stat size %d read size %d\n", (int)status.st_size, error);
+			printf("SUCCESS at stat size %jd read size %zd\n",
+			    (intmax_t)status.st_size, error);
 			successes++;
-			/* Sleep to avoid the natural race in reading st_size. */
-			usleep(1000000);
 		}
 	}
-}
 
+	exit(0);
 }

Copied and modified: head/tests/sys/kern/pipe/pipe_ino_test.c (from r290911, head/tools/regression/pipe/pipe-ino.c)
==============================================================================
--- head/tools/regression/pipe/pipe-ino.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_ino_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -40,7 +40,7 @@
 #include <unistd.h>
 
 int
-main(int argc, char **argv)
+main(void)
 {
 	int pipefd[2];
 	struct stat st1, st2;
@@ -52,12 +52,11 @@ main(int argc, char **argv)
 		err(1, "FAIL: fstat st1");
 	if (fstat(pipefd[1], &st2) == -1)
 		err(1, "FAIL: fstat st2");
-	if (st1.st_dev != st2.st_dev || st1.st_dev == 0 || st2.st_dev == 0) {
-		errx(1, "FAIL: wrong dev number %d %d",
-		    st1.st_dev, st2.st_dev);
-	}
+	if (st1.st_dev != st2.st_dev || st1.st_dev == 0 || st2.st_dev == 0)
+		errx(1, "FAIL: wrong dev number %d %d", st1.st_dev, st2.st_dev);
 	if (st1.st_ino == st2.st_ino)
 		errx(1, "FAIL: inode numbers are equal: %d", st1.st_ino);
+
 	close(pipefd[0]);
 	close(pipefd[1]);
 	printf("PASS\n");

Copied and modified: head/tests/sys/kern/pipe/pipe_overcommit1_test.c (from r290911, head/tools/regression/pipe/pipe-overcommit1.c)
==============================================================================
--- head/tools/regression/pipe/pipe-overcommit1.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_overcommit1_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -26,8 +26,10 @@
  * DAMAGE.
  */
 
+#include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 /*
  * $FreeBSD$
@@ -35,13 +37,16 @@
  * that using up all pipe memory doesn't cause a panic.
  */
 
-int main (void)
-
+int
+main(void)
 {
-	int i, returnval;
-	int pipes[10000];
-	for (i = 0; i < 10000; i++) {
+	int pipes[10000], returnval;
+	unsigned int i;
+
+	for (i = 0; i < nitems(pipes); i++) {
 		returnval = pipe(&pipes[i]);
 	}
 	printf("PASS\n");
+
+	exit(0);
 }

Copied and modified: head/tests/sys/kern/pipe/pipe_overcommit2_test.c (from r290911, head/tools/regression/pipe/pipe-overcommit2.c)
==============================================================================
--- head/tools/regression/pipe/pipe-overcommit2.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_overcommit2_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -26,9 +26,13 @@
  * DAMAGE.
  */
 
+#include <sys/param.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <fcntl.h>
+#include <unistd.h>
 
 /*
  * $FreeBSD$
@@ -37,15 +41,21 @@
  * limit for that user has been exceeded.
  */
 
-int main (int argc, void *argv[])
-
+int
+main(void)
 {
-	int i, returnval, lastfd;
-	int pipes[10000];
-
-	for (i = 0; i < 100000; i++) {
-		returnval = open(argv[0], O_RDONLY);
-		if (returnval < 1)
+	char template[] = "pipe.XXXXXXXXXX";
+	int lastfd, pipes[10000], returnval;
+	unsigned int i;
+
+	lastfd = -1;
+
+	if (mkstemp(template) == -1)
+		err(1, "mkstemp failed");
+
+	for (i = 0; i < nitems(pipes); i++) {
+		returnval = open(template, O_RDONLY);
+		if (returnval == -1 && (errno == ENFILE || errno == EMFILE))
 			break; /* All descriptors exhausted. */
 		else
 			lastfd = returnval;
@@ -66,4 +76,8 @@ int main (int argc, void *argv[])
 		returnval = pipe(&pipes[i]);
 	}
 	printf("PASS\n");
+
+	unlink(template);
+
+	exit(0);
 }

Copied and modified: head/tests/sys/kern/pipe/pipe_reverse2_test.c (from r290911, head/tools/regression/pipe/pipe-reverse2.c)
==============================================================================
--- head/tools/regression/pipe/pipe-reverse2.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_reverse2_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -26,17 +26,17 @@
  * $FreeBSD$
  */
 
-#include	<sys/select.h>
+#include <sys/select.h>
 
-#include	<err.h>
-#include	<stdio.h>
-#include	<unistd.h>
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
 
 /*
  * Check that pipes can be selected for writing in the reverse direction.
  */
 int
-main(int argc, char *argv[])
+main(void)
 {
 	int pip[2];
 	fd_set set;

Copied and modified: head/tests/sys/kern/pipe/pipe_reverse_test.c (from r290911, head/tools/regression/pipe/pipe-reverse.c)
==============================================================================
--- head/tools/regression/pipe/pipe-reverse.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_reverse_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -23,9 +23,16 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 SUCH DAMAGE.
 */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
-#include <sys/stat.h>
 
 /*
  * $FreeBSD$
@@ -35,79 +42,108 @@ SUCH DAMAGE.
  * Linux.)
  */
 
-int main (void)
+int
+main(void)
 {
-char buffer[65535], buffer2[65535];
-int desc[2];
-int buggy, error, i, successes, total;
-struct stat status;
-pid_t new_pid;
-
-buggy = 0;
-total = 0;
-
-error = pipe(desc);
-
-if (error)
-	err(0, "Couldn't allocate fds\n");
-
-buffer[0] = 'A';
-
-for (i = 1; i < 65535; i++) {
-	buffer[i] = buffer[i - 1] + 1;
-	if (buffer[i] > 'Z')
-		buffer[i] = 'A';
+	char buffer[65535], buffer2[65535], go[] = "go", go2[] = "go2";
+	int desc[2], ipc_coord[2];
+	size_t i;
+	ssize_t total;
+	int buggy, error;
+	pid_t new_pid;
+
+	buggy = 0;
+	total = 0;
+
+	error = pipe(desc);
+	if (error == -1)
+		err(1, "Couldn't allocate data pipe");
+
+	error = pipe(ipc_coord);
+	if (error == -1)
+		err(1, "Couldn't allocate IPC coordination pipe");
+
+	buffer[0] = 'A';
+
+	for (i = 1; i < (int)sizeof(buffer); i++) {
+		buffer[i] = buffer[i - 1] + 1;
+		if (buffer[i] > 'Z')
+			buffer[i] = 'A';
 	}
 
-new_pid = fork();
+	new_pid = fork();
+	assert(new_pid != -1);
 
-if (new_pid == 0) {
-	error = write(desc[0], &buffer, 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	printf("Wrote %d bytes, sleeping\n", total);
-	usleep(1000000);
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	error = write(desc[0], &buffer[total], 4096);
-	total += error;
-	printf("Wrote another 8192 bytes, %d total, done\n", total);
-} else {
-	usleep(500000);
-	error = read(desc[1], &buffer2, 32768);
+#define	SYNC_R(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: waiting for synchronization", __LINE__); \
+	if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+	errno = _error; \
+	} while(0)
+
+#define	SYNC_W(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: sending synchronization", __LINE__); \
+	if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+	errno = _error; \
+	} while(0)
+
+#define	WRITE(s) do { 							\
+	ssize_t _size; 							\
+	if ((_size = write(desc[1], &buffer[total], s)) != s)		\
+		warn("short write; wrote %zd, expected %d", _size, s);	\
+	total += _size;							\
+	} while(0)
+
+	if (new_pid == 0) {
+		SYNC_R(0, go);
+		for (i = 0; i < 8; i++)
+			WRITE(4096);
+
+		SYNC_W(0, go2);
+		SYNC_R(0, go);
+
+		for (i = 0; i < 2; i++)
+			WRITE(4096);
+
+		SYNC_W(0, go2);
+
+		_exit(0);
+	}
+
+	SYNC_W(1, go);
+	SYNC_R(1, go2);
+
+	error = read(desc[0], &buffer2, 8 * 4096);
 	total += error;
-	printf("Read %d bytes, going back to sleep\n", error);
-	usleep(1000000);
-	error = read(desc[1], &buffer2[total], 8192);
+	printf("Read %d bytes\n", error);
+
+	SYNC_W(1, go);
+	SYNC_R(1, go2);
+
+	error = read(desc[0], &buffer2[total], 2 * 4096);
 	total += error;
 	printf("Read %d bytes, done\n", error);
 
-	for (i = 0; i < total; i++) {
-		if (buffer[i] != buffer2[i]) {
-			buggy = 1;
-			printf("Location %d input: %hhx output: %hhx\n",
-					i, buffer[i], buffer2[i]);
+	if (memcmp(buffer, buffer2, total) != 0) {
+		for (i = 0; i < (size_t)total; i++) {
+			if (buffer[i] != buffer2[i]) {
+				buggy = 1;
+				printf("Location %zu input: %hhx "
+				    "output: %hhx\n",
+				    i, buffer[i], buffer2[i]);
+			}
 		}
 	}
 
-if ((buggy == 1) || (total != 40960))
-	printf("FAILURE\n");
-else
-	printf("SUCCESS\n");
+	waitpid(new_pid, NULL, 0);
 
-}
+	if ((buggy == 1) || (total != 10 * 4096))
+		errx(1, "FAILED");
+	else
+		printf("SUCCESS\n");
 
+	exit(0);
 }

Copied and modified: head/tests/sys/kern/pipe/pipe_wraparound_test.c (from r290911, head/tools/regression/pipe/pipe-wraparound.c)
==============================================================================
--- head/tools/regression/pipe/pipe-wraparound.c	Mon Nov 16 04:53:13 2015	(r290911, copy source)
+++ head/tests/sys/kern/pipe/pipe_wraparound_test.c	Mon Nov 16 05:38:40 2015	(r290914)
@@ -23,9 +23,16 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 SUCH DAMAGE.
 */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
-#include <sys/stat.h>
 
 /*
  * $FreeBSD$
@@ -37,67 +44,97 @@ SUCH DAMAGE.
 
 int main (void)
 {
-char buffer[32768], buffer2[32768];
-int desc[2];
-int buggy, error, i, successes, total;
-struct stat status;
-pid_t new_pid;
-
-buggy = 0;
-total = 0;
-
-error = pipe(desc);
-
-if (error)
-	err(0, "Couldn't allocate fds\n");
-
-buffer[0] = 'A';
-
-for (i = 1; i < 32768; i++) {
-	buffer[i] = buffer[i - 1] + 1;
-	if (buffer[i] > 'Z')
-		buffer[i] = 'A';
+	char buffer[32768], buffer2[32768], go[] = "go", go2[] = "go2";
+	int desc[2], ipc_coord[2];
+	ssize_t error, total;
+	int buggy, i;
+	pid_t new_pid;
+
+	buggy = 0;
+	total = 0;
+
+	error = pipe(desc);
+	if (error == -1)
+		err(1, "Couldn't allocate data pipe");
+
+	error = pipe(ipc_coord);
+	if (error == -1)
+		err(1, "Couldn't allocate IPC coordination pipe");
+
+	buffer[0] = 'A';
+
+	for (i = 1; i < (int)sizeof(buffer); i++) {
+		buffer[i] = buffer[i - 1] + 1;
+		if (buffer[i] > 'Z')
+			buffer[i] = 'A';
 	}
 
-new_pid = fork();
+	new_pid = fork();
+	assert(new_pid != -1);
 
-if (new_pid == 0) {
-	error = write(desc[1], &buffer, 4096);
-	total += error;
-	error = write(desc[1], &buffer[total], 4096);
-	total += error;
-	error = write(desc[1], &buffer[total], 4000);
-	total += error;
-	printf("Wrote %d bytes, sleeping\n", total);
-	usleep(1000000);
-	error = write(desc[1], &buffer[total], 3000);
-	total += error;
-	error = write(desc[1], &buffer[total], 3000);
-	total += error;
-	printf("Wrote another 6000 bytes, %d total, done\n", total);
-} else {
-	usleep(500000);
+#define	SYNC_R(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: waiting for synchronization", __LINE__); \
+	if (read(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "parent" : "child")); \
+	errno = _error; \
+	} while(0)
+
+#define	SYNC_W(i, _buf) do {	\
+	int _error = errno; \
+	warnx("%d: sending synchronization", __LINE__); \
+	if (write(ipc_coord[i], &_buf, sizeof(_buf)) != sizeof(_buf)) \
+		err(1, "failed to synchronize (%s)", (i == 0 ? "child" : "parent")); \
+	errno = _error; \
+	} while(0)
+
+#define	WRITE(s) do { 							\
+	ssize_t _size; 							\
+	if ((_size = write(desc[1], &buffer[total], s)) != s)		\
+		warn("short write; wrote %zd, expected %d", _size, s);	\
+	total += _size;							\
+	} while(0)
+
+	if (new_pid == 0) {
+		WRITE(4096);
+		WRITE(4096);
+		WRITE(4000);
+		SYNC_W(0, go2);
+
+		SYNC_R(0, go);
+		WRITE(3000);
+		WRITE(3000);
+		SYNC_W(0, go2);
+
+		_exit(0);
+	}
+
+	SYNC_R(1, go2);
 	error = read(desc[0], &buffer2, 8192);
 	total += error;
-	printf("Read %d bytes, going back to sleep\n", error);
-	usleep(1000000);
+	printf("Read %zd bytes\n", error);
+	SYNC_W(1, go);
+	SYNC_R(1, go2);
 	error = read(desc[0], &buffer2[total], 16384);
 	total += error;
-	printf("Read %d bytes, done\n", error);
+	printf("Read %zd bytes, done\n", error);
 
-	for (i = 0; i < total; i++) {
-		if (buffer[i] != buffer2[i]) {
-			buggy = 1;
-			printf("Location %d input: %hhx output: %hhx\n",
-					i, buffer[i], buffer2[i]);
+	if (memcmp(buffer, buffer2, total) != 0) {
+		for (i = 0; i < total; i++) {
+			if (buffer[i] != buffer2[i]) {
+				buggy = 1;
+				printf("Location %d input: %hhx output: %hhx\n",
+				    i, buffer[i], buffer2[i]);
+			}
 		}
 	}
 
-if (buggy)
-	printf("FAILURE\n");
-else
-	printf("SUCCESS\n");
-}
+	waitpid(new_pid, NULL, 0);
+
+	if (buggy)
+		errx(1, "FAILURE");
 
+	printf("SUCCESS\n");
 
+	exit(0);
 }


More information about the svn-src-head mailing list