1290914Sngie#include <sys/select.h> 2290914Sngie#include <err.h> 3290914Sngie#include <errno.h> 4290914Sngie#include <fcntl.h> 5118262Spb#include <stdio.h> 6118262Spb#include <stdlib.h> 7118262Spb#include <string.h> 8290914Sngie#include <unistd.h> 9118262Spb 10132479Ssilby#define BIG_PIPE_SIZE 64*1024 /* From sys/pipe.h */ 11132479Ssilby 12118262Spb/* 13118262Spb * Test for the non-blocking big pipe bug (write(2) returning 14118262Spb * EAGAIN while select(2) returns the descriptor as ready for write). 15118262Spb * 16118262Spb * $FreeBSD$ 17118262Spb */ 18118262Spb 19290914Sngiestatic void 20290914Sngiewrite_frame(int fd, char *buf, unsigned long buflen) 21118262Spb{ 22290914Sngie fd_set wfd; 23290914Sngie int i; 24118262Spb 25290914Sngie while (buflen) { 26290914Sngie FD_ZERO(&wfd); 27290914Sngie FD_SET(fd, &wfd); 28290914Sngie i = select(fd+1, NULL, &wfd, NULL, NULL); 29290914Sngie if (i < 0) 30290914Sngie err(1, "select failed"); 31290914Sngie if (i != 1) { 32290914Sngie errx(1, "select returned unexpected value %d\n", i); 33290914Sngie exit(1); 34290914Sngie } 35290914Sngie i = write(fd, buf, buflen); 36290914Sngie if (i < 0) { 37290914Sngie if (errno != EAGAIN) 38290914Sngie warn("write failed"); 39290914Sngie exit(1); 40290914Sngie } 41290914Sngie buf += i; 42290914Sngie buflen -= i; 43118262Spb } 44118262Spb} 45118262Spb 46290914Sngieint 47290914Sngiemain(void) 48118262Spb{ 49290914Sngie /* any value over PIPE_SIZE should do */ 50290914Sngie char buf[BIG_PIPE_SIZE]; 51290914Sngie int i, flags, fd[2]; 52118262Spb 53290914Sngie if (pipe(fd) < 0) 54290914Sngie errx(1, "pipe failed"); 55137587Snik 56290914Sngie flags = fcntl(fd[1], F_GETFL); 57290914Sngie if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) { 58290914Sngie printf("fcntl failed: %s\n", strerror(errno)); 59290914Sngie exit(1); 60290914Sngie } 61118262Spb 62290914Sngie switch (fork()) { 63118262Spb case -1: 64290914Sngie err(1, "fork failed: %s\n", strerror(errno)); 65290914Sngie break; 66118262Spb case 0: 67290914Sngie close(fd[1]); 68290914Sngie for (;;) { 69290914Sngie /* Any small size should do */ 70290914Sngie i = read(fd[0], buf, 256); 71290914Sngie if (i == 0) 72290914Sngie break; 73290914Sngie if (i < 0) 74290914Sngie err(1, "read"); 75290914Sngie } 76290914Sngie exit(0); 77118262Spb default: 78290914Sngie break; 79290914Sngie } 80118262Spb 81290914Sngie close(fd[0]); 82290914Sngie memset(buf, 0, sizeof buf); 83290914Sngie for (i = 0; i < 1000; i++) 84290914Sngie write_frame(fd[1], buf, sizeof buf); 85290914Sngie 86290914Sngie printf("ok\n"); 87290914Sngie exit(0); 88118262Spb} 89