Files
heimdal/lib/roken/poll-test.c
T
2026-05-25 17:31:26 -05:00

132 lines
2.9 KiB
C

#include <config.h>
#include <roken.h>
static void
close_pair(rk_socket_t a, rk_socket_t b)
{
if (!rk_IS_BAD_SOCKET(a))
rk_closesocket(a);
if (!rk_IS_BAD_SOCKET(b))
rk_closesocket(b);
}
static int
connected_pair(rk_socket_t *a, rk_socket_t *b)
{
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
rk_socket_t ls = rk_INVALID_SOCKET;
rk_socket_t cs = rk_INVALID_SOCKET;
rk_socket_t as = rk_INVALID_SOCKET;
int one = 1;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sin.sin_port = 0;
ls = socket(AF_INET, SOCK_STREAM, 0);
if (rk_IS_BAD_SOCKET(ls))
return rk_SOCK_ERRNO;
setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
if (rk_IS_SOCKET_ERROR(bind(ls, (struct sockaddr *)&sin, sizeof(sin))) ||
rk_IS_SOCKET_ERROR(listen(ls, 1)) ||
rk_IS_SOCKET_ERROR(getsockname(ls, (struct sockaddr *)&sin, &len))) {
int ret = rk_SOCK_ERRNO;
rk_closesocket(ls);
return ret;
}
cs = socket(AF_INET, SOCK_STREAM, 0);
if (rk_IS_BAD_SOCKET(cs)) {
int ret = rk_SOCK_ERRNO;
rk_closesocket(ls);
return ret;
}
if (rk_IS_SOCKET_ERROR(connect(cs, (struct sockaddr *)&sin, len))) {
int ret = rk_SOCK_ERRNO;
close_pair(ls, cs);
return ret;
}
as = accept(ls, NULL, NULL);
if (rk_IS_BAD_SOCKET(as)) {
int ret = rk_SOCK_ERRNO;
close_pair(ls, cs);
return ret;
}
rk_closesocket(ls);
*a = as;
*b = cs;
return 0;
}
int
main(int argc, char **argv)
{
struct pollfd pfd;
rk_socket_t a = rk_INVALID_SOCKET;
rk_socket_t b = rk_INVALID_SOCKET;
char c = 'x';
int ret;
setprogname(argv[0]);
ret = rk_SOCK_INIT();
if (ret)
err(1, "rk_SOCK_INIT");
ret = poll(NULL, 0, 0);
if (ret != 0)
errx(1, "poll with no fds returned %d", ret);
ret = connected_pair(&a, &b);
if (ret)
errx(1, "connected_pair failed: %d", ret);
pfd.fd = a;
pfd.events = POLLIN;
pfd.revents = 0;
ret = poll(&pfd, 1, 0);
if (ret != 0)
errx(1, "poll readable before send returned %d", ret);
if (pfd.revents != 0)
errx(1, "poll timeout left revents as %#x", pfd.revents);
ret = send(b, &c, 1, 0);
if (rk_IS_SOCKET_ERROR(ret))
err(1, "send");
pfd.fd = a;
pfd.events = POLLIN;
pfd.revents = 0;
ret = poll(&pfd, 1, 5000);
if (ret != 1)
errx(1, "poll readable after send returned %d", ret);
if ((pfd.revents & POLLIN) == 0)
errx(1, "poll readable missing POLLIN in %#x", pfd.revents);
ret = recv(a, &c, 1, 0);
if (rk_IS_SOCKET_ERROR(ret))
err(1, "recv");
if (ret != 1)
errx(1, "recv returned %d", ret);
pfd.fd = b;
pfd.events = POLLOUT;
pfd.revents = 0;
ret = poll(&pfd, 1, 5000);
if (ret != 1)
errx(1, "poll writable returned %d", ret);
if ((pfd.revents & POLLOUT) == 0)
errx(1, "poll writable missing POLLOUT in %#x", pfd.revents);
close_pair(a, b);
rk_SOCK_EXIT();
return 0;
}