diff options
author | pb <pb@FreeBSD.org> | 2003-07-31 12:40:56 +0000 |
---|---|---|
committer | pb <pb@FreeBSD.org> | 2003-07-31 12:40:56 +0000 |
commit | ee50ebe2699e0160daca4b63c4d46a7c82fb78e5 (patch) | |
tree | e0af319952ae08456298f6ce6760cf4c974936ce /tools/regression | |
parent | 3001b66e9f60d9319440a96b653b9ad4a1801291 (diff) | |
download | FreeBSD-src-ee50ebe2699e0160daca4b63c4d46a7c82fb78e5.zip FreeBSD-src-ee50ebe2699e0160daca4b63c4d46a7c82fb78e5.tar.gz |
Add a regression test for the big pipe bug.
Suggested by: silby
Diffstat (limited to 'tools/regression')
-rw-r--r-- | tools/regression/README | 1 | ||||
-rw-r--r-- | tools/regression/pipe/Makefile | 16 | ||||
-rw-r--r-- | tools/regression/pipe/bigpipetest.c | 78 |
3 files changed, 95 insertions, 0 deletions
diff --git a/tools/regression/README b/tools/regression/README index 40595ec..c7ecdab 100644 --- a/tools/regression/README +++ b/tools/regression/README @@ -22,6 +22,7 @@ geom Some tests and an out-of-kernel simulator for the GEOM code ia64_unaligned Tests unaligned reads on the IA64 nfsmmap Some tests to exercise some tricky cases in NFS and mmap p1003_1b Exercise 1003.1B scheduler +pipe Pipe code regression test fsx General filesystem exerciser sysvmsg SysV IPC Message Queue Regression Utility sysvsem SysV IPC Semaphore Regression Utility diff --git a/tools/regression/pipe/Makefile b/tools/regression/pipe/Makefile new file mode 100644 index 0000000..ff9f501 --- /dev/null +++ b/tools/regression/pipe/Makefile @@ -0,0 +1,16 @@ +# +# $FreeBSD$ +# +# "make" then "make regress". +# +PROG= bigpipetest +NOMAN= yes + +regress: + @if ./bigpipetest; then \ + echo "PASS"; \ + else \ + echo "FAIL"; \ + fi + +.include <bsd.prog.mk> diff --git a/tools/regression/pipe/bigpipetest.c b/tools/regression/pipe/bigpipetest.c new file mode 100644 index 0000000..1eb3776 --- /dev/null +++ b/tools/regression/pipe/bigpipetest.c @@ -0,0 +1,78 @@ +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/select.h> +#include <sys/pipe.h> +#include <string.h> +#include <errno.h> + +/* + * Test for the non-blocking big pipe bug (write(2) returning + * EAGAIN while select(2) returns the descriptor as ready for write). + * + * $FreeBSD$ + */ + +void write_frame(int fd, char *buf, unsigned long buflen) +{ + fd_set wfd; + int i; + + while (buflen) { + FD_ZERO(&wfd); + FD_SET(fd, &wfd); + i = select(fd+1, NULL, &wfd, NULL, NULL); + if (i < 0) { + perror("select"); + exit(1); + } + 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() +{ + char buf[BIG_PIPE_SIZE]; /* any value over PIPE_SIZE should do */ + int i, flags, fd[2]; + + 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); + } + + switch (fork()) { + case -1: + perror("fork"); + exit(1); + 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); + default: + break; + } + + close(fd[0]); + memset(buf, 0, sizeof buf); + for (i = 0; i < 1000; i++) write_frame(fd[1], buf, sizeof buf); + exit(0); +} |