net: return native SO_ERROR

This commit is contained in:
nmzik
2026-09-06 05:07:44 +04:00
parent 46850f9574
commit d9d17737c3
2 changed files with 30 additions and 11 deletions
+23 -11
View File
@@ -918,7 +918,10 @@ static int SetGuestSocketError(int error) {
return -1; return -1;
} }
static int SetHostSocketError(int error) { static int ConvertHostSocketError(int error) {
if (error == 0) {
return 0;
}
int posix_error = Posix::POSIX_EIO; int posix_error = Posix::POSIX_EIO;
#if defined(_WIN32) #if defined(_WIN32)
switch (error) { switch (error) {
@@ -971,14 +974,14 @@ static int SetHostSocketError(int error) {
default: break; default: break;
} }
#endif #endif
return SetGuestSocketError(posix_error); return posix_error;
} }
static int SetHostSocketError() { static int SetHostSocketError() {
#if defined(_WIN32) #if defined(_WIN32)
return SetHostSocketError(WSAGetLastError()); return SetGuestSocketError(ConvertHostSocketError(WSAGetLastError()));
#else #else
return SetHostSocketError(errno); return SetGuestSocketError(ConvertHostSocketError(errno));
#endif #endif
} }
@@ -1873,18 +1876,27 @@ int KYTY_SYSV_ABI Getsockopt(int s, int level, int optname, void* optval, uint32
return -1; return -1;
} }
#if defined(_WIN32) // Guest socket options: SOL_SOCKET=0xffff, SO_ERROR=0x1007.
int len = static_cast<int>(*optlen); const bool socket_error = (level == 0xffff && optname == 0x1007);
#if !defined(_WIN32)
if (!socket_error) {
return SetGuestSocketError(Posix::POSIX_ENOPROTOOPT);
}
#endif
if (socket_error) {
optname = SO_ERROR;
}
SocketLength len = static_cast<SocketLength>(*optlen);
if (::getsockopt(socket, ConvertSocketOptionLevel(level), optname, static_cast<char*>(optval), if (::getsockopt(socket, ConvertSocketOptionLevel(level), optname, static_cast<char*>(optval),
&len) == SOCKET_ERROR) { &len) != 0) {
return SetHostSocketError(); return SetHostSocketError();
} }
if (socket_error && len >= static_cast<SocketLength>(sizeof(int))) {
auto* error = static_cast<int*>(optval);
*error = ConvertHostSocketError(*error);
}
*optlen = static_cast<uint32_t>(len); *optlen = static_cast<uint32_t>(len);
return 0; return 0;
#else
*Posix::GetErrorAddr() = Posix::POSIX_ENOSYS;
return -1;
#endif
} }
int KYTY_SYSV_ABI Setsockopt(int s, int level, int optname, const void* optval, uint32_t optlen) { int KYTY_SYSV_ABI Setsockopt(int s, int level, int optname, const void* optval, uint32_t optlen) {
+7
View File
@@ -99,6 +99,13 @@ void CheckSocketWakeup() {
const int enabled = 1; const int enabled = 1;
Check(Net::Setsockopt(writer, 6, 1, &enabled, sizeof(enabled)) == 0, Check(Net::Setsockopt(writer, 6, 1, &enabled, sizeof(enabled)) == 0,
"enable TCP_NODELAY"); "enable TCP_NODELAY");
int socket_error = -1;
uint32_t error_size = sizeof(socket_error);
*Libs::Posix::GetErrorAddr() = Libs::Posix::POSIX_EINVAL;
Check(Net::Getsockopt(writer, 0xffff, 0x1007, &socket_error, &error_size) == 0 &&
socket_error == 0 && error_size == sizeof(socket_error) &&
*Libs::Posix::GetErrorAddr() == Libs::Posix::POSIX_EINVAL,
"SO_ERROR reports socket status without changing guest errno");
std::array<uint64_t, 16> readable {}; std::array<uint64_t, 16> readable {};
const auto bit = uint64_t {1} << (reader % 64); const auto bit = uint64_t {1} << (reader % 64);