aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro <tmunro@FreeBSD.org>2021-04-28 11:08:27 +0000
committerThomas Munro <tmunro@FreeBSD.org>2021-04-28 11:15:39 +0000
commit18f21f0355481283ceef0ec10e99554f44c205c2 (patch)
tree25750a0ea81c1ff176ae161ab9e9a4348b8f4715
parent3aaaa2efde896e19d229ee2cf09fe7e6ab0fbf6e (diff)
downloadsrc-18f21f0355481283ceef0ec10e99554f44c205c2.tar.gz
src-18f21f0355481283ceef0ec10e99554f44c205c2.zip
Update tools/regression/poll/sockpoll.c for POLLRDPOLL.
Add a POLLRDHUP example to this tool, for comparison with other operating systems. Also record current output on FreeBSD and Linux. Reviewed by: kib MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D29757
-rw-r--r--tools/regression/poll/14/sockpoll.out22
-rw-r--r--tools/regression/poll/l/sockpoll.out22
-rw-r--r--tools/regression/poll/sockpoll.c111
3 files changed, 121 insertions, 34 deletions
diff --git a/tools/regression/poll/14/sockpoll.out b/tools/regression/poll/14/sockpoll.out
new file mode 100644
index 000000000000..1e60f0e283e0
--- /dev/null
+++ b/tools/regression/poll/14/sockpoll.out
@@ -0,0 +1,22 @@
+1..18
+ok 1 state initial 0: expected POLLOUT; got POLLOUT
+ok 2 state initial 1: expected POLLOUT; got POLLOUT
+ok 3 state after large write: expected 0; got 0
+ok 4 state other side after large write: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 5 state other side after close: expected POLLIN | POLLHUP; got POLLIN | POLLHUP
+not ok 6 state other side after reading input: expected POLLHUP; got POLLIN | POLLHUP
+ok 7 state after shutdown(SHUT_WR): expected POLLOUT; got POLLOUT
+ok 8 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 9 state other side after reading EOF: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 10 state after data from other side: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 11 state after writing: expected POLLIN; got POLLIN
+ok 12 state after second shutdown: expected POLLIN | POLLHUP; got POLLIN | POLLHUP
+not ok 13 state after second shutdown: expected POLLHUP; got POLLIN | POLLHUP
+not ok 14 state after close: expected POLLHUP; got POLLIN | POLLHUP
+ok 15 state after shutdown(SHUT_RD): expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 16 state other side after shutdown(SHUT_RD): expected POLLOUT; got POLLOUT
+not ok 17 state after shutdown(SHUT_WR): expected POLLHUP; got POLLIN | POLLHUP
+ok 18 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 19 state other side after shutdown(SHUT_RD): expected POLLOUT; got POLLOUT
+ok 20 state other side after write: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 21 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT | POLLRDHUP; got POLLIN | POLLOUT | POLLRDHUP
diff --git a/tools/regression/poll/l/sockpoll.out b/tools/regression/poll/l/sockpoll.out
new file mode 100644
index 000000000000..cf5627d7953d
--- /dev/null
+++ b/tools/regression/poll/l/sockpoll.out
@@ -0,0 +1,22 @@
+1..18
+ok 1 state initial 0: expected POLLOUT; got POLLOUT
+ok 2 state initial 1: expected POLLOUT; got POLLOUT
+ok 3 state after large write: expected 0; got 0
+ok 4 state other side after large write: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+not ok 5 state other side after close: expected POLLIN | POLLHUP; got POLLIN | POLLOUT | POLLHUP
+not ok 6 state other side after reading input: expected POLLHUP; got POLLIN | POLLOUT | POLLHUP
+ok 7 state after shutdown(SHUT_WR): expected POLLOUT; got POLLOUT
+ok 8 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 9 state other side after reading EOF: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 10 state after data from other side: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 11 state after writing: expected POLLIN; got POLLIN
+not ok 12 state after second shutdown: expected POLLIN | POLLHUP; got POLLIN | POLLOUT | POLLHUP
+not ok 13 state after second shutdown: expected POLLHUP; got POLLIN | POLLHUP
+not ok 14 state after close: expected POLLHUP; got POLLIN | POLLOUT | POLLHUP | 8
+ok 15 state after shutdown(SHUT_RD): expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+ok 16 state other side after shutdown(SHUT_RD): expected POLLOUT; got POLLOUT
+not ok 17 state after shutdown(SHUT_WR): expected POLLHUP; got POLLIN | POLLOUT | POLLHUP
+not ok 18 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT; got POLLIN | POLLOUT | POLLHUP
+ok 19 state other side after shutdown(SHUT_RD): expected POLLOUT; got POLLOUT
+ok 20 state other side after write: expected POLLIN | POLLOUT; got POLLIN | POLLOUT
+not ok 21 state other side after shutdown(SHUT_WR): expected POLLIN | POLLOUT | POLLRDHUP; got POLLIN | POLLOUT | POLLHUP | POLLRDHUP
diff --git a/tools/regression/poll/sockpoll.c b/tools/regression/poll/sockpoll.c
index 4bffd29dc6f3..31ebcaf9bcb2 100644
--- a/tools/regression/poll/sockpoll.c
+++ b/tools/regression/poll/sockpoll.c
@@ -1,61 +1,82 @@
/* $FreeBSD$ */
-#include <sys/poll.h>
+#define _GNU_SOURCE /* expose POLLRDHUP when testing on Linux */
+
#include <sys/socket.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
+#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-static const char *
-decode_events(int events)
+static void
+append(char *out, size_t out_size, const char *s)
+{
+ size_t size = strlen(out);
+
+ snprintf(out + size, out_size - size, "%s", s);
+}
+
+static void
+decode_events(int events, char *out, size_t out_size)
{
- char *ncresult;
- const char *result;
-
- switch (events) {
- case POLLIN:
- result = "POLLIN";
- break;
- case POLLOUT:
- result = "POLLOUT";
- break;
- case POLLIN | POLLOUT:
- result = "POLLIN | POLLOUT";
- break;
- case POLLHUP:
- result = "POLLHUP";
- break;
- case POLLIN | POLLHUP:
- result = "POLLIN | POLLHUP";
- break;
- case POLLOUT | POLLHUP:
- result = "POLLOUT | POLLHUP";
- break;
- case POLLIN | POLLOUT | POLLHUP:
- result = "POLLIN | POLLOUT | POLLHUP";
- break;
- default:
- asprintf(&ncresult, "%#x", events);
- result = ncresult;
- break;
+ int unknown;
+
+ out[0] = 0;
+
+ if (events == 0) {
+ append(out, out_size, "0");
+ return;
+ }
+
+#define DECODE_FLAG(x) \
+ if (events & (x)) { \
+ if (out[0] != 0) \
+ append(out, out_size, " | "); \
+ append(out, out_size, #x); \
+ }
+
+ /* Show the expected flags by name. */
+ DECODE_FLAG(POLLIN);
+ DECODE_FLAG(POLLOUT);
+ DECODE_FLAG(POLLHUP);
+#ifndef POLLRDHUP
+#define KNOWN_FLAGS (POLLIN | POLLOUT | POLLHUP)
+#else
+ DECODE_FLAG(POLLRDHUP);
+#define KNOWN_FLAGS (POLLIN | POLLOUT | POLLHUP | POLLRDHUP);
+#endif
+
+ /* Show any unexpected bits as hex. */
+ unknown = events & ~KNOWN_FLAGS;
+ if (unknown != 0) {
+ char buf[80];
+
+ snprintf(buf, sizeof(buf), "%s%x", out[0] != 0 ? " | " : "",
+ unknown);
+ append(out, out_size, buf);
}
- return (result);
}
static void
report(int num, const char *state, int expected, int got)
{
+ char expected_str[80];
+ char got_str[80];
+
+ decode_events(expected, expected_str, sizeof(expected_str));
+ decode_events(got, got_str, sizeof(got_str));
if (expected == got)
printf("ok %-2d ", num);
else
printf("not ok %-2d", num);
printf(" state %s: expected %s; got %s\n",
- state, decode_events(expected), decode_events(got));
+ state, expected_str, got_str);
fflush(stdout);
}
@@ -198,5 +219,27 @@ main(void)
close(fd[0]);
close(fd[1]);
+#ifdef POLLRDHUP
+ setup();
+ pfd1.events |= POLLRDHUP;
+ if (shutdown(fd[0], SHUT_RD) == -1)
+ err(1, "shutdown");
+ if (poll(&pfd1, 1, 0) == -1)
+ err(1, "poll");
+ report(num++, "other side after shutdown(SHUT_RD)", POLLOUT, pfd1.revents);
+ if (write(fd[0], "x", 1) != 1)
+ err(1, "write");
+ if (poll(&pfd1, 1, 0) == -1)
+ err(1, "poll");
+ report(num++, "other side after write", POLLIN | POLLOUT, pfd1.revents);
+ if (shutdown(fd[0], SHUT_WR) == -1)
+ err(1, "shutdown");
+ if (poll(&pfd1, 1, 0) == -1)
+ err(1, "poll");
+ report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT | POLLRDHUP, pfd1.revents);
+ close(fd[0]);
+ close(fd[1]);
+#endif
+
return (0);
}