mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
The sigtimedwait entry still said SIGPIPE has no host equivalent, and the sigaction entry left it out of the signals whose handlers run. guest_broken_pipe now also covers VLC's drain: with a handler and 13 blocked, sigtimedwait takes the 13 a failed write leaves pending; with 13 ignored, nothing is pending. Co-Authored-By: Claude Opus 5.5 <[email protected]>
63 lines
2.3 KiB
C++
63 lines
2.3 KiB
C++
#include "prx/libkernel/include/Api.hpp"
|
|
#include "prx/libc/include/Api.hpp"
|
|
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <csignal>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
|
|
namespace {
|
|
|
|
constexpr int Unix = 1;
|
|
constexpr int Stream = 1;
|
|
constexpr int BrokenPipe = 13;
|
|
constexpr int PipeError = 32;
|
|
constexpr int TryAgain = 35;
|
|
volatile std::sig_atomic_t brokenPipeSignals = 0;
|
|
|
|
void Require(bool value) {
|
|
if (!value) std::abort();
|
|
}
|
|
|
|
void APS5_VABI CountBrokenPipe(int signal) {
|
|
if (signal == BrokenPipe) brokenPipeSignals = brokenPipeSignals + 1;
|
|
}
|
|
|
|
int WriteToClosedPeer() {
|
|
int pair[2] = {-1, -1};
|
|
Require(socketpair_nid_postfix(Unix, Stream, 0, pair) == 0);
|
|
Require(close_nid_postfix(pair[1]) == 0);
|
|
*__error_nid_postfix() = 0;
|
|
const bool failed = write_nid_postfix(pair[0], "x", 1) == -1;
|
|
const int error = *__error_nid_postfix();
|
|
Require(close_nid_postfix(pair[0]) == 0);
|
|
return failed ? error : 0;
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
const auto ignore = reinterpret_cast<GuestHandler>(std::uintptr_t{1});
|
|
Require(signal_nid_postfix(BrokenPipe, ignore) == nullptr);
|
|
Require(WriteToClosedPeer() == PipeError);
|
|
Require(signal_nid_postfix(BrokenPipe, CountBrokenPipe) == ignore);
|
|
Require(WriteToClosedPeer() == PipeError && brokenPipeSignals == 1);
|
|
GuestSignalSet blocked{};
|
|
blocked.bits[0] = 1u << (BrokenPipe - 1);
|
|
Require(_sigprocmask_nid_postfix(1, &blocked, nullptr) == 0);
|
|
Require(WriteToClosedPeer() == PipeError && brokenPipeSignals == 1);
|
|
GuestSignalSet pending{};
|
|
Require(sigpending_nid_postfix(&pending) == 0 && (pending.bits[0] & blocked.bits[0]) != 0);
|
|
Require(_sigprocmask_nid_postfix(2, &blocked, nullptr) == 0 && brokenPipeSignals == 2);
|
|
const KernelTimespec poll{0, 0};
|
|
Require(_sigprocmask_nid_postfix(1, &blocked, nullptr) == 0);
|
|
Require(WriteToClosedPeer() == PipeError);
|
|
Require(sigtimedwait_nid_postfix(&blocked, nullptr, &poll) == BrokenPipe);
|
|
Require(signal_nid_postfix(BrokenPipe, ignore) == CountBrokenPipe);
|
|
Require(WriteToClosedPeer() == PipeError);
|
|
*__error_nid_postfix() = 0;
|
|
Require(sigtimedwait_nid_postfix(&blocked, nullptr, &poll) == -1 && *__error_nid_postfix() == TryAgain);
|
|
Require(_sigprocmask_nid_postfix(2, &blocked, nullptr) == 0 && brokenPipeSignals == 2);
|
|
Require(signal_nid_postfix(BrokenPipe, nullptr) == ignore);
|
|
return 0;
|
|
}
|