[+] bool IsHandleFile(AuUInt uHandle)

[+] bool IsHandleTTY(AuUInt uHandle)
[+] bool IsHandlePipe(AuUInt uHandle)
...as opposed to forced IOHandle usage
[+] AuIOHandle
[+] AuSharedIOHandle
This commit is contained in:
Reece Wilson 2023-08-29 01:24:52 +01:00
parent be32e2777f
commit ac0981ac1b
6 changed files with 301 additions and 305 deletions

View File

@ -134,4 +134,10 @@ namespace Aurora::IO
};
AUKN_SHARED_SOO_NC(IOHandle, IIOHandle, 256);
AUKN_SYM bool IsHandleTTY(AuUInt uHandle);
AUKN_SYM bool IsHandlePipe(AuUInt uHandle);
AUKN_SYM bool IsHandleFile(AuUInt uHandle);
}

View File

@ -146,6 +146,9 @@ using AuFutexCond = AuThreading::Waitables::FutexCondWaitable;
template<typename T, bool bIsStatic = false>
using AuTLSVariable = AuThreads::TLSVariable<T, bIsStatic>;
using AuIOHandle = AuIO::IOHandle;
using AuSharedIOHandle = AuSPtr<AuIO::IOHandle>;
#include "Aurora/Async/AuFutures.hpp"
static bool AuIsThreadRunning()

View File

