[+] AuIO::IO::EStandardStream
[+] AuIO::IOHandle::InitFromStreamEnum(...)
This commit is contained in:
parent
d0538ea4de
commit
b4d5f4c127
17
Include/Aurora/IO/EStandardStream.hpp
Normal file
17
Include/Aurora/IO/EStandardStream.hpp
Normal 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
|
||||||
|
);
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "EStreamError.hpp"
|
#include "EStreamError.hpp"
|
||||||
|
#include "EStandardStream.hpp"
|
||||||
|
|
||||||
#include "IStreamReader.hpp"
|
#include "IStreamReader.hpp"
|
||||||
#include "IStreamWriter.hpp"
|
#include "IStreamWriter.hpp"
|
||||||
|
@ -106,6 +106,8 @@ namespace Aurora::IO
|
|||||||
virtual bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
virtual bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle) = 0;
|
AuOptionalEx<AuUInt64> uOSWriteHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromStreamEnum(EStandardStream eStream) = 0;
|
||||||
|
|
||||||
virtual AuUInt64 GetOSHandle() = 0;
|
virtual AuUInt64 GetOSHandle() = 0;
|
||||||
|
|
||||||
virtual AuOptionalEx<AuUInt64> GetOSHandleSafe() = 0;
|
virtual AuOptionalEx<AuUInt64> GetOSHandleSafe() = 0;
|
||||||
|
@ -45,6 +45,55 @@ namespace Aurora::IO
|
|||||||
AuWin32CloseHandle(hHandle);
|
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
|
struct NTIOHandle final : AFileHandle
|
||||||
{
|
{
|
||||||
bool InitFromPath(HandleCreate create) override;
|
bool InitFromPath(HandleCreate create) override;
|
||||||
|
@ -23,17 +23,49 @@
|
|||||||
// Yea, I don't give a shit.
|
// Yea, I don't give a shit.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FD_CLOEXEC)
|
||||||
|
#define FD_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Aurora::IO
|
namespace Aurora::IO
|
||||||
{
|
{
|
||||||
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
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)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
return 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);
|
return AuUInt64(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +80,16 @@ namespace Aurora::IO
|
|||||||
::close(fd);
|
::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
|
struct UnixIOHandle final : AFileHandle
|
||||||
{
|
{
|
||||||
bool InitFromPath(HandleCreate create) override;
|
bool InitFromPath(HandleCreate create) override;
|
||||||
|
@ -126,6 +126,23 @@ namespace Aurora::IO
|
|||||||
return true;
|
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 AFileHandle::IsFile()
|
||||||
{
|
{
|
||||||
bool bIsFile {};
|
bool bIsFile {};
|
||||||
|
@ -30,6 +30,8 @@ namespace Aurora::IO
|
|||||||
bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
|
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
|
||||||
|
|
||||||
|
bool InitFromStreamEnum(EStandardStream eStream) override;
|
||||||
|
|
||||||
AuUInt64 GetOSHandle() override;
|
AuUInt64 GetOSHandle() override;
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> GetOSHandleSafe() override;
|
AuOptionalEx<AuUInt64> GetOSHandleSafe() override;
|
||||||
@ -54,6 +56,9 @@ namespace Aurora::IO
|
|||||||
bool IsTTY() override;
|
bool IsTTY() override;
|
||||||
bool IsPipe() override;
|
bool IsPipe() override;
|
||||||
|
|
||||||
|
void InitStdIn(bool bSharing = false);
|
||||||
|
void InitStdOut(bool bError = false, bool bSharing = false);
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
||||||
AuOptionalEx<AuUInt64> uOSReadHandle;
|
AuOptionalEx<AuUInt64> uOSReadHandle;
|
||||||
AuSPtr<IIOHandle> pThat;
|
AuSPtr<IIOHandle> pThat;
|
||||||
|
@ -295,23 +295,15 @@ namespace Aurora::Processes
|
|||||||
}
|
}
|
||||||
else if (this->startup_.fwdOut == EStreamForward::eCurrentProcess)
|
else if (this->startup_.fwdOut == EStreamForward::eCurrentProcess)
|
||||||
{
|
{
|
||||||
HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
AuResetMember(this->startup_.handleOutStream);
|
||||||
|
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleOutStream.AsPointer())->InitStdOut(false, true);
|
||||||
if (hHandle != INVALID_HANDLE_VALUE)
|
auto optHandle = this->startup_.handleOutStream->GetOSHandleSafe();
|
||||||
|
if (!optHandle)
|
||||||
{
|
{
|
||||||
HANDLE hTargetProcess = ::GetCurrentProcess();
|
return false;
|
||||||
|
|
||||||
if (!::DuplicateHandle(hTargetProcess,
|
|
||||||
hHandle,
|
|
||||||
hTargetProcess,
|
|
||||||
&this->pipeStdOutWrite_,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
TRUE,
|
|
||||||
0))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this->pipeStdOutWrite_ = (HANDLE)optHandle.value();
|
||||||
|
this->bDontRelOut_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
||||||
@ -355,23 +347,15 @@ namespace Aurora::Processes
|
|||||||
}
|
}
|
||||||
else if (this->startup_.fwdErr == EStreamForward::eCurrentProcess)
|
else if (this->startup_.fwdErr == EStreamForward::eCurrentProcess)
|
||||||
{
|
{
|
||||||
HANDLE hHandle = GetStdHandle(STD_ERROR_HANDLE);
|
AuResetMember(this->startup_.handleErrorStream);
|
||||||
|
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleErrorStream.AsPointer())->InitStdOut(true, true);
|
||||||
if (hHandle != INVALID_HANDLE_VALUE)
|
auto optHandle = this->startup_.handleErrorStream->GetOSHandleSafe();
|
||||||
|
if (!optHandle)
|
||||||
{
|
{
|
||||||
HANDLE hTargetProcess = ::GetCurrentProcess();
|
return false;
|
||||||
|
|
||||||
if (!::DuplicateHandle(hTargetProcess,
|
|
||||||
hHandle,
|
|
||||||
hTargetProcess,
|
|
||||||
&this->pipeStdErrWrite_,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
TRUE,
|
|
||||||
0))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this->pipeStdErrWrite_ = (HANDLE)optHandle.value();
|
||||||
|
this->bDontRelErr_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->startup_.fwdIn == EStreamForward::eAsyncPipe)
|
if (this->startup_.fwdIn == EStreamForward::eAsyncPipe)
|
||||||
@ -415,23 +399,15 @@ namespace Aurora::Processes
|
|||||||
}
|
}
|
||||||
else if (this->startup_.fwdIn == EStreamForward::eCurrentProcess)
|
else if (this->startup_.fwdIn == EStreamForward::eCurrentProcess)
|
||||||
{
|
{
|
||||||
HANDLE hHandle = GetStdHandle(STD_INPUT_HANDLE);
|
AuResetMember(this->startup_.handleInputStream);
|
||||||
|
AuStaticCast<AuIO::AFileHandle>(this->startup_.handleInputStream.AsPointer())->InitStdIn(true);
|
||||||
if (hHandle != INVALID_HANDLE_VALUE)
|
auto optHandle = this->startup_.handleInputStream->GetOSHandleSafe();
|
||||||
|
if (!optHandle)
|
||||||
{
|
{
|
||||||
HANDLE hTargetProcess = ::GetCurrentProcess();
|
return false;
|
||||||
|
|
||||||
if (!::DuplicateHandle(hTargetProcess,
|
|
||||||
hHandle,
|
|
||||||
hTargetProcess,
|
|
||||||
&this->pipeStdInRead_,
|
|
||||||
GENERIC_READ,
|
|
||||||
TRUE,
|
|
||||||
0))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this->pipeStdInRead_ = (HANDLE)optHandle.value();
|
||||||
|
this->bDontRelIn_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -439,7 +415,7 @@ namespace Aurora::Processes
|
|||||||
|
|
||||||
#define NEW_NULL_HANDLE \
|
#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); \
|
SetHandleInformation(nulFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user