[+] 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
|
||||
|
||||
#include "EStreamError.hpp"
|
||||
#include "EStandardStream.hpp"
|
||||
|
||||
#include "IStreamReader.hpp"
|
||||
#include "IStreamWriter.hpp"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 {};
|
||||
|
@ -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;
|
||||
|
@ -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); \
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user