From 3df8621944f459502ed925eab506049a090c7030 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Tue, 15 Aug 2023 14:41:49 +0100 Subject: [PATCH] [+] NT: IOHandle::IsFile(), IOHandle::IsTTY(), IOHandle::IsPipe() [*] Revert to supporting write-only handles --- Include/Aurora/IO/IOHandle.hpp | 8 +++ Source/IO/AuIOHandle.NT.cpp | 101 +++++++++++++++++++++++++++++++ Source/IO/AuIOHandle.cpp | 15 +++++ Source/IO/AuIOHandle.hpp | 2 + Source/IO/FS/FileStream.NT.cpp | 89 ++++++++++++++++++++++----- Source/IO/FS/FileStream.NT.hpp | 2 +- Source/IO/FS/FileStream.Unix.cpp | 4 +- 7 files changed, 204 insertions(+), 17 deletions(-) diff --git a/Include/Aurora/IO/IOHandle.hpp b/Include/Aurora/IO/IOHandle.hpp index b88f67d1..51abc665 100644 --- a/Include/Aurora/IO/IOHandle.hpp +++ b/Include/Aurora/IO/IOHandle.hpp @@ -108,6 +108,8 @@ namespace Aurora::IO virtual AuUInt64 GetOSHandle() = 0; + virtual AuOptionalEx GetOSHandleSafe() = 0; + virtual AuUInt64 GetOSReadHandle() = 0; virtual AuOptionalEx GetOSReadHandleSafe() = 0; @@ -123,6 +125,12 @@ namespace Aurora::IO virtual bool IsAsync() = 0; virtual AuString GetPath() = 0; + + virtual bool IsFile() = 0; + + virtual bool IsTTY() = 0; + + virtual bool IsPipe() = 0; }; AUKN_SHARED_SOO(IOHandle, IIOHandle, 256); diff --git a/Source/IO/AuIOHandle.NT.cpp b/Source/IO/AuIOHandle.NT.cpp index e446a432..b0646c54 100644 --- a/Source/IO/AuIOHandle.NT.cpp +++ b/Source/IO/AuIOHandle.NT.cpp @@ -245,8 +245,109 @@ namespace Aurora::IO return this->IsValid(); } + + bool IsFile() override; + bool IsTTY() override; + bool IsPipe() override; + + AuOptionalEx optIsFile {}; + AuOptionalEx optIsPipe {}; + AuOptionalEx optIsTTY {}; }; + bool NTIOHandle::IsFile() + { + bool bIsFile {}; + DWORD dwType {}; + HANDLE hHandle {}; + + if (auto file = this->optIsFile) + { + return file.value(); + } + + if (auto optHandle = this->GetOSHandleSafe()) + { + hHandle = (HANDLE)optHandle.value(); + } + else + { + SysPushErrorUninitialized(); + return false; + } + + if (!(dwType = GetFileType(hHandle))) + { + return false; + } + + bIsFile = dwType == FILE_TYPE_DISK; + this->optIsFile = bIsFile; + return bIsFile; + } + + bool NTIOHandle::IsTTY() + { + bool bIsTTY {}; + DWORD dwType {}; + HANDLE hHandle {}; + + if (auto file = this->optIsTTY) + { + return file.value(); + } + + if (auto optHandle = this->GetOSHandleSafe()) + { + hHandle = (HANDLE)optHandle.value(); + } + else + { + SysPushErrorUninitialized(); + return false; + } + + if (!(dwType = GetFileType(hHandle))) + { + return false; + } + + bIsTTY = dwType == FILE_TYPE_CHAR; + this->optIsTTY = bIsTTY; + return bIsTTY; + } + + bool NTIOHandle::IsPipe() + { + bool bIsPipe {}; + DWORD dwType {}; + HANDLE hHandle {}; + + if (auto file = this->optIsPipe) + { + return file.value(); + } + + if (auto optHandle = this->GetOSHandleSafe()) + { + hHandle = (HANDLE)optHandle.value(); + } + else + { + SysPushErrorUninitialized(); + return false; + } + + if (!(dwType = GetFileType(hHandle))) + { + return false; + } + + bIsPipe = dwType == FILE_TYPE_PIPE; + this->optIsPipe = bIsPipe; + return bIsPipe; + } + AUKN_SYM IIOHandle *IOHandleNew() { return _new NTIOHandle(); diff --git a/Source/IO/AuIOHandle.cpp b/Source/IO/AuIOHandle.cpp index d210d008..8bc73077 100644 --- a/Source/IO/AuIOHandle.cpp +++ b/Source/IO/AuIOHandle.cpp @@ -126,6 +126,21 @@ namespace Aurora::IO return true; } + AuOptionalEx AFileHandle::GetOSHandleSafe() + { + if (auto write = this->uOSWriteHandle) + { + return write; + } + + if (auto read = this->uOSReadHandle) + { + return read; + } + + return {}; + } + AuUInt64 AFileHandle::GetOSHandle() { return this->uOSReadHandle.ValueOr(this->uOSWriteHandle.Value()); diff --git a/Source/IO/AuIOHandle.hpp b/Source/IO/AuIOHandle.hpp index 2a530d7d..d26b6a7b 100644 --- a/Source/IO/AuIOHandle.hpp +++ b/Source/IO/AuIOHandle.hpp @@ -32,6 +32,8 @@ namespace Aurora::IO AuUInt64 GetOSHandle() override; + AuOptionalEx GetOSHandleSafe() override; + AuUInt64 GetOSReadHandle() override; AuOptionalEx GetOSReadHandleSafe() override; diff --git a/Source/IO/FS/FileStream.NT.cpp b/Source/IO/FS/FileStream.NT.cpp index 40311d3a..43d78e37 100644 --- a/Source/IO/FS/FileStream.NT.cpp +++ b/Source/IO/FS/FileStream.NT.cpp @@ -30,10 +30,25 @@ namespace Aurora::IO::FS { LARGE_INTEGER distance {}; LARGE_INTEGER pos {}; + HANDLE hHandle {}; - auto hHandle = this->GetWin32Handle(); + if (auto pHandle = this->pHandle_) + { + if (!pHandle->IsFile()) + { + SysPushErrorIOResourceRejected(); + return 0; + } - if (hHandle == INVALID_HANDLE_VALUE) + hHandle = this->GetWin32Handle(); + + if (hHandle == INVALID_HANDLE_VALUE) + { + SysPushErrorInvalidFd(); + return 0; + } + } + else { SysPushErrorUninitialized(); return 0; @@ -55,13 +70,28 @@ namespace Aurora::IO::FS { LARGE_INTEGER distance {}; LARGE_INTEGER pos {}; + HANDLE hHandle {}; - auto hHandle = this->GetWin32Handle(); + if (auto pHandle = this->pHandle_) + { + if (!pHandle->IsFile()) + { + SysPushErrorIOResourceRejected(); + return 0; + } - if (hHandle == INVALID_HANDLE_VALUE) + hHandle = this->GetWin32Handle(); + + if (hHandle == INVALID_HANDLE_VALUE) + { + SysPushErrorInvalidFd(); + return 0; + } + } + else { SysPushErrorUninitialized(); - return false; + return 0; } distance.QuadPart = offset; @@ -78,10 +108,25 @@ namespace Aurora::IO::FS AuUInt64 WinFileStream::GetLength() { LARGE_INTEGER length; + HANDLE hHandle {}; - auto hHandle = this->GetWin32Handle(); - - if (hHandle == INVALID_HANDLE_VALUE) + if (auto pHandle = this->pHandle_) + { + if (!pHandle->IsFile()) + { + SysPushErrorIOResourceRejected(); + return 0; + } + + hHandle = this->GetWin32Handle(); + + if (hHandle == INVALID_HANDLE_VALUE) + { + SysPushErrorInvalidFd(); + return 0; + } + } + else { SysPushErrorUninitialized(); return 0; @@ -98,12 +143,18 @@ namespace Aurora::IO::FS bool WinFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters) { - auto hHandle = this->GetWin32Handle(); + if (!this->pHandle_) + { + SysPushErrorUninitialized(); + return 0; + } + + auto hHandle = this->GetWin32Handle(true); HANDLE hEventHandle { INVALID_HANDLE_VALUE }; if (hHandle == INVALID_HANDLE_VALUE) { - SysPushErrorUninitialized(); + SysPushErrorIOResourceRejected(); return {}; } @@ -339,11 +390,21 @@ namespace Aurora::IO::FS return this->pHandle_; } - HANDLE WinFileStream::GetWin32Handle() + HANDLE WinFileStream::GetWin32Handle(bool bReadOnly) { - return this->pHandle_ ? - (HANDLE)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)INVALID_HANDLE_VALUE)) : - INVALID_HANDLE_VALUE; + if (this->pHandle_) + { + if (bReadOnly) + { + return (HANDLE)this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)INVALID_HANDLE_VALUE); + } + else + { + return (HANDLE)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)INVALID_HANDLE_VALUE)); + } + } + + return INVALID_HANDLE_VALUE; } AUKN_SYM AuSPtr OpenBlockingFileStreamFromHandle(AuSPtr pIOHandle) diff --git a/Source/IO/FS/FileStream.NT.hpp b/Source/IO/FS/FileStream.NT.hpp index 20b9fdcd..67b27341 100644 --- a/Source/IO/FS/FileStream.NT.hpp +++ b/Source/IO/FS/FileStream.NT.hpp @@ -28,7 +28,7 @@ namespace Aurora::IO::FS void MakeTemporary() override; AuSPtr GetHandle() override; - HANDLE GetWin32Handle(); + HANDLE GetWin32Handle(bool bReadOnly = false); private: AuSPtr pHandle_; diff --git a/Source/IO/FS/FileStream.Unix.cpp b/Source/IO/FS/FileStream.Unix.cpp index c91599ca..f07126be 100755 --- a/Source/IO/FS/FileStream.Unix.cpp +++ b/Source/IO/FS/FileStream.Unix.cpp @@ -215,10 +215,10 @@ namespace Aurora::IO::FS return 0; } - int fd = this->GetUnixHandle(); + int fd = (int)this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)-1); if (fd == -1) { - SysPushErrorUninitialized(); + SysPushErrorIOResourceRejected(); return 0; }