]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - tests/sys/kern/pipe/big_pipe_test.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / tests / sys / kern / pipe / big_pipe_test.c
1 #include <sys/select.h>
2 #include <err.h>
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
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  *
16  * $FreeBSD$
17  */
18
19 static void
20 write_frame(int fd, char *buf, unsigned long buflen)
21 {
22         fd_set wfd;
23         int i;
24
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;
43         }
44 }
45
46 int
47 main(void)
48 {
49         /* any value over PIPE_SIZE should do */
50         char buf[BIG_PIPE_SIZE];
51         int i, flags, fd[2];
52
53         if (pipe(fd) < 0)
54                 errx(1, "pipe failed");
55
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         }
61
62         switch (fork()) {
63         case -1:
64                 err(1, "fork failed: %s\n", strerror(errno));
65                 break;
66         case 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);
77         default:
78                 break;
79         }
80
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);
88 }