From 8e5e9be236e11e263c4f037c401af1a4c1772c16 Mon Sep 17 00:00:00 2001 From: Queuze <58829992+lucaslima430@users.noreply.github.com> Date: Sun, 1 Nov 2026 06:15:20 -0300 Subject: [PATCH 1/4] fix(libc): map native stream read errors --- core/libs/prx/libc/src/FileAndHeap.cpp | 5 + core/libs/prx/libc/src/StandardStreams.cpp | 16 ++ core/libs/tests/FileStreams.cpp | 290 +++++++++++++++++++++ 3 files changed, 311 insertions(+) diff --git a/core/libs/prx/libc/src/FileAndHeap.cpp b/core/libs/prx/libc/src/FileAndHeap.cpp index d942dbff418..fd13b13b9f9 100644 --- a/core/libs/prx/libc/src/FileAndHeap.cpp +++ b/core/libs/prx/libc/src/FileAndHeap.cpp @@ -553,8 +553,13 @@ size_t APS5_VABI fread_nid_postfix(void* buffer, size_t size, size_t count, File return count; } if (!stream->SwitchToReading()) return 0; + const int previousError = errno; + errno = 0; const auto result = std::fread(buffer, size, count, handle); + const int nativeError = errno; stream->SyncStatus(); + if (nativeError != 0) errno = GuestErrnoFromHost_nid_no_patch(nativeError); + else errno = previousError; stream->KeepDirectoryReadError(result < count); return result; } diff --git a/core/libs/prx/libc/src/StandardStreams.cpp b/core/libs/prx/libc/src/StandardStreams.cpp index 8819a6175d9..728b1d77272 100644 --- a/core/libs/prx/libc/src/StandardStreams.cpp +++ b/core/libs/prx/libc/src/StandardStreams.cpp @@ -1,6 +1,7 @@ #include "prx/libc/include/Api.hpp" #include "prx/libc/include/FileStream.hpp" #include "prx/libc/include/General.hpp" +#include "prx/libc/include/HostErrno.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include #include @@ -91,8 +92,13 @@ int APS5_VABI fgetc_nid_postfix(FileStream* stream) { if (stream && !stream->IsOpen()) { errno = 9; return -1; } auto* native = GetNativeStream(stream); if (!stream->SwitchToReading()) return -1; + const int previousError = errno; + errno = 0; const int result = std::fgetc(native); + const int nativeError = errno; stream->SyncStatus(); + if (nativeError != 0) errno = GuestErrnoFromHost_nid_no_patch(nativeError); + else errno = previousError; stream->KeepDirectoryReadError(result == -1); return result; } @@ -148,12 +154,17 @@ int APS5_VABI getc_unlocked_nid_postfix(FileStream* stream) { if (stream && !stream->IsOpen()) { errno = 9; return -1; } auto* native = GetNativeStream(stream); if (!stream->SwitchToReadingUnlocked()) return -1; + const int previousError = errno; + errno = 0; #ifdef _WIN32 const int result = _fgetc_nolock(native); #else const int result = getc_unlocked(native); #endif + const int nativeError = errno; stream->SyncUnlockedStatus(); + if (nativeError != 0) errno = GuestErrnoFromHost_nid_no_patch(nativeError); + else errno = previousError; stream->KeepDirectoryReadError(result == -1); return result; } @@ -228,8 +239,13 @@ char* APS5_VABI fgets_nid_postfix(char* buffer, int size, FileStream* stream) { } auto* native = GetNativeStream(stream); if (!stream->SwitchToReading()) return nullptr; + const int previousError = errno; + errno = 0; auto* result = std::fgets(buffer, size, native); + const int nativeError = errno; stream->SyncStatus(); + if (nativeError != 0) errno = GuestErrnoFromHost_nid_no_patch(nativeError); + else errno = previousError; stream->KeepDirectoryReadError(result == nullptr); return result; } diff --git a/core/libs/tests/FileStreams.cpp b/core/libs/tests/FileStreams.cpp index 8a0603b2e04..9cb8d96b407 100644 --- a/core/libs/tests/FileStreams.cpp +++ b/core/libs/tests/FileStreams.cpp @@ -45,6 +45,295 @@ static void ExpectException(TAction action) { throw std::runtime_error("Expected a stream exception"); } +static void CheckReadErrnoAndStatus(const char* path) { + { + auto* stream = fopen_nid_postfix(path, "wb"); + Require(stream != nullptr); + constexpr char payload[] = "hello world\n"; + Require(fwrite_nid_postfix(payload, 1, sizeof(payload) - 1, stream) == sizeof(payload) - 1); + Require(fclose_nid_postfix(stream) == 0); + } + { + auto* stream = fopen_nid_postfix(path, "rb"); + Require(stream != nullptr); + std::array buffer{}; + errno = 35; + Require(fread_nid_postfix(buffer.data(), 0, 10, stream) == 0); + Require(errno == 35); + Require(fread_nid_postfix(buffer.data(), 10, 0, stream) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(stream) == 0); + + Require(fread_nid_postfix(buffer.data(), 1, 5, stream) == 5); + Require(std::memcmp(buffer.data(), "hello", 5) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(stream) == 0); + + Require(fgetc_nid_postfix(stream) == ' '); + Require(errno == 35); + Require(ferror_nid_postfix(stream) == 0); + + Require(getc_unlocked_nid_postfix(stream) == 'w'); + Require(errno == 35); + Require(ferror_unlocked_nid_postfix(stream) == 0); + + std::array lineBuffer{}; + Require(fgets_nid_postfix(lineBuffer.data(), static_cast(lineBuffer.size()), stream) == lineBuffer.data()); + Require(std::strcmp(lineBuffer.data(), "orld\n") == 0); + Require(errno == 35); + Require(ferror_nid_postfix(stream) == 0); + + Require(fread_nid_postfix(buffer.data(), 1, buffer.size(), stream) == 0); + Require(feof_nid_postfix(stream) != 0); + Require(ferror_nid_postfix(stream) == 0); + Require(errno == 35); + + Require(fgetc_nid_postfix(stream) == EOF); + Require(feof_nid_postfix(stream) != 0); + Require(ferror_nid_postfix(stream) == 0); + Require(errno == 35); + + Require(getc_unlocked_nid_postfix(stream) == EOF); + Require(feof_unlocked_nid_postfix(stream) != 0); + Require(ferror_unlocked_nid_postfix(stream) == 0); + Require(errno == 35); + + Require(fgets_nid_postfix(lineBuffer.data(), static_cast(lineBuffer.size()), stream) == nullptr); + Require(feof_nid_postfix(stream) != 0); + Require(ferror_nid_postfix(stream) == 0); + Require(errno == 35); + + Require(fclose_nid_postfix(stream) == 0); + } +#ifndef _WIN32 + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + buffer.fill('Z'); + errno = 0; + Require(fread_nid_postfix(buffer.data(), 1, buffer.size(), &pipe) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + Require(feof_nid_postfix(&pipe) == 0); + Require(buffer[0] == 'Z'); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + errno = 0; + Require(fgetc_nid_postfix(&pipe) == EOF); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + Require(feof_nid_postfix(&pipe) == 0); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + errno = 0; + Require(getc_unlocked_nid_postfix(&pipe) == EOF); + Require(errno == 35); + Require(ferror_unlocked_nid_postfix(&pipe) != 0); + Require(feof_unlocked_nid_postfix(&pipe) == 0); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + buffer.fill('Z'); + errno = 0; + Require(fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &pipe) == nullptr); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + Require(feof_nid_postfix(&pipe) == 0); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + buffer.fill('A'); + errno = 35; + Require(fread_nid_postfix(buffer.data(), 0, 4, &pipe) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) == 0); + Require(fread_nid_postfix(buffer.data(), 4, 0, &pipe) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) == 0); + Require(buffer[0] == 'A'); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + Require(::write(descriptors[1], "ab", 2) == 2); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + buffer.fill('Z'); + errno = 0; + Require(fread_nid_postfix(buffer.data(), 4, 1, &pipe) == 0); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + Require(buffer[0] == 'a' && buffer[1] == 'b' && buffer[2] == 'Z' && buffer[3] == 'Z'); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + Require(::write(descriptors[1], "abc", 3) == 3); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + buffer.fill('?'); + errno = 0; + char* const result = fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &pipe); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + if (result != nullptr) { + Require(result == buffer.data()); + Require(buffer[0] == 'a' && buffer[1] == 'b' && buffer[2] == 'c'); + } + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + Require(::write(descriptors[1], "hello\n", 6) == 6); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + errno = 35; + Require(fgetc_nid_postfix(&pipe) == 'h'); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) == 0); + Require(getc_unlocked_nid_postfix(&pipe) == 'e'); + Require(errno == 35); + Require(ferror_unlocked_nid_postfix(&pipe) == 0); + Require(fread_nid_postfix(buffer.data(), 1, 2, &pipe) == 2); + Require(buffer[0] == 'l' && buffer[1] == 'l'); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) == 0); + char* const line = fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &pipe); + Require(line == buffer.data()); + Require(std::strcmp(buffer.data(), "o\n") == 0); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) == 0); + pipe.Close(); + } + Require(::close(descriptors[1]) == 0); + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + Require(::close(descriptors[1]) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + std::array buffer{}; + errno = 35; + Require(fread_nid_postfix(buffer.data(), 1, buffer.size(), &pipe) == 0); + Require(feof_nid_postfix(&pipe) != 0); + Require(ferror_nid_postfix(&pipe) == 0); + Require(errno == 35); + + Require(fgetc_nid_postfix(&pipe) == EOF); + Require(feof_nid_postfix(&pipe) != 0); + Require(ferror_nid_postfix(&pipe) == 0); + Require(errno == 35); + + Require(getc_unlocked_nid_postfix(&pipe) == EOF); + Require(feof_unlocked_nid_postfix(&pipe) != 0); + Require(ferror_unlocked_nid_postfix(&pipe) == 0); + Require(errno == 35); + + Require(fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &pipe) == nullptr); + Require(feof_nid_postfix(&pipe) != 0); + Require(ferror_nid_postfix(&pipe) == 0); + Require(errno == 35); + + pipe.Close(); + } + } + { + int descriptors[2]; + Require(::pipe(descriptors) == 0); + Require(::fcntl(descriptors[0], F_SETFL, ::fcntl(descriptors[0], F_GETFL) | O_NONBLOCK) == 0); + { + FileStream pipe(::fdopen(descriptors[0], "rb")); + errno = 0; + Require(fgetc_nid_postfix(&pipe) == EOF); + Require(errno == 35); + Require(ferror_nid_postfix(&pipe) != 0); + + Require(::write(descriptors[1], "xy", 2) == 2); + std::array buffer{}; + errno = 35; + Require(fread_nid_postfix(buffer.data(), 1, 2, &pipe) == 2); + Require(buffer[0] == 'x' && buffer[1] == 'y'); + Require(ferror_nid_postfix(&pipe) != 0); + Require(errno == 35); + + Require(::close(descriptors[1]) == 0); + descriptors[1] = -1; + + errno = 35; + Require(fread_nid_postfix(buffer.data(), 1, buffer.size(), &pipe) == 0); + Require(feof_nid_postfix(&pipe) != 0); + Require(ferror_nid_postfix(&pipe) != 0); + Require(errno == 35); + + Require(fgetc_nid_postfix(&pipe) == EOF); + Require(errno == 35); + + Require(getc_unlocked_nid_postfix(&pipe) == EOF); + Require(errno == 35); + + Require(fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &pipe) == nullptr); + Require(errno == 35); + + pipe.Close(); + } + if (descriptors[1] >= 0) ::close(descriptors[1]); + } +#endif +} + static void ReplaceWithReadOnlyDescriptor(FileStream* stream, const char* path) { #ifdef _WIN32 const int descriptor = _open(path, _O_RDONLY | _O_BINARY); @@ -488,6 +777,7 @@ int main(int argc, char** argv) { CheckZeroSizedTransfers(argv[1]); CheckUpdateStreamReadsAfterWrites(argv[1]); CheckStreamWritesAfterReads(argv[1]); + CheckReadErrnoAndStatus(argv[1]); Require(_Stdout_nid_postfix.GetHandle() == stdout); Require(_Stderr_nid_postfix.GetHandle() == stderr); Require(fputs_nid_postfix("stdout object works\n", &_Stdout_nid_postfix) >= 0); From 4c34b46ff96e67e3f36ad3c3f6335118b7999747 Mon Sep 17 00:00:00 2001 From: Queuze <58829992+lucaslima430@users.noreply.github.com> Date: Sun, 1 Nov 2026 06:21:56 -0300 Subject: [PATCH 2/4] fix(libc): map read transition failures --- core/libs/prx/libc/src/FileAndHeap.cpp | 2 +- core/libs/prx/libc/src/StandardStreams.cpp | 6 ++-- core/libs/tests/FileStreams.cpp | 41 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/core/libs/prx/libc/src/FileAndHeap.cpp b/core/libs/prx/libc/src/FileAndHeap.cpp index fd13b13b9f9..526e4e85d0f 100644 --- a/core/libs/prx/libc/src/FileAndHeap.cpp +++ b/core/libs/prx/libc/src/FileAndHeap.cpp @@ -552,9 +552,9 @@ size_t APS5_VABI fread_nid_postfix(void* buffer, size_t size, size_t count, File stream->SyncStatus(); return count; } - if (!stream->SwitchToReading()) return 0; const int previousError = errno; errno = 0; + if (!stream->SwitchToReading()) { errno = errno != 0 ? GuestErrnoFromHost_nid_no_patch(errno) : previousError; return 0; } const auto result = std::fread(buffer, size, count, handle); const int nativeError = errno; stream->SyncStatus(); diff --git a/core/libs/prx/libc/src/StandardStreams.cpp b/core/libs/prx/libc/src/StandardStreams.cpp index 728b1d77272..8f2975401e1 100644 --- a/core/libs/prx/libc/src/StandardStreams.cpp +++ b/core/libs/prx/libc/src/StandardStreams.cpp @@ -91,9 +91,9 @@ int __isthreaded_nid_postfix = 1; int APS5_VABI fgetc_nid_postfix(FileStream* stream) { if (stream && !stream->IsOpen()) { errno = 9; return -1; } auto* native = GetNativeStream(stream); - if (!stream->SwitchToReading()) return -1; const int previousError = errno; errno = 0; + if (!stream->SwitchToReading()) { errno = errno != 0 ? GuestErrnoFromHost_nid_no_patch(errno) : previousError; return -1; } const int result = std::fgetc(native); const int nativeError = errno; stream->SyncStatus(); @@ -153,9 +153,9 @@ int APS5_VABI getc_nid_postfix(FileStream* stream) { return fgetc_nid_postfix(st int APS5_VABI getc_unlocked_nid_postfix(FileStream* stream) { if (stream && !stream->IsOpen()) { errno = 9; return -1; } auto* native = GetNativeStream(stream); - if (!stream->SwitchToReadingUnlocked()) return -1; const int previousError = errno; errno = 0; + if (!stream->SwitchToReadingUnlocked()) { errno = errno != 0 ? GuestErrnoFromHost_nid_no_patch(errno) : previousError; return -1; } #ifdef _WIN32 const int result = _fgetc_nolock(native); #else @@ -238,9 +238,9 @@ char* APS5_VABI fgets_nid_postfix(char* buffer, int size, FileStream* stream) { return nullptr; } auto* native = GetNativeStream(stream); - if (!stream->SwitchToReading()) return nullptr; const int previousError = errno; errno = 0; + if (!stream->SwitchToReading()) { errno = errno != 0 ? GuestErrnoFromHost_nid_no_patch(errno) : previousError; return nullptr; } auto* result = std::fgets(buffer, size, native); const int nativeError = errno; stream->SyncStatus(); diff --git a/core/libs/tests/FileStreams.cpp b/core/libs/tests/FileStreams.cpp index 9cb8d96b407..e73e3067e6d 100644 --- a/core/libs/tests/FileStreams.cpp +++ b/core/libs/tests/FileStreams.cpp @@ -29,6 +29,9 @@ #include #else #include +#ifdef __linux__ +#include +#endif #endif static void Require(bool condition, const char* message = "File stream check failed") { @@ -331,6 +334,44 @@ static void CheckReadErrnoAndStatus(const char* path) { } if (descriptors[1] >= 0) ::close(descriptors[1]); } +#ifdef __linux__ + for (int reader = 0; reader < 4; ++reader) { + int descriptors[2]; + Require(::socketpair(AF_UNIX, SOCK_STREAM, 0, descriptors) == 0); + const int flags = ::fcntl(descriptors[0], F_GETFL); + Require(flags >= 0 && ::fcntl(descriptors[0], F_SETFL, flags | O_NONBLOCK) == 0); + auto* native = ::fdopen(descriptors[0], "r+"); + Require(native != nullptr); + std::array nativeBuffer{}; + Require(std::setvbuf(native, nativeBuffer.data(), _IOFBF, nativeBuffer.size()) == 0); + FileStream stream(native); + Require(std::fwrite("pending", 1, 7, native) == 7); + std::array chunk{}; + bool blocked = false; + for (int attempt = 0; attempt < 10000; ++attempt) { + if (::write(descriptors[0], chunk.data(), chunk.size()) < 0) { + Require(errno == EAGAIN || errno == EWOULDBLOCK); + blocked = true; + break; + } + } + Require(blocked); + std::array buffer{}; + buffer.fill('!'); + errno = 35; + switch (reader) { + case 0: Require(fread_nid_postfix(buffer.data(), 1, buffer.size(), &stream) == 0); break; + case 1: Require(fgetc_nid_postfix(&stream) == EOF); break; + case 2: Require(getc_unlocked_nid_postfix(&stream) == EOF); break; + case 3: Require(fgets_nid_postfix(buffer.data(), static_cast(buffer.size()), &stream) == nullptr); break; + } + Require(errno == 35, "Read transition leaked native errno"); + Require(ferror_nid_postfix(&stream) != 0 && feof_nid_postfix(&stream) == 0); + Require(std::all_of(buffer.begin(), buffer.end(), [](char byte) { return byte == '!'; })); + static_cast(stream.Close()); + Require(::close(descriptors[1]) == 0); + } +#endif #endif } From 71bc2e6fdb2af095d6c01f26744b5796a8a46719 Mon Sep 17 00:00:00 2001 From: Queuze <58829992+lucaslima430@users.noreply.github.com> Date: Sun, 1 Nov 2026 12:16:05 -0300 Subject: [PATCH 3/4] test: separate stream error regression calls --- core/libs/tests/FileStreams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/libs/tests/FileStreams.cpp b/core/libs/tests/FileStreams.cpp index e73e3067e6d..f0b9d2e4e52 100644 --- a/core/libs/tests/FileStreams.cpp +++ b/core/libs/tests/FileStreams.cpp @@ -816,9 +816,9 @@ int main(int argc, char** argv) { CheckExclusiveCppOpen(argv[1]); CheckShortCharacterScans(); CheckZeroSizedTransfers(argv[1]); + CheckReadErrnoAndStatus(argv[1]); CheckUpdateStreamReadsAfterWrites(argv[1]); CheckStreamWritesAfterReads(argv[1]); - CheckReadErrnoAndStatus(argv[1]); Require(_Stdout_nid_postfix.GetHandle() == stdout); Require(_Stderr_nid_postfix.GetHandle() == stderr); Require(fputs_nid_postfix("stdout object works\n", &_Stdout_nid_postfix) >= 0); From 0873e3d4e976d1b85790fac939e51bf2ab728abf Mon Sep 17 00:00:00 2001 From: Queuze <58829992+lucaslima430@users.noreply.github.com> Date: Wed, 4 Nov 2026 20:35:29 -0300 Subject: [PATCH 4/4] test(libc): avoid fcloseall fixture overlap --- core/libs/tests/FileStreams.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/libs/tests/FileStreams.cpp b/core/libs/tests/FileStreams.cpp index 92562a1c6c9..014d9d281f1 100644 --- a/core/libs/tests/FileStreams.cpp +++ b/core/libs/tests/FileStreams.cpp @@ -12,6 +12,9 @@ #include #include #include +#ifdef __linux__ +#include +#endif #include #include #include @@ -29,9 +32,6 @@ #include #else #include -#ifdef __linux__ -#include -#endif #endif static void Require(bool condition, const char* message = "File stream check failed") { @@ -962,9 +962,9 @@ int main(int argc, char** argv) { Require(argc == 2); CheckExclusiveCppOpen(argv[1]); CheckShortCharacterScans(); + CheckReadErrnoAndStatus(argv[1]); CheckOrdinaryCharacterScans(); CheckZeroSizedTransfers(argv[1]); - CheckReadErrnoAndStatus(argv[1]); CheckUpdateStreamReadsAfterWrites(argv[1]); CheckStreamWritesAfterReads(argv[1]); Require(_Stdout_nid_postfix.GetHandle() == stdout);