Merge pull request #4394 from AaravMehta-07/codex/sce-net-stream-sender
fix(libSceNet): preserve successful stream recvfrom results
This commit is contained in:
commit
83e6be8a69
|
|
@ -199,6 +199,10 @@ bool guest_to_native_address(const void* address, std::uint32_t length,
|
|||
|
||||
bool native_to_guest_address(const sockaddr_storage& native, void* address, std::uint32_t* length) {
|
||||
if (!address || !length) return false;
|
||||
if (native.ss_family == AF_UNSPEC) {
|
||||
*length = 0;
|
||||
return true;
|
||||
}
|
||||
std::uint8_t bytes[28]{};
|
||||
if (native.ss_family == AF_INET) {
|
||||
const auto& v4 = reinterpret_cast<const sockaddr_in&>(native);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,63 @@ static bool Failed(std::int64_t result, int error) {
|
|||
return result == static_cast<int>(0x80410100u | static_cast<unsigned>(error)) && *sceNetErrnoLoc() == error;
|
||||
}
|
||||
|
||||
static void CheckStreamSender(int family) {
|
||||
const auto addressSize = family == 2 ? 16u : 28u;
|
||||
const int listener = sceNetSocket(nullptr, family, 1, 6);
|
||||
Require(listener >= 0);
|
||||
std::array<std::uint8_t, 28> destination{};
|
||||
destination[0] = static_cast<std::uint8_t>(addressSize);
|
||||
destination[1] = static_cast<std::uint8_t>(family);
|
||||
if (family == 2) { destination[4] = 127; destination[7] = 1; }
|
||||
else destination[23] = 1;
|
||||
Require(sceNetBind_nid_postfix(listener, destination.data(), addressSize) == 0 && sceNetListen(listener, 1) == 0);
|
||||
std::uint32_t size = destination.size();
|
||||
Require(sceNetGetsockname(listener, destination.data(), &size) == 0 && size == addressSize);
|
||||
const int client = sceNetSocket(nullptr, family, 1, 6);
|
||||
Require(client >= 0 && sceNetConnect(client, destination.data(), addressSize) == 0);
|
||||
const int accepted = sceNetAccept(listener, nullptr, nullptr);
|
||||
Require(accepted >= 0);
|
||||
const char payload[] = "stream";
|
||||
for (const auto endpoints : {std::array{accepted, client}, std::array{client, accepted}}) {
|
||||
const auto receiver = endpoints[0], sender = endpoints[1];
|
||||
for (const std::uint32_t capacity : {0u, 1u, 16u, 28u, UINT32_MAX}) {
|
||||
Require(sceNetSend(sender, payload, sizeof(payload), 0) == sizeof(payload));
|
||||
std::array<std::uint8_t, 28> address;
|
||||
address.fill(0xa5);
|
||||
char received[sizeof(payload)]{};
|
||||
size = capacity;
|
||||
*sceNetErrnoLoc() = 123;
|
||||
Require(sceNetRecvfrom(receiver, received, 0, 2, address.data(), &size) == 0);
|
||||
Require(size == 0 && received[0] == 0 && *sceNetErrnoLoc() == 123);
|
||||
Require(std::all_of(address.begin(), address.end(), [](auto byte) { return byte == 0xa5; }));
|
||||
for (const int flags : {2, 0}) {
|
||||
size = capacity;
|
||||
*sceNetErrnoLoc() = 123;
|
||||
Require(sceNetRecvfrom(receiver, received, sizeof(received), flags, address.data(), &size) == sizeof(payload));
|
||||
Require(size == 0 && std::memcmp(received, payload, sizeof(payload)) == 0 && *sceNetErrnoLoc() == 123);
|
||||
Require(std::all_of(address.begin(), address.end(), [](auto byte) { return byte == 0xa5; }));
|
||||
}
|
||||
}
|
||||
Require(sceNetSend(sender, payload, sizeof(payload), 0) == sizeof(payload));
|
||||
std::array<std::uint8_t, 28> address;
|
||||
address.fill(0xa5);
|
||||
char received[sizeof(payload)]{};
|
||||
Require(Failed(sceNetRecvfrom(receiver, received, sizeof(received), 0, address.data(), nullptr), 22));
|
||||
size = 123;
|
||||
Require(sceNetRecvfrom(receiver, received, sizeof(received), 0, nullptr, &size) == sizeof(payload));
|
||||
Require(size == 123 && std::memcmp(received, payload, sizeof(payload)) == 0);
|
||||
Require(sceNetShutdown(sender, 1) == 0);
|
||||
for (const int flags : {2, 0}) {
|
||||
size = address.size();
|
||||
*sceNetErrnoLoc() = 123;
|
||||
Require(sceNetRecvfrom(receiver, received, sizeof(received), flags, address.data(), &size) == 0);
|
||||
Require(size == 0 && *sceNetErrnoLoc() == 123);
|
||||
Require(std::all_of(address.begin(), address.end(), [](auto byte) { return byte == 0xa5; }));
|
||||
}
|
||||
}
|
||||
for (const int descriptor : {client, accepted, listener}) Require(sceNetSocketClose(descriptor) == 0);
|
||||
}
|
||||
|
||||
static void CheckPoolStats() {
|
||||
const int pool = sceNetPoolCreate("stats", 0x4000, 0);
|
||||
Require(pool > 0);
|
||||
|
|
@ -626,6 +683,9 @@ int main() {
|
|||
Require(sceNetInetNtop(28, ipv6.data(), text, sizeof(text)) == text);
|
||||
Require(std::strcmp(text, "::1") == 0);
|
||||
|
||||
CheckStreamSender(2);
|
||||
if (!ipv6Unavailable) CheckStreamSender(28);
|
||||
|
||||
int state = -1;
|
||||
Require(sceNetCtlGetState(&state) == 0);
|
||||
Require(state == 0 || state == 3);
|
||||
|
|
|
|||
Loading…
Reference in New Issue