2023-07-29 07:02:47 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: AuIOHandle.cpp
|
|
|
|
Date: 2023-7-28
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#include <RuntimeInternal.hpp>
|
|
|
|
#include "AuIOHandle.hpp"
|
2023-09-23 03:38:26 +00:00
|
|
|
#include "FS/FileAdvisory.hpp"
|
2023-07-29 07:02:47 +00:00
|
|
|
|
2024-01-03 02:39:54 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
#include <Aurora/IO/NT/HANDLEPipeServer.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
#include <Aurora/IO/UNIX/UNIX.hpp>
|
|
|
|
#endif
|
|
|
|
|
2023-07-29 07:02:47 +00:00
|
|
|
namespace Aurora::IO
|
|
|
|
{
|
|
|
|
AFileHandle::~AFileHandle()
|
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
if (this->uOSWriteHandle.has_value() && this->uOSReadHandle.has_value() &&
|
|
|
|
this->uOSReadHandle.value() == this->uOSWriteHandle.value())
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
this->CloseHandle(this->uOSReadHandle.value());
|
|
|
|
AuResetMember(this->uOSReadHandle);
|
|
|
|
AuResetMember(this->uOSWriteHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->uOSReadHandle)
|
|
|
|
{
|
|
|
|
this->CloseHandle(this->uOSReadHandle.value());
|
|
|
|
AuResetMember(this->uOSReadHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->uOSWriteHandle)
|
|
|
|
{
|
|
|
|
this->CloseHandle(this->uOSWriteHandle.value());
|
|
|
|
AuResetMember(this->uOSWriteHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AFileHandle::InitFromHandle(AuSPtr<IIOHandle> pHandle)
|
|
|
|
{
|
|
|
|
auto pSrc = AuStaticCast<AFileHandle>(pHandle);
|
|
|
|
auto pDest = this;
|
|
|
|
|
|
|
|
if (this->IsValid())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pDest->pThat = pHandle;
|
|
|
|
pDest->uOSReadHandle = pSrc->uOSReadHandle;
|
|
|
|
pDest->uOSWriteHandle = pSrc->uOSWriteHandle;
|
|
|
|
pDest->bIsAsync = pSrc->bIsAsync;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AFileHandle::InitFromCopy(AuUInt64 uOSHandle)
|
|
|
|
{
|
|
|
|
if (this->IsValid())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto uOSWriteHandle = this->DupHandle(uOSHandle, true))
|
|
|
|
{
|
|
|
|
this->uOSReadHandle = uOSWriteHandle;
|
|
|
|
this->uOSWriteHandle = uOSWriteHandle;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AFileHandle::InitFromMove(AuUInt64 uOSHandle)
|
|
|
|
{
|
|
|
|
if (this->IsValid())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->uOSReadHandle = uOSHandle;
|
|
|
|
this->uOSWriteHandle = uOSHandle;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:52:51 +00:00
|
|
|
bool AFileHandle::InitFromPair(AuOptionalEx<AuUInt64> optOSReadHandle,
|
|
|
|
AuOptionalEx<AuUInt64> optOSWriteHandle)
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
if (this->IsValid())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
if (optOSReadHandle)
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
if (auto uOSReadHandle2 = this->DupHandle(optOSReadHandle.value(), false))
|
|
|
|
{
|
|
|
|
this->uOSReadHandle = uOSReadHandle2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
if (optOSWriteHandle)
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
if (auto uOSWriteHandle2 = this->DupHandle(optOSWriteHandle.value(), true))
|
|
|
|
{
|
|
|
|
this->uOSWriteHandle = uOSWriteHandle2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->CloseHandle(this->uOSReadHandle.value());
|
|
|
|
AuResetMember(this->uOSReadHandle);
|
|
|
|
return {};
|
|
|
|
}
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:52:51 +00:00
|
|
|
bool AFileHandle::InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
|
|
|
AuOptionalEx<AuUInt64> uOSWriteHandle)
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
if (this->IsValid())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->uOSReadHandle = uOSReadHandle;
|
|
|
|
this->uOSWriteHandle = uOSWriteHandle;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-09-13 01:50:53 +00:00
|
|
|
bool AFileHandle::InitFromStreamEnum(EStandardStream eStream)
|
|
|
|
{
|
|
|
|
switch (eStream)
|
|
|
|
{
|
|
|
|
case EStandardStream::eInputStream:
|
|
|
|
this->InitStdIn();
|
|
|
|
return this->IsValid();
|
|
|
|
case EStandardStream::eErrorStream:
|
|
|
|
case EStandardStream::eOutputStream:
|
|
|
|
this->InitStdOut(eStream == EStandardStream::eErrorStream);
|
|
|
|
return this->IsValid();
|
|
|
|
default:
|
|
|
|
SysPushErrorArg();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::IsFile() const
|
2023-08-29 00:24:52 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::IsTTY() const
|
2023-08-29 00:24:52 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-01-02 00:00:47 +00:00
|
|
|
bool AFileHandle::IsFlushOnClose() const
|
|
|
|
{
|
|
|
|
return this->bFlushOnClose;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AFileHandle::SetFlushOnClose(bool bFlushOnClose)
|
|
|
|
{
|
|
|
|
this->bFlushOnClose = bFlushOnClose;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::IsPipe() const
|
2023-08-29 00:24:52 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:52:51 +00:00
|
|
|
AuOptionalEx<AuUInt64> AFileHandle::GetOSHandleSafe() const
|
2023-08-15 13:41:49 +00:00
|
|
|
{
|
|
|
|
if (auto write = this->uOSWriteHandle)
|
|
|
|
{
|
|
|
|
return write;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto read = this->uOSReadHandle)
|
|
|
|
{
|
|
|
|
return read;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
AuUInt64 AFileHandle::GetOSHandle() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 08:52:51 +00:00
|
|
|
return this->uOSReadHandle.ValueOr(this->uOSWriteHandle.value());
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
AuUInt64 AFileHandle::GetOSReadHandle() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
return this->uOSReadHandle.value();
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:52:51 +00:00
|
|
|
AuOptionalEx<AuUInt64> AFileHandle::GetOSReadHandleSafe() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
return this->uOSReadHandle;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
AuUInt64 AFileHandle::GetOSWriteHandle() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
return this->uOSWriteHandle.value();
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 08:52:51 +00:00
|
|
|
AuOptionalEx<AuUInt64> AFileHandle::GetOSWriteHandleSafe() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
return this->uOSWriteHandle;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::IsValid() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
return this->uOSReadHandle ||
|
|
|
|
this->uOSWriteHandle;
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::HasUniqueWriteHandle() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
2023-12-18 05:32:38 +00:00
|
|
|
return bool(this->uOSWriteHandle);
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
bool AFileHandle::IsAsync() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
return this->bIsAsync;
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
AuString AFileHandle::GetPath() const
|
2023-07-29 07:02:47 +00:00
|
|
|
{
|
|
|
|
return this->path;
|
|
|
|
}
|
2023-09-23 03:38:26 +00:00
|
|
|
|
|
|
|
bool AFileHandle::SectionLock(AuUInt64 uOffset,
|
|
|
|
AuUInt64 uLength,
|
|
|
|
FS::EFileAdvisoryLockLevel level)
|
|
|
|
{
|
|
|
|
return FS::ApplyFileSectionLock(AuUnsafeRaiiToShared(this), level, uOffset, uLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AFileHandle::SectionUnlock(AuUInt64 uOffset,
|
|
|
|
AuUInt64 uLength)
|
|
|
|
{
|
|
|
|
return FS::UnapplyFileSectionLock(AuUnsafeRaiiToShared(this), uOffset, uLength);
|
|
|
|
}
|
2023-09-28 10:53:42 +00:00
|
|
|
|
2024-01-03 02:39:54 +00:00
|
|
|
bool AFileHandle::InitFromSharing(const AuString &handle)
|
|
|
|
{
|
|
|
|
if (this->uOSReadHandle ||
|
|
|
|
this->uOSWriteHandle)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
auto hHandle = NT::ShareFileDescriptorAccept(handle);
|
|
|
|
if (hHandle == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto uOSWriteHandle = AuUInt(hHandle);
|
|
|
|
this->uOSReadHandle = uOSWriteHandle;
|
|
|
|
this->uOSWriteHandle = uOSWriteHandle;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
auto iHandle = UNIX::ShareFileDescriptorAccept(handle);
|
|
|
|
if (iHandle == -1 ||
|
|
|
|
iHandle == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto uOSWriteHandle = AuUInt(iHandle);
|
|
|
|
this->uOSReadHandle = uOSWriteHandle;
|
|
|
|
this->uOSWriteHandle = uOSWriteHandle;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
AuString AFileHandle::SharingGetString()
|
|
|
|
{
|
|
|
|
AuString handle;
|
|
|
|
|
|
|
|
if (this->pIPCString)
|
|
|
|
{
|
|
|
|
return *this->pIPCString;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
handle = NT::ShareFileDescriptor((HANDLE)this->GetOSHandleSafe().ValueOr(-1));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
handle = UNIX::ShareFileDescriptor((HANDLE)this->GetOSHandleSafe().ValueOr(-1));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (handle.empty())
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
this->pIPCString = AuMakeSharedPanic<AuString>(handle);
|
|
|
|
return *this->pIPCString;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AFileHandle::SharingIsShared()
|
|
|
|
{
|
|
|
|
return bool(this->pIPCString);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AFileHandle::SharingStop()
|
|
|
|
{
|
|
|
|
if (auto pString = AuExchange(this->pIPCString, {}))
|
|
|
|
{
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
NT::ShareFileDescriptorStop(*pString);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
UNIX::ShareFileDescriptorStop(*pString);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-28 10:53:42 +00:00
|
|
|
AUKN_SYM IIOHandle *IOHandleNew()
|
|
|
|
{
|
|
|
|
return _new AFileHandle();
|
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM void IOHandleRelease(IIOHandle *pIOHandle)
|
|
|
|
{
|
|
|
|
AuSafeDelete<AFileHandle *>(pIOHandle);
|
|
|
|
}
|
|
|
|
|
2023-12-18 05:32:38 +00:00
|
|
|
AUKN_SYM void IOHandleCopy(IIOHandle *dest, const IIOHandle *source)
|
|
|
|
{
|
|
|
|
AuResetMember(*AuStaticCast<AFileHandle>(dest));
|
|
|
|
dest->InitFromPair(source->GetOSReadHandleSafe(), source->GetOSWriteHandleSafe());
|
|
|
|
}
|
|
|
|
|
2023-09-28 10:53:42 +00:00
|
|
|
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, IOHandle, AFileHandle)
|
2023-07-29 07:02:47 +00:00
|
|
|
}
|