3 #define _GNU_SOURCE /* expose POLLRDHUP when testing on Linux */
5 #include <sys/socket.h>
18 append(char *out, size_t out_size, const char *s)
20 size_t size = strlen(out);
22 snprintf(out + size, out_size - size, "%s", s);
26 decode_events(int events, char *out, size_t out_size)
33 append(out, out_size, "0");
37 #define DECODE_FLAG(x) \
40 append(out, out_size, " | "); \
41 append(out, out_size, #x); \
44 /* Show the expected flags by name. */
49 #define KNOWN_FLAGS (POLLIN | POLLOUT | POLLHUP)
51 DECODE_FLAG(POLLRDHUP);
52 #define KNOWN_FLAGS (POLLIN | POLLOUT | POLLHUP | POLLRDHUP);
55 /* Show any unexpected bits as hex. */
56 unknown = events & ~KNOWN_FLAGS;
60 snprintf(buf, sizeof(buf), "%s%x", out[0] != 0 ? " | " : "",
62 append(out, out_size, buf);
67 report(int num, const char *state, int expected, int got)
69 char expected_str[80];
72 decode_events(expected, expected_str, sizeof(expected_str));
73 decode_events(got, got_str, sizeof(got_str));
75 printf("ok %-2d ", num);
77 printf("not ok %-2d", num);
78 printf(" state %s: expected %s; got %s\n",
79 state, expected_str, got_str);
84 set_nonblocking(int sck)
88 flags = fcntl(sck, F_GETFL, 0);
91 if (fcntl(sck, F_SETFL, flags))
97 static char largeblock[1048576]; /* should be more than AF_UNIX sockbuf size */
99 static struct pollfd pfd0;
100 static struct pollfd pfd1;
105 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0)
106 err(1, "socketpair");
107 if (set_nonblocking(fd[0]) == -1)
109 if (set_nonblocking(fd[1]) == -1)
112 pfd0.events = POLLIN | POLLOUT;
114 pfd1.events = POLLIN | POLLOUT;
126 /* Large write with close */
128 if (poll(&pfd0, 1, 0) == -1)
130 report(num++, "initial 0", POLLOUT, pfd0.revents);
131 if (poll(&pfd1, 1, 0) == -1)
133 report(num++, "initial 1", POLLOUT, pfd1.revents);
134 if (write(fd[0], largeblock, sizeof(largeblock)) == -1)
136 if (poll(&pfd0, 1, 0) == -1)
138 report(num++, "after large write", 0, pfd0.revents);
139 if (poll(&pfd1, 1, 0) == -1)
141 report(num++, "other side after large write", POLLIN | POLLOUT, pfd1.revents);
143 if (poll(&pfd1, 1, 0) == -1)
145 report(num++, "other side after close", POLLIN | POLLHUP, pfd1.revents);
146 if (read(fd[1], largeblock, sizeof(largeblock)) == -1)
148 if (poll(&pfd1, 1, 0) == -1)
150 report(num++, "other side after reading input", POLLHUP, pfd1.revents);
153 /* With shutdown(SHUT_WR) */
155 if (shutdown(fd[0], SHUT_WR) == -1)
157 if (poll(&pfd0, 1, 0) == -1)
159 report(num++, "after shutdown(SHUT_WR)", POLLOUT, pfd0.revents);
160 if (poll(&pfd1, 1, 0) == -1)
162 report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT, pfd1.revents);
163 switch (read(fd[1], largeblock, sizeof(largeblock))) {
167 err(1, "read after other side shutdown");
170 errx(1, "kernel made up data that was never written");
172 if (poll(&pfd1, 1, 0) == -1)
174 report(num++, "other side after reading EOF", POLLIN | POLLOUT, pfd1.revents);
175 if (write(fd[1], largeblock, sizeof(largeblock)) == -1)
177 if (poll(&pfd0, 1, 0) == -1)
179 report(num++, "after data from other side", POLLIN | POLLOUT, pfd0.revents);
180 if (poll(&pfd1, 1, 0) == -1)
182 report(num++, "after writing", POLLIN, pfd1.revents);
183 if (shutdown(fd[1], SHUT_WR) == -1)
184 err(1, "shutdown second");
185 if (poll(&pfd0, 1, 0) == -1)
187 report(num++, "after second shutdown", POLLIN | POLLHUP, pfd0.revents);
188 if (poll(&pfd1, 1, 0) == -1)
190 report(num++, "after second shutdown", POLLHUP, pfd1.revents);
192 if (poll(&pfd1, 1, 0) == -1)
194 report(num++, "after close", POLLHUP, pfd1.revents);
198 * With shutdown(SHUT_RD)
199 * Note that shutdown(SHUT_WR) is passed to the peer, but
200 * shutdown(SHUT_RD) is not.
203 if (shutdown(fd[0], SHUT_RD) == -1)
205 if (poll(&pfd0, 1, 0) == -1)
207 report(num++, "after shutdown(SHUT_RD)", POLLIN | POLLOUT, pfd0.revents);
208 if (poll(&pfd1, 1, 0) == -1)
210 report(num++, "other side after shutdown(SHUT_RD)", POLLOUT, pfd1.revents);
211 if (shutdown(fd[0], SHUT_WR) == -1)
213 if (poll(&pfd0, 1, 0) == -1)
215 report(num++, "after shutdown(SHUT_WR)", POLLHUP, pfd0.revents);
216 if (poll(&pfd1, 1, 0) == -1)
218 report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT, pfd1.revents);
224 pfd1.events |= POLLRDHUP;
225 if (shutdown(fd[0], SHUT_RD) == -1)
227 if (poll(&pfd1, 1, 0) == -1)
229 report(num++, "other side after shutdown(SHUT_RD)", POLLOUT, pfd1.revents);
230 if (write(fd[0], "x", 1) != 1)
232 if (poll(&pfd1, 1, 0) == -1)
234 report(num++, "other side after write", POLLIN | POLLOUT, pfd1.revents);
235 if (shutdown(fd[0], SHUT_WR) == -1)
237 if (poll(&pfd1, 1, 0) == -1)
239 report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT | POLLRDHUP, pfd1.revents);