98 lines
3.8 KiB
C++
98 lines
3.8 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <filesystem>
|
|
#include <string>
|
|
|
|
extern "C" {
|
|
int APS5_VABI tcgetattr_nid_postfix(int, void*);
|
|
int APS5_VABI tcsetattr_nid_postfix(int, int, const void*);
|
|
int APS5_VABI open_nid_postfix(const char*, int, int);
|
|
int APS5_VABI pipe_nid_postfix(int*);
|
|
int APS5_VABI socket_nid_postfix(int, int, int);
|
|
int APS5_VABI close_nid_postfix(int);
|
|
int* APS5_VABI __error_nid_postfix();
|
|
}
|
|
|
|
static void Check(bool value, int line) {
|
|
if (!value) {
|
|
std::fprintf(stderr, "terminal check failed at line %d, errno %d\n", line, *__error_nid_postfix());
|
|
std::abort();
|
|
}
|
|
}
|
|
#define Require(value) Check((value), __LINE__)
|
|
|
|
constexpr int Now = 0;
|
|
constexpr int Drain = 1;
|
|
constexpr int Flush = 2;
|
|
constexpr int Soft = 0x10;
|
|
constexpr int NotTerminal = 25;
|
|
constexpr int BadDescriptor = 9;
|
|
constexpr int InvalidArgument = 22;
|
|
constexpr int BadAddress = 14;
|
|
constexpr int AddressNotAvailable = 49;
|
|
|
|
static bool Fails(int result, int error) { return result == -1 && *__error_nid_postfix() == error; }
|
|
|
|
static void RequireNotTerminal(int descriptor) {
|
|
unsigned char attributes[44];
|
|
std::memset(attributes, 0xaa, sizeof(attributes));
|
|
unsigned char untouched[44];
|
|
std::memset(untouched, 0xaa, sizeof(untouched));
|
|
*__error_nid_postfix() = 0;
|
|
Require(Fails(tcgetattr_nid_postfix(descriptor, attributes), NotTerminal));
|
|
Require(std::memcmp(attributes, untouched, sizeof(attributes)) == 0);
|
|
for (const int action : {Now, Drain, Flush, Now | Soft, Flush | Soft}) {
|
|
*__error_nid_postfix() = 0;
|
|
Require(Fails(tcsetattr_nid_postfix(descriptor, action, attributes), NotTerminal));
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
const auto name = "anyps5-terminal-test-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count());
|
|
const int file = open_nid_postfix(name.c_str(), 0x202, 0644);
|
|
Require(file >= 0);
|
|
RequireNotTerminal(file);
|
|
RequireNotTerminal(0);
|
|
RequireNotTerminal(1);
|
|
RequireNotTerminal(2);
|
|
|
|
int ends[2] = {-1, -1};
|
|
Require(pipe_nid_postfix(ends) == 0);
|
|
RequireNotTerminal(ends[0]);
|
|
RequireNotTerminal(ends[1]);
|
|
|
|
const int socket = socket_nid_postfix(2, 2, 0);
|
|
Require(socket >= 0);
|
|
unsigned char untouched[44];
|
|
std::memset(untouched, 0xaa, sizeof(untouched));
|
|
unsigned char probe[44];
|
|
std::memset(probe, 0xaa, sizeof(probe));
|
|
Require(Fails(tcgetattr_nid_postfix(socket, probe), AddressNotAvailable));
|
|
Require(std::memcmp(probe, untouched, sizeof(probe)) == 0);
|
|
Require(Fails(tcsetattr_nid_postfix(socket, Flush, probe), AddressNotAvailable));
|
|
|
|
unsigned char attributes[44]{};
|
|
Require(Fails(tcsetattr_nid_postfix(file, 3, attributes), InvalidArgument));
|
|
Require(Fails(tcsetattr_nid_postfix(file, -1, attributes), InvalidArgument));
|
|
Require(Fails(tcsetattr_nid_postfix(file, Soft | 3, attributes), InvalidArgument));
|
|
Require(Fails(tcsetattr_nid_postfix(-1, 3, attributes), InvalidArgument));
|
|
Require(Fails(tcsetattr_nid_postfix(file, Now, nullptr), BadAddress));
|
|
Require(Fails(tcsetattr_nid_postfix(-1, Now, nullptr), BadAddress));
|
|
Require(Fails(tcgetattr_nid_postfix(-1, attributes), BadDescriptor));
|
|
Require(Fails(tcsetattr_nid_postfix(-1, Now, attributes), BadDescriptor));
|
|
|
|
Require(close_nid_postfix(socket) == 0);
|
|
Require(Fails(tcgetattr_nid_postfix(socket, attributes), BadDescriptor));
|
|
Require(Fails(tcsetattr_nid_postfix(socket, Now, attributes), BadDescriptor));
|
|
Require(close_nid_postfix(ends[0]) == 0 && close_nid_postfix(ends[1]) == 0);
|
|
Require(close_nid_postfix(file) == 0);
|
|
Require(Fails(tcgetattr_nid_postfix(file, attributes), BadDescriptor));
|
|
Require(Fails(tcsetattr_nid_postfix(file, Flush, attributes), BadDescriptor));
|
|
std::filesystem::remove(name);
|
|
return 0;
|
|
}
|