1#include <stdio.h>
| 1#include <sys/select.h> 2#include <err.h> 3#include <errno.h>
|
2#include <fcntl.h>
| 4#include <fcntl.h>
|
3#include <unistd.h>
| 5#include <stdio.h>
|
4#include <stdlib.h>
| 6#include <stdlib.h>
|
5#include <sys/select.h>
| |
6#include <string.h>
| 7#include <string.h>
|
7#include <errno.h>
| 8#include <unistd.h>
|
8 9#define BIG_PIPE_SIZE 64*1024 /* From sys/pipe.h */ 10 11/* 12 * Test for the non-blocking big pipe bug (write(2) returning 13 * EAGAIN while select(2) returns the descriptor as ready for write). 14 *
| 9 10#define BIG_PIPE_SIZE 64*1024 /* From sys/pipe.h */ 11 12/* 13 * Test for the non-blocking big pipe bug (write(2) returning 14 * EAGAIN while select(2) returns the descriptor as ready for write). 15 *
|
15 * $FreeBSD: head/tools/regression/pipe/bigpipetest.c 137587 2004-11-11 19:47:55Z nik $
| 16 * $FreeBSD: head/tests/sys/kern/pipe/big_pipe_test.c 290914 2015-11-16 05:38:40Z ngie $
|
16 */ 17
| 17 */ 18
|
18void write_frame(int fd, char *buf, unsigned long buflen)
| 19static void 20write_frame(int fd, char *buf, unsigned long buflen)
|
19{
| 21{
|
20 fd_set wfd; 21 int i;
| 22 fd_set wfd; 23 int i;
|
22
| 24
|
23 while (buflen) { 24 FD_ZERO(&wfd); 25 FD_SET(fd, &wfd); 26 i = select(fd+1, NULL, &wfd, NULL, NULL); 27 if (i < 0) { 28 perror("select"); 29 exit(1);
| 25 while (buflen) { 26 FD_ZERO(&wfd); 27 FD_SET(fd, &wfd); 28 i = select(fd+1, NULL, &wfd, NULL, NULL); 29 if (i < 0) 30 err(1, "select failed"); 31 if (i != 1) { 32 errx(1, "select returned unexpected value %d\n", i); 33 exit(1); 34 } 35 i = write(fd, buf, buflen); 36 if (i < 0) { 37 if (errno != EAGAIN) 38 warn("write failed"); 39 exit(1); 40 } 41 buf += i; 42 buflen -= i;
|
30 }
| 43 }
|
31 if (i != 1) { 32 fprintf(stderr, "select returned unexpected value %d\n", i); 33 exit(1); 34 } 35 i = write(fd, buf, buflen); 36 if (i < 0) { 37 if (errno != EAGAIN) 38 perror("write"); 39 exit(1); 40 } 41 buf += i; 42 buflen -= i; 43 }
| |
44} 45
| 44} 45
|
46int main()
| 46int 47main(void)
|
47{
| 48{
|
48 char buf[BIG_PIPE_SIZE]; /* any value over PIPE_SIZE should do */ 49 int i, flags, fd[2];
| 49 /* any value over PIPE_SIZE should do */ 50 char buf[BIG_PIPE_SIZE]; 51 int i, flags, fd[2];
|
50
| 52
|
51 printf("1..1\n");
| 53 if (pipe(fd) < 0) 54 errx(1, "pipe failed");
|
52
| 55
|
53 if (pipe(fd) < 0) { perror("pipe"); exit(1); }
| 56 flags = fcntl(fd[1], F_GETFL); 57 if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) { 58 printf("fcntl failed: %s\n", strerror(errno)); 59 exit(1); 60 }
|
54
| 61
|
55 flags = fcntl(fd[1], F_GETFL); 56 if (flags == -1 || fcntl(fd[1], F_SETFL, flags|O_NONBLOCK) == -1) { 57 perror("fcntl"); 58 exit(1); 59 } 60 61 switch (fork()) {
| 62 switch (fork()) {
|
62 case -1:
| 63 case -1:
|
63 perror("fork"); 64 exit(1);
| 64 err(1, "fork failed: %s\n", strerror(errno)); 65 break;
|
65 case 0:
| 66 case 0:
|
66 close(fd[1]); 67 for (;;) { 68 i = read(fd[0], buf, 256); /* any small size should do */ 69 if (i == 0) break; 70 if (i < 0) { perror("read"); exit(1); } 71 } 72 exit(0);
| 67 close(fd[1]); 68 for (;;) { 69 /* Any small size should do */ 70 i = read(fd[0], buf, 256); 71 if (i == 0) 72 break; 73 if (i < 0) 74 err(1, "read"); 75 } 76 exit(0);
|
73 default:
| 77 default:
|
74 break; 75 }
| 78 break; 79 }
|
76
| 80
|
77 close(fd[0]); 78 memset(buf, 0, sizeof buf); 79 for (i = 0; i < 1000; i++) write_frame(fd[1], buf, sizeof buf); 80 printf("ok 1\n"); 81 exit(0);
| 81 close(fd[0]); 82 memset(buf, 0, sizeof buf); 83 for (i = 0; i < 1000; i++) 84 write_frame(fd[1], buf, sizeof buf); 85 86 printf("ok\n"); 87 exit(0);
|
82}
| 88}
|