mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 00:53:02 -05:00
On Linux a guest stderr redirect also moves the host's: guest descriptors are host descriptors, and the guest stderr stream wraps the host stderr FILE. After dup2(fd, 2), or freopen(path, mode, stderr) with full buffering, the libc terminate report, the host fprintf(stderr) diagnostics and libstdc++'s terminate message go into the title's pipe or file, and abort() discards what is still buffered. RetroArch (PPSA99169) reopens stderr onto app0/trace.txt with full buffering, so its stop on main left no message anywhere. Before the first guest redirect of descriptor 2 (libkernel dup2, libc freopen of a stream on descriptor 2), keep a close-on-exec duplicate of the host descriptor 2 and point the host stderr at an unbuffered stream on it. The guest stream keeps its own FILE and follows the redirect. The libc terminate report writes to the kept descriptor with write() instead of the stderr stream, and libkernel's sceKernelDebugOutText uses the same kept descriptor.
44 lines
1.7 KiB
C++
44 lines
1.7 KiB
C++
#ifndef CORE_LIBS_PRX_LIBC_INCLUDE_GENERAL_HPP
|
|
#define CORE_LIBS_PRX_LIBC_INCLUDE_GENERAL_HPP
|
|
|
|
#include <stdexcept>
|
|
#include <filesystem>
|
|
#include <vector>
|
|
|
|
#include "general/LogMacros.hpp"
|
|
#include "general/VabiMacros.hpp"
|
|
#include "general/ExportMacros.hpp"
|
|
|
|
extern "C" void NotImplemented_nid_no_patch(const char* funcName);
|
|
extern "C" void CxaFinalize_nid_no_patch(void* dsoHandle);
|
|
extern "C" bool StopAtPrefixLetter_nid_no_patch(const char* str, char** endptr, int base);
|
|
#ifndef _WIN32
|
|
extern "C" int KeepHostStandardError_nid_no_patch();
|
|
extern "C" int HostStandardError_nid_no_patch();
|
|
#endif
|
|
|
|
extern "C" std::filesystem::path ResolvePath_nid_no_patch(const char* path);
|
|
extern "C" int SetWorkingDirectory_nid_no_patch(const char* resolved);
|
|
extern "C" bool FinalPathComponentIsDot_nid_no_patch(const char* path);
|
|
// Guest path aliases: a guest prefix such as "/savedata0" (a save-data mount point) resolves to a host
|
|
// directory instead of the run directory; the prefix matches whole path components only.
|
|
extern "C" void AddPathAlias_nid_no_patch(const char* guestPrefix, const char* hostPath);
|
|
extern "C" void RemovePathAlias_nid_no_patch(const char* guestPrefix);
|
|
extern "C" void RecordWrittenPath_nid_no_patch(const std::filesystem::path& path);
|
|
extern "C" std::vector<std::filesystem::path> WrittenPaths_nid_no_patch();
|
|
extern "C" void SyncWrittenPaths_nid_no_patch();
|
|
extern "C" void BlockPathAlias_nid_no_patch(const char* guestPrefix);
|
|
#ifdef _WIN32
|
|
extern "C" int WindowsOpenError_nid_no_patch(unsigned long error);
|
|
#endif
|
|
|
|
#define APS5_INVALID_ARG_EX throw std::invalid_argument(std::string(__func__) + ": invalid argument")
|
|
|
|
#define APS5_DUMMY_FUN \
|
|
int DummyFunction_nid_no_patch() { \
|
|
NotImplemented_nid_no_patch(__func__); \
|
|
return 0; \
|
|
}
|
|
|
|
#endif
|