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);
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to