Remove socket errors from SocketOptionSet

This commit is contained in:
Ruihan Li
2025-02-19 15:33:03 +08:00
committed by Tate, Hongliang Tian
parent 76e9694dd0
commit 68cf99993e
7 changed files with 221 additions and 151 deletions

View File

@ -323,31 +323,58 @@ FN_TEST(async_connect)
socklen_t errlen = sizeof(err);
sk_addr.sin_port = 0xbeef;
#define ASYNC_CONNECT \
TEST_ERRNO(connect(sk_bound, (struct sockaddr *)&sk_addr, \
sizeof(sk_addr)), \
EINPROGRESS); \
TEST_RES(poll(&pfd, 1, 60), pfd.revents &POLLOUT);
ASYNC_CONNECT;
// The second `connect` will fail with `ECONNREFUSED`.
TEST_ERRNO(connect(sk_bound, (struct sockaddr *)&sk_addr,
sizeof(sk_addr)),
EINPROGRESS);
ECONNREFUSED);
TEST_RES(poll(&pfd, 1, 60), pfd.revents & POLLOUT);
TEST_RES(getsockopt(sk_bound, SOL_SOCKET, SO_ERROR, &err, &errlen),
errlen == sizeof(err) && err == ECONNREFUSED);
ASYNC_CONNECT;
// Reading the socket error will cause it to be cleared
TEST_RES(getsockopt(sk_bound, SOL_SOCKET, SO_ERROR, &err, &errlen),
errlen == sizeof(err) && err == ECONNREFUSED);
TEST_RES(getsockopt(sk_bound, SOL_SOCKET, SO_ERROR, &err, &errlen),
errlen == sizeof(err) && err == 0);
// `listen` won't succeed until the second `connect`.
TEST_ERRNO(listen(sk_bound, 10), EINVAL);
// The second `connect` will fail with `ECONNABORTED` if the socket
// error is cleared.
TEST_ERRNO(connect(sk_bound, (struct sockaddr *)&sk_addr,
sizeof(sk_addr)),
ECONNABORTED);
#undef ASYNC_CONNECT
}
END_TEST()
void set_blocking(int sockfd)
static void set_blocking(int sockfd, int is_blocking)
{
int flags = CHECK(fcntl(sockfd, F_GETFL, 0));
CHECK(fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)));
if (is_blocking) {
flags &= ~O_NONBLOCK;
} else {
flags |= O_NONBLOCK;
}
CHECK(fcntl(sockfd, F_SETFL, flags));
}
FN_SETUP(enter_blocking_mode)
{
set_blocking(sk_connected);
set_blocking(sk_bound);
set_blocking(sk_connected, 1);
set_blocking(sk_bound, 1);
}
END_SETUP()
@ -536,6 +563,7 @@ FN_TEST(bind_and_connect_same_address)
TEST_SUCC(listen(sk_listen, 3));
// For blocking sockets, conflict addresses result in `EADDRNOTAVAIL`.
sk_addr.sin_port = htons(listen_port);
TEST_SUCC(connect(sk_connect1, (struct sockaddr *)&sk_addr,
sizeof(sk_addr)));
@ -543,8 +571,15 @@ FN_TEST(bind_and_connect_same_address)
sizeof(sk_addr)),
EADDRNOTAVAIL);
// For non-blocking sockets, conflict addresses also result in `EADDRNOTAVAIL`.
// (`EINPROGRESS` should _not_ be returned in this case.)
set_blocking(sk_connect2, 0);
TEST_ERRNO(connect(sk_connect2, (struct sockaddr *)&sk_addr,
sizeof(sk_addr)),
EADDRNOTAVAIL);
TEST_SUCC(close(sk_listen));
TEST_SUCC(close(sk_connect1));
TEST_SUCC(close(sk_connect2));
}
END_TEST()
END_TEST()