/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IOHandle.hpp Date: 2023-7-28 Author: Reece ***/ #pragma once #include "FS/EFileAdvisoryLockLevel.hpp" #include "FS/EFileOpenMode.hpp" namespace Aurora::IO { // Note: A handle is never disposable to prevent IO fd use after close // You must ensure RAII and/or shared-ownership release to dispose of the IO resource. // This class is only intended to be a handle view; therefore, it is not possible to close the handle. // // Warning: if for some reason you need to wait until any given handle is closed, // you should ensure the handle is out of scope, then make a call to Aurora::RuntimeWaitForSecondaryTick(); // // You should use the AuIOHandle or AuIO::IOHandle aliases for SOO construction; although, allocating functions AuIO::IOHandleShared/Unique/New are available. struct IIOHandle { struct HandleCreate { /** * "Create" */ bool bFailIfNonEmptyFile {}; /** * Lock level */ FS::EFileAdvisoryLockLevel eAdvisoryLevel; /** * Path */ AuROString path; /** * Mode */ FS::EFileOpenMode eMode; /** * */ bool bAlwaysCreateDirTree { true }; /** * Indicates the handle will be for use with IAsyncTransactions as opposed to IFileStream and AuProcess */ bool bAsyncHandle { false }; /** * Indicates the handle will only ever directly interface with the disk hardware/IO stack, as opposed to leveraging kernel assigned shared user memory. * In this mode, only alignment/chunks of AuUInt32 AuFS::GetLogicalSectorSizeFromPath(const AuString &fileOrDirPath) is guaranteed to be accessible. */ bool bDirectIOMode { false }; /** * Force flush on close? */ bool bFlushOnClose { false }; /** * Auto-truncate? */ bool bWriteEoSOnClose { false }; cstatic HandleCreate Create(const AuROString &path) { HandleCreate create(path); create.bFailIfNonEmptyFile = true; create.eMode = FS::EFileOpenMode::eReadWrite; create.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite; return AuMove(create); } cstatic HandleCreate ReadWrite(const AuROString &path) { HandleCreate create(path); create.eMode = FS::EFileOpenMode::eReadWrite; create.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite; return AuMove(create); } cstatic HandleCreate Read(const AuROString &path) { HandleCreate read(path); read.eMode = FS::EFileOpenMode::eRead; read.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockWrite; return AuMove(read); } cstatic HandleCreate Open(const AuROString &path) { HandleCreate read(path); read.eMode = FS::EFileOpenMode::eRead; read.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite; return AuMove(read); } inline HandleCreate(const AuROString &path) : path(path), eAdvisoryLevel(FS::EFileAdvisoryLockLevel::eNoSafety), eMode(FS::EFileOpenMode::eRead) { } }; virtual bool InitFromHandle(const AuSPtr &pHandle) = 0; virtual bool InitFromHandleCopy(const IIOHandle *pHandle) = 0; virtual bool InitFromPath(HandleCreate create) = 0; virtual bool InitFromCopy(AuUInt64 uOSHandle) = 0; virtual bool InitFromMove(AuUInt64 uOSHandle) = 0; virtual bool InitFromPair(AuOptional optOSReadHandle, AuOptional optOSWriteHandle) = 0; virtual bool InitFromPairMove(AuOptional optOSReadHandle, AuOptional optOSWriteHandle) = 0; virtual bool InitFromStreamEnum(EStandardStream eStream) = 0; virtual bool InitFromSharing(const AuROString &handle) = 0; virtual AuUInt64 GetOSHandle() const = 0; virtual AuOptional GetOSHandleSafe() const = 0; virtual AuUInt64 GetOSReadHandle() const = 0; virtual AuOptional GetOSReadHandleSafe() const = 0; virtual AuUInt64 GetOSWriteHandle() const = 0; virtual AuOptional GetOSWriteHandleSafe() const = 0; virtual bool IsValid() const = 0; virtual bool HasUniqueWriteHandle() const = 0; virtual bool IsAsync() const = 0; virtual const AuString &GetPath() const = 0; virtual bool IsFlushOnClose() const = 0; virtual void SetFlushOnClose(bool bFlushOnClose) = 0; // aka truncate on close virtual bool IsWriteEoSOnClose() const = 0; // aka truncate on close virtual void SetWriteEoSOnClose(bool bWriteEoSOnClose) = 0; virtual bool IsFile() const = 0; virtual bool IsTTY() const = 0; virtual bool IsPipe() const = 0; virtual bool SectionLock(AuUInt64 uOffset, AuUInt64 uLength, FS::EFileAdvisoryLockLevel level) = 0; virtual bool SectionUnlock(AuUInt64 uOffset, AuUInt64 uLength) = 0; virtual AuString SharingGetString() = 0; virtual bool SharingIsShared() = 0; virtual void SharingStop() = 0; virtual AuUInt64 GetFileLength() = 0; }; AUKN_SHARED_SOO_CC(IOHandle, IIOHandle, 192); AUKN_SYM bool IsHandleTTY(AuUInt uHandle); AUKN_SYM bool IsHandlePipe(AuUInt uHandle); AUKN_SYM bool IsHandleFile(AuUInt uHandle); }