mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-29 12:15:39 +00:00
78 lines
2.7 KiB
C++
78 lines
2.7 KiB
C++
#include "prx/libc/include/Api.hpp"
|
|
#include "prx/libc/include/FileStream.hpp"
|
|
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <cerrno>
|
|
#include <chrono>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iterator>
|
|
#include <string>
|
|
#include <fcntl.h>
|
|
#ifdef _WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <io.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
extern "C" {
|
|
|
|
extern FileStream* __stdoutp_nid_postfix;
|
|
}
|
|
|
|
static void Require(bool value, int line) {
|
|
if (!value) {
|
|
std::fprintf(stderr, "freopen host standard check failed at line %d, errno %d\n", line, errno);
|
|
std::abort();
|
|
}
|
|
}
|
|
#define Check(value) Require((value), __LINE__)
|
|
|
|
#ifdef _WIN32
|
|
static int HostDup(int descriptor) { return ::_dup(descriptor); }
|
|
static int HostDup2(int from, int to) { return ::_dup2(from, to); }
|
|
static int HostClose(int descriptor) { return ::_close(descriptor); }
|
|
static int HostWrite(int descriptor, const char* text, unsigned size) { return ::_write(descriptor, text, size); }
|
|
static int HostFileno(std::FILE* stream) { return ::_fileno(stream); }
|
|
#else
|
|
static int HostDup(int descriptor) { return ::dup(descriptor); }
|
|
static int HostDup2(int from, int to) { return ::dup2(from, to) == to ? 0 : -1; }
|
|
static int HostClose(int descriptor) { return ::close(descriptor); }
|
|
static int HostWrite(int descriptor, const char* text, unsigned size) { return static_cast<int>(::write(descriptor, text, size)); }
|
|
static int HostFileno(std::FILE* stream) { return ::fileno(stream); }
|
|
#endif
|
|
|
|
static std::string Contents(const std::string& name) {
|
|
std::ifstream stream(name, std::ios::binary);
|
|
return std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
|
|
}
|
|
|
|
int main() {
|
|
const auto sinkName = "anyps5-freopen-host-standard-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()) + ".txt";
|
|
std::FILE* sink = std::fopen(sinkName.c_str(), "wb");
|
|
Check(sink != nullptr);
|
|
const int original = HostDup(1);
|
|
Check(original >= 0 && HostDup2(HostFileno(sink), 1) == 0);
|
|
|
|
errno = 0;
|
|
FileStream* const reopened = freopen_nid_postfix("", "w", __stdoutp_nid_postfix);
|
|
const int error = errno;
|
|
|
|
const int written = HostWrite(1, "host", 4);
|
|
const bool restored = HostDup2(original, 1) == 0 && HostClose(original) == 0;
|
|
Check(std::fclose(sink) == 0);
|
|
Check(restored);
|
|
Check(reopened == nullptr);
|
|
Check(error == ENOENT);
|
|
Check(written == 4);
|
|
Check(Contents(sinkName) == "host");
|
|
|
|
errno = 0;
|
|
Check(fputs_nid_postfix("text", __stdoutp_nid_postfix) == -1 && errno == EBADF);
|
|
Check(std::filesystem::remove(sinkName));
|
|
return 0;
|
|
}
|