@ -42,310 +42,268 @@ namespace Aurora::IO
struct NTIOHandle final : AFileHandle
{
bool InitFromPath(HandleCreate create) override
bool InitFromPath(HandleCreate create) override;
};
bool NTIOHandle::InitFromPath(HandleCreate create)
{
HANDLE hFileHandle;
DWORD dwFlags {};
DWORD dwShare {};
if (create.path.empty())
{
HANDLE hFileHandle;
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
return false;
}
DWORD dwFlags {};
DWORD dwShare {};
if (!FS::EFileOpenModeIsValid(create.eMode))
{
SysPushErrorParam("Invalid open mode");
return false;
}
if (create.path.empty())
{
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
return false;
}
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
{
SysPushErrorParam("Invalid lock mode");
return false;
}
if (!FS::EFileOpenModeIsValid(create.eMode))
{
SysPushErrorParam("Invalid open mode");
return false;
}
auto pathex = FS::NormalizePathRet(create.path);
if (pathex.empty())
{
SysPushErrorMemory();
return false;
}
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
{
SysPushErrorParam("Invalid lock mode");
return false;
}
auto win32Path = Locale::ConvertFromUTF8(pathex);
if (win32Path.empty())
{
SysPushErrorMemory();
return false;
}
auto pathex = FS::NormalizePathRet(create.path);
if (pathex.empty())
{
SysPushErrorMemory();
return false;
}
hFileHandle = INVALID_HANDLE_VALUE;
auto win32Path = Locale::ConvertFromUTF8(pathex);
if (win32Path.empty())
{
SysPushErrorMemory();
return false;
}
dwShare = FS::NtLockAdvisoryToShare(create.eAdvisoryLevel);
hFileHandle = INVALID_HANDLE_VALUE;
if (create.bAsyncHandle)
{
dwFlags |= FILE_FLAG_OVERLAPPED;
}
dwShare = FS::NtLockAdvisoryToShare(create.eAdvisoryLevel);
if (create.bAsyncHandle)
{
dwFlags |= FILE_FLAG_OVERLAPPED;
}
if (create.bDirectIOMode)
{
dwFlags |= FILE_FLAG_NO_BUFFERING;
this->bDirectIO = true;
}
if (create.bDirectIOMode)
{
dwFlags |= FILE_FLAG_NO_BUFFERING;
this->bDirectIO = true;
}
if (!dwFlags)
if (!dwFlags)
{
dwFlags |= FILE_ATTRIBUTE_NORMAL;
}
switch (create.eMode)
{
case FS::EFileOpenMode::eRead:
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_READ,
dwShare,
NULL,
OPEN_EXISTING,
dwFlags,
NULL);
if (hFileHandle != INVALID_HANDLE_VALUE)
{
dwFlags |= FILE_ATTRIBUTE_NORMAL;
this->uOSReadHandle = AuUInt64(hFileHandle);
}
switch (create.eMode)
break;
}
case FS::EFileOpenMode::eReadWrite:
{
if (create.bAlwaysCreateDirTree)
{
case FS::EFileOpenMode::eRead:
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_READ,
GENERIC_WRITE | GENERIC_READ | DELETE,
NULL,
NULL,
CREATE_NEW,
dwFlags,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare,
NULL,
OPEN_EXISTING,
dwFlags,
NULL);
if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eReadWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
NULL,
NULL,
CREATE_NEW,
dwFlags,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
if (hFileHandle == INVALID_HANDLE_VALUE)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare,
NULL,
OPEN_EXISTING,
CREATE_NEW,
dwFlags,
NULL);
}
}
if (hFileHandle == INVALID_HANDLE_VALUE)
if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | DELETE,
NULL,
NULL,
CREATE_NEW,
dwFlags,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (AuFS::FileExists(pathex.c_str()))
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare,
NULL,
CREATE_NEW,
dwFlags,
NULL);
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eWrite:
else
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE,
dwShare,
NULL,
OPEN_EXISTING,
dwFlags,
NULL);
if (create.bFailIfNonEmptyFile)
if (hFileHandle == INVALID_HANDLE_VALUE)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | DELETE,
NULL,
dwShare,
NULL,
CREATE_NEW,
dwFlags,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE,
dwShare,
NULL,
OPEN_EXISTING,
dwFlags,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
hFileHandle = ::CreateFileW(win32Path.c_str(),
GENERIC_WRITE | DELETE,
dwShare,
NULL,
CREATE_NEW,
dwFlags,
NULL);
}
}
if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
}
if (hFileHandle == INVALID_HANDLE_VALUE)
if (hFileHandle != INVALID_HANDLE_VALUE)
{
SysPushErrorIO("Couldn't open: {}", create.path);
return false;
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
this->bIsAsync = create.bAsyncHandle;
this->path = create.path;
return this->IsValid();
break;
}
}
bool IsFile() override;
bool IsTTY() override;
bool IsPipe() override;
AuOptionalEx<bool> optIsFile {};
AuOptionalEx<bool> optIsPipe {};
AuOptionalEx<bool> optIsTTY {};
};
bool NTIOHandle::IsFile()
{
bool bIsFile {};
DWORD dwType {};
HANDLE hHandle {};
if (auto file = this->optIsFile)
if (hFileHandle == INVALID_HANDLE_VALUE)
{
return file.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
hHandle = (HANDLE)optHandle.value();
}
else
{
SysPushErrorUninitialized();
SysPushErrorIO("Couldn't open: {}", create.path);
return false;
}
if (!(dwType = GetFileType(hHandle)))
{
return false;
}
this->bIsAsync = create.bAsyncHandle;
bIsFile = dwType == FILE_TYPE_DISK;
this->optIsFile = bIsFile;
return bIsFile;
this->path = create.path;
return this->IsValid();
}
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()
AUKN_SYM bool IsHandleTTY(AuUInt uHandle)
{
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)))
if (!uHandle ||
uHandle == (AuUInt)INVALID_HANDLE_VALUE)
{
return false;
}
bIsPipe = dwType == FILE_TYPE_PIPE;
this->optIsPipe = bIsPipe;
return bIsPipe;
if (!(dwType = ::GetFileType((HANDLE)uHandle)))
{
return {};
}
return dwType == FILE_TYPE_CHAR;
}
AUKN_SYM bool IsHandlePipe(AuUInt uHandle)
{
bool bIsPipe {};
DWORD dwType {};
if (!uHandle ||
uHandle == (AuUInt)INVALID_HANDLE_VALUE)
{
return false;
}
if (!(dwType = ::GetFileType((HANDLE)uHandle)))
{
return {};
}
return dwType == FILE_TYPE_PIPE;
}
AUKN_SYM bool IsHandleFile(AuUInt uHandle)
{
bool bIsPipe {};
DWORD dwType {};
if (!uHandle ||
uHandle == (AuUInt)INVALID_HANDLE_VALUE)
{
return false;
}
if (!(dwType = ::GetFileType((HANDLE)uHandle)))
{
return {};
}
return dwType == FILE_TYPE_DISK;
}
AUKN_SYM IIOHandle *IOHandleNew()

View File

@ -55,10 +55,6 @@ namespace Aurora::IO
bool IsFile() override;
bool IsTTY() override;
bool IsPipe() override;
AuOptionalEx<bool> optIsFile {};
AuOptionalEx<bool> optIsPipe {};
AuOptionalEx<bool> optIsTTY {};
};
bool UnixIOHandle::InitFromPath(HandleCreate create)
@ -178,93 +174,50 @@ namespace Aurora::IO
return this->IsValid();
}
bool UnixIOHandle::IsFile()
AUKN_SYM bool IsHandleTTY(AuUInt uHandle)
{
bool bIsFile {};
struct stat st;
int iFileDescriptor {};
if (auto file = this->optIsFile)
if ((AuInt)uHandle < 0)
{
return file.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
iFileDescriptor = (int)optHandle.value();
}
else
{
SysPushErrorUninitialized();
return false;
}
if (::fstat(iFileDescriptor, &st) != 0)
return ::isatty((int)uHandle);
}
AUKN_SYM bool IsHandlePipe(AuUInt uHandle)
{
struct stat st;
if ((AuInt)uHandle < 0)
{
return false;
}
if (::fstat((int)uHandle, &st) != 0)
{
SysPushErrorIO("fstat failed");
return false;
}
bIsFile = S_ISREG(st.st_mode);
this->optIsFile = bIsFile;
return bIsFile;
return S_ISFIFO(st.st_mode);
}
bool UnixIOHandle::IsTTY()
AUKN_SYM bool IsHandleFile(AuUInt uHandle)
{
bool bIsTTY {};
int iFileDescriptor {};
if (auto file = this->optIsTTY)
{
return file.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
iFileDescriptor = (int)optHandle.value();
}
else
{
SysPushErrorUninitialized();
return false;
}
bIsTTY = ::isatty(iFileDescriptor);
this->optIsTTY = bIsTTY;
return bIsTTY;
}
bool UnixIOHandle::IsPipe()
{
bool bIsPipe {};
struct stat st;
int iFileDescriptor {};
if (auto file = this->optIsPipe)
if ((AuInt)uHandle < 0)
{
return file.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
iFileDescriptor = (int)optHandle.value();
}
else
{
SysPushErrorUninitialized();
return false;
}
if (::fstat(iFileDescriptor, &st) != 0)
if (::fstat((int)uHandle, &st) != 0)
{
SysPushErrorIO("fstat failed");
return false;
}
bIsPipe = S_ISFIFO(st.st_mode);
this->optIsPipe = bIsPipe;
return bIsPipe;
return S_ISREG(st.st_mode);
}
AUKN_SYM IIOHandle *IOHandleNew()

View File

@ -126,6 +126,75 @@ namespace Aurora::IO
return true;
}
bool AFileHandle::IsFile()
{
bool bIsFile {};
if (auto optFile = this->optIsFile)
{
return optFile.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
bIsFile = IsHandleFile(optHandle.value());
}
else
{
SysPushErrorUninitialized();
return false;
}
this->optIsFile = bIsFile;
return bIsFile;
}
bool AFileHandle::IsTTY()
{
bool bIsTTY {};
if (auto optTTY = this->optIsTTY)
{
return optTTY.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
bIsTTY = IsHandleTTY(optHandle.value());
}
else
{
SysPushErrorUninitialized();
return false;
}
this->optIsTTY = bIsTTY;
return bIsTTY;
}
bool AFileHandle::IsPipe()
{
bool bIsPipe {};
if (auto optPipe = this->optIsPipe)
{
return optPipe.value();
}
if (auto optHandle = this->GetOSHandleSafe())
{
bIsPipe = IsHandlePipe(optHandle.value());
}
else
{
SysPushErrorUninitialized();
return false;
}
this->optIsPipe = bIsPipe;
return bIsPipe;
}
AuOptionalEx<AuUInt64> AFileHandle::GetOSHandleSafe()
{
if (auto write = this->uOSWriteHandle)

View File

@ -50,6 +50,10 @@ namespace Aurora::IO
AuString GetPath() override;
bool IsFile() override;
bool IsTTY() override;
bool IsPipe() override;
AuOptionalEx<AuUInt64> uOSWriteHandle;
AuOptionalEx<AuUInt64> uOSReadHandle;
AuSPtr<IIOHandle> pThat;
@ -57,6 +61,9 @@ namespace Aurora::IO
AuString path;
IPC::IPCPipeImpl *pIPCPipe {};
bool bDirectIO {};
AuOptionalEx<bool> optIsFile;
AuOptionalEx<bool> optIsPipe;
AuOptionalEx<bool> optIsTTY;
protected:
// Implement me: