From 88094c48ae93c9894383bc91f03b73b827909fd1 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Fri, 20 Oct 2023 11:37:52 +0100 Subject: [PATCH] [*] Harden pipe reads under FS streams --- Source/IO/FS/FileStream.NT.cpp | 26 ++++++++++++---- Source/IO/FS/FileStream.Unix.cpp | 51 ++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/Source/IO/FS/FileStream.NT.cpp b/Source/IO/FS/FileStream.NT.cpp index 1228664c..7d56f562 100644 --- a/Source/IO/FS/FileStream.NT.cpp +++ b/Source/IO/FS/FileStream.NT.cpp @@ -145,13 +145,15 @@ namespace Aurora::IO::FS { OVERLAPPED overlapped {}; AuUInt64 uOffset {}; + + parameters.outVariable = 0; if (!this->pHandle_) { SysPushErrorUninitialized(); return 0; } - + auto hHandle = this->GetWin32Handle(true); HANDLE hEventHandle { INVALID_HANDLE_VALUE }; @@ -161,6 +163,22 @@ namespace Aurora::IO::FS return {}; } + AuUInt64 uLength = parameters.length; + if (this->pHandle_->IsPipe()) + { + DWORD uAvail {}; + if (!PeekNamedPipe(hHandle, NULL, NULL, NULL, &uAvail, NULL)) + { + return false; + } + + uLength = AuMin(uLength, uAvail); + if (!uLength) + { + return true; + } + } + bool bIsAsync = this->pHandle_->IsAsync(); if (bIsAsync) { @@ -172,9 +190,6 @@ namespace Aurora::IO::FS } } - parameters.outVariable = 0; - - AuUInt64 uLength = parameters.length; while (uLength) { DWORD read {}; @@ -247,6 +262,8 @@ namespace Aurora::IO::FS { OVERLAPPED overlapped {}; AuUInt64 uOffset {}; + + parameters.outVariable = 0; auto optHandle = this->GetHandle()->GetOSWriteHandleSafe(); if (!optHandle) @@ -275,7 +292,6 @@ namespace Aurora::IO::FS return false; } } - parameters.outVariable = 0; AuUInt64 uLength = parameters.length; while (uLength) diff --git a/Source/IO/FS/FileStream.Unix.cpp b/Source/IO/FS/FileStream.Unix.cpp index 55267f1c..f940e16a 100755 --- a/Source/IO/FS/FileStream.Unix.cpp +++ b/Source/IO/FS/FileStream.Unix.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #if !defined(_AURUNTIME_GENERICFILESTREAM) @@ -237,7 +238,6 @@ namespace Aurora::IO::FS parameters.outVariable = 0; - if (!this->pHandle_) { SysPushErrorUninitialized(); @@ -251,30 +251,49 @@ namespace Aurora::IO::FS return 0; } - auto length = parameters.length; - AuUInt offset {0}; - while (length) + AuUInt uOffset {}; + AuUInt64 uLength = parameters.length; + + if (this->pHandle_->IsPipe()) { - AuUInt32 read; - - int blockSize = AuMin(kFileCopyBlock, length); - - if (!PosixRead(fd, &reinterpret_cast(parameters.ptr)[offset], blockSize, &read)) + #if defined(FIONREAD) + int available {}; + if (::ioctl(fd, FIONREAD, &available) < 0) { - SysPushErrorNested("File Error: {}", path_); + return 0; + } + + uLength = AuMin(uLength, available); + if (!uLength) + { + return 0; + } + #endif + } + + while (uLength) + { + AuUInt32 uRead; + + if (!PosixRead(fd, + &reinterpret_cast(parameters.ptr)[uOffset], + AuMin(kFileCopyBlock, uLength), + &uRead)) + { + SysPushErrorNested("File Error: {}", this->path_); break; } - if (read == 0) + if (uRead == 0) { break; } - offset += read; - length -= read; + uOffset += uRead; + uLength -= uRead; } - parameters.outVariable = offset; + parameters.outVariable = uOffset; return true; } @@ -282,6 +301,8 @@ namespace Aurora::IO::FS { AU_LOCK_GUARD(this->spinlock_); + parameters.outVariable = 0; + if (!this->pHandle_) { SysPushErrorUninitialized(); @@ -295,8 +316,6 @@ namespace Aurora::IO::FS return 0; } - parameters.outVariable = 0; - AuUInt length = parameters.length; AuUInt offset {0}; while (length)