From owner-svn-src-head@freebsd.org Mon Nov 16 05:38:43 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3A8B8A30DC5; Mon, 16 Nov 2015 05:38:43 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F36291D3E; Mon, 16 Nov 2015 05:38:42 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tAG5cgEZ055738; Mon, 16 Nov 2015 05:38:42 GMT (envelope-from ngie@FreeBSD.org) Received: (from ngie@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tAG5cffe055727; Mon, 16 Nov 2015 05:38:41 GMT (envelope-from ngie@FreeBSD.org) Message-Id: <201511160538.tAG5cffe055727@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ngie set sender to ngie@FreeBSD.org using -f From: Garrett Cooper Date: Mon, 16 Nov 2015 05:38:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290914 - in head: etc/mtree tests/sys/kern tests/sys/kern/pipe tools/regression/pipe X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Nov 2015 05:38:43 -0000 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 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 +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 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 +#include +#include +#include #include -#include +#include #include -#include #include -#include +#include #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 +#include +#include +#include +#include +#include +#include #include +#include #include -#include /* * $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 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 #include #include +#include /* * $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 +#include +#include +#include #include #include -#include +#include /* * $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 +#include -#include -#include -#include +#include +#include +#include /* * 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 +#include +#include +#include +#include +#include #include +#include +#include #include -#include /* * $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 +#include +#include +#include +#include +#include #include +#include +#include #include -#include /* * $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); }