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
This commit is contained in:
Thomas Munro 2021-04-28 23:08:27 +12:00
parent 3aaaa2efde
commit 18f21f0355
3 changed files with 120 additions and 33 deletions

View File

@ -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

View File

@ -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

View File

@ -1,61 +1,82 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
#include <sys/poll.h> #define _GNU_SOURCE /* expose POLLRDHUP when testing on Linux */
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <err.h> #include <err.h>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
static const char * static void
decode_events(int events) append(char *out, size_t out_size, const char *s)
{ {
char *ncresult; size_t size = strlen(out);
const char *result;
switch (events) { snprintf(out + size, out_size - size, "%s", s);
case POLLIN: }
result = "POLLIN";
break; static void
case POLLOUT: decode_events(int events, char *out, size_t out_size)
result = "POLLOUT"; {
break; int unknown;
case POLLIN | POLLOUT:
result = "POLLIN | POLLOUT"; out[0] = 0;
break;
case POLLHUP: if (events == 0) {
result = "POLLHUP"; append(out, out_size, "0");
break; return;
case POLLIN | POLLHUP: }
result = "POLLIN | POLLHUP";
break; #define DECODE_FLAG(x) \
case POLLOUT | POLLHUP: if (events & (x)) { \
result = "POLLOUT | POLLHUP"; if (out[0] != 0) \
break; append(out, out_size, " | "); \
case POLLIN | POLLOUT | POLLHUP: append(out, out_size, #x); \
result = "POLLIN | POLLOUT | POLLHUP"; }
break;
default: /* Show the expected flags by name. */
asprintf(&ncresult, "%#x", events); DECODE_FLAG(POLLIN);
result = ncresult; DECODE_FLAG(POLLOUT);
break; 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 static void
report(int num, const char *state, int expected, int got) 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) if (expected == got)
printf("ok %-2d ", num); printf("ok %-2d ", num);
else else
printf("not ok %-2d", num); printf("not ok %-2d", num);
printf(" state %s: expected %s; got %s\n", printf(" state %s: expected %s; got %s\n",
state, decode_events(expected), decode_events(got)); state, expected_str, got_str);
fflush(stdout); fflush(stdout);
} }
@ -198,5 +219,27 @@ main(void)
close(fd[0]); close(fd[0]);
close(fd[1]); 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); return (0);
} }