mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-12 09:58:36 +00:00
Add a regression test for the big pipe bug.
Suggested by: silby
This commit is contained in:
parent
9c000261d4
commit
af1a7621cf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=118262
@ -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
|
||||
|
16
tools/regression/pipe/Makefile
Normal file
16
tools/regression/pipe/Makefile
Normal file
@ -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>
|
78
tools/regression/pipe/bigpipetest.c
Normal file
78
tools/regression/pipe/bigpipetest.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user