[+] AuIO::IO::EStandardStream

[+] AuIO::IOHandle::InitFromStreamEnum(...)
This commit is contained in:
Reece Wilson 2023-09-13 02:50:53 +01:00
parent d0538ea4de
commit b4d5f4c127
8 changed files with 157 additions and 48 deletions

View File

@ -0,0 +1,17 @@
/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EStandardStream.hpp
Date: 2023-9-13
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
AUE_DEFINE_VA(EStandardStream,
eInputStream,
eOutputStream,
eErrorStream
);
}

View File

@ -8,6 +8,7 @@
#pragma once
#include "EStreamError.hpp"
#include "EStandardStream.hpp"
#include "IStreamReader.hpp"
#include "IStreamWriter.hpp"

View File

@ -106,6 +106,8 @@ namespace Aurora::IO
virtual bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
AuOptionalEx<AuUInt64> uOSWriteHandle) = 0;
virtual bool InitFromStreamEnum(EStandardStream eStream) = 0;
virtual AuUInt64 GetOSHandle() = 0;
virtual AuOptionalEx<AuUInt64> GetOSHandleSafe() = 0;

View File

@ -45,6 +45,55 @@ namespace Aurora::IO
AuWin32CloseHandle(hHandle);
}
void AFileHandle::InitStdIn(bool bSharing)
{
HANDLE hHandle =
#if defined(AURORA_PLATFORM_WIN32)
GetStdHandle(STD_INPUT_HANDLE);
#else
Win32Open(L"CONIN$",
GENERIC_READ,
FILE_SHARE_READ,
false,
OPEN_EXISTING,
0,
0);
#endif
if (hHandle != INVALID_HANDLE_VALUE)
{
auto uHandle = AuBuild::kCurrentPlatform == AuBuild::EPlatform::ePlatformWin32 ?
DupHandle((AuUInt64)hHandle, false, bSharing) :
(AuUInt64)hHandle;
this->uOSReadHandle = uHandle;
}
}
void AFileHandle::InitStdOut(bool bError, bool bSharing)
{
HANDLE hHandle =
#if defined(AURORA_PLATFORM_WIN32)
GetStdHandle(bError ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
#else
Win32Open(bError ? L"CONERR$" : L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
false,
OPEN_EXISTING,
0,
0);
#endif
if (hHandle != INVALID_HANDLE_VALUE)
{
auto uHandle = AuBuild::kCurrentPlatform == AuBuild::EPlatform::ePlatformWin32 ?
DupHandle((AuUInt64)hHandle, true, bSharing) :
(AuUInt64)hHandle;
this->uOSWriteHandle = this->uOSReadHandle = uHandle;
}
}
struct NTIOHandle final : AFileHandle
{
bool InitFromPath(HandleCreate create) override;

View File

@ -23,17 +23,49 @@
// Yea, I don't give a shit.
#endif
#if !defined(FD_CLOEXEC)
#define FD_CLOEXEC 0
#endif
namespace Aurora::IO
{
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
{
int fd = dup(uOSHandle);
return DupHandle(uOSHandle, bWriteAccess, false);
}
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess, bool bShareAccess)
{
int fd = ::dup(uOSHandle);
if (fd < 0)
{
return 0;
}
int flags = ::fcntl(fd, F_GETFL, 0);
if (flags == -1)
{
::close(fd);
return 0;
}
if (bShareAccess)
{
flags &= ~FD_CLOEXEC;
}
else
{
flags |= FD_CLOEXEC;
}
flags = ::fcntl(fd, F_SETFL, flags);
if (flags == -1)
{
::close(fd);
return 0;
}
return AuUInt64(fd);
}
@ -48,6 +80,16 @@ namespace Aurora::IO
::close(fd);
}
void AFileHandle::InitStdIn(bool bSharing)
{
this->uOSReadHandle = DupHandle(STDIN_FILENO, false, bSharing);
}
void AFileHandle::InitStdOut(bool bError, bool bSharing)
{
this->uOSReadHandle = this->uOSWriteHandle = DupHandle(bError ? STDERR_FILENO : STDOUT_FILENO, true, bSharing);
}
struct UnixIOHandle final : AFileHandle
{
bool InitFromPath(HandleCreate create) override;

View File

@ -126,6 +126,23 @@ namespace Aurora::IO
return true;
}
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;
}
}
bool AFileHandle::IsFile()
{
bool bIsFile {};

View File

@ -30,6 +30,8 @@ namespace Aurora::IO
bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
bool InitFromStreamEnum(EStandardStream eStream) override;
AuUInt64 GetOSHandle() override;
AuOptionalEx<AuUInt64> GetOSHandleSafe() override;
@ -54,6 +56,9 @@ namespace Aurora::IO
bool IsTTY() override;
bool IsPipe() override;
void InitStdIn(bool bSharing = false);
void InitStdOut(bool bError = false, bool bSharing = false);
AuOptionalEx<AuUInt64> uOSWriteHandle;
AuOptionalEx<AuUInt64> uOSReadHandle;
AuSPtr<IIOHandle> pThat;

View File

@ -295,23 +295,15 @@ namespace Aurora::Processes
}
else if (this->startup_.fwdOut == EStreamForward::eCurrentProcess)
{
HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (hHandle != INVALID_HANDLE_VALUE)
AuResetMember(this->startup_.handleOutStream);
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleOutStream.AsPointer())->InitStdOut(false, true);
auto optHandle = this->startup_.handleOutStream->GetOSHandleSafe();
if (!optHandle)
{
HANDLE hTargetProcess = ::GetCurrentProcess();
if (!::DuplicateHandle(hTargetProcess,
hHandle,
hTargetProcess,
&this->pipeStdOutWrite_,
GENERIC_READ | GENERIC_WRITE,
TRUE,
0))
{
return false;
}
return false;
}
this->pipeStdOutWrite_ = (HANDLE)optHandle.value();
this->bDontRelOut_ = true;
}
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
@ -355,23 +347,15 @@ namespace Aurora::Processes
}
else if (this->startup_.fwdErr == EStreamForward::eCurrentProcess)
{
HANDLE hHandle = GetStdHandle(STD_ERROR_HANDLE);
if (hHandle != INVALID_HANDLE_VALUE)
AuResetMember(this->startup_.handleErrorStream);
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleErrorStream.AsPointer())->InitStdOut(true, true);
auto optHandle = this->startup_.handleErrorStream->GetOSHandleSafe();
if (!optHandle)
{
HANDLE hTargetProcess = ::GetCurrentProcess();
if (!::DuplicateHandle(hTargetProcess,
hHandle,
hTargetProcess,
&this->pipeStdErrWrite_,
GENERIC_READ | GENERIC_WRITE,
TRUE,
0))
{
return false;
}
return false;
}
this->pipeStdErrWrite_ = (HANDLE)optHandle.value();
this->bDontRelErr_ = true;
}
if (this->startup_.fwdIn == EStreamForward::eAsyncPipe)
@ -415,23 +399,15 @@ namespace Aurora::Processes
}
else if (this->startup_.fwdIn == EStreamForward::eCurrentProcess)
{
HANDLE hHandle = GetStdHandle(STD_INPUT_HANDLE);
if (hHandle != INVALID_HANDLE_VALUE)
AuResetMember(this->startup_.handleInputStream);
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleInputStream.AsPointer())->InitStdIn(true);
auto optHandle = this->startup_.handleInputStream->GetOSHandleSafe();
if (!optHandle)
{
HANDLE hTargetProcess = ::GetCurrentProcess();
if (!::DuplicateHandle(hTargetProcess,
hHandle,
hTargetProcess,
&this->pipeStdInRead_,
GENERIC_READ,
TRUE,
0))
{
return false;
}
return false;
}
this->pipeStdInRead_ = (HANDLE)optHandle.value();
this->bDontRelIn_ = true;
}
{
@ -439,7 +415,7 @@ namespace Aurora::Processes
#define NEW_NULL_HANDLE \
{ \
nulFile = CreateFileA("NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); \
nulFile = Win32Open(L"NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, false, OPEN_EXISTING, 0, 0); \
SetHandleInformation(nulFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); \
}