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