[+] Explicit async/blocking read process stdout/err
[*] Fixed missing inherit handles flag [TODO] consider CREATE_NO_WINDOW flag when refactoring create process object
This commit is contained in:
parent
31695ae63b
commit
a20bb97128
@ -26,9 +26,6 @@ namespace Aurora::Processes
|
||||
/// otherwise returns zero
|
||||
virtual AuSInt GetExitCode() = 0;
|
||||
|
||||
///
|
||||
/// @param exitOnSpawn atomically destroys the current process <br>
|
||||
/// some platforms only support this
|
||||
///
|
||||
// TODO(Reece): what in the hell this is ugly
|
||||
virtual bool Start(enum ESpawnType, bool fwdOut, bool fwdErr, bool fwdIn) = 0;
|
||||
@ -37,6 +34,7 @@ namespace Aurora::Processes
|
||||
virtual bool TryKill() = 0;
|
||||
|
||||
virtual bool Read(bool error, void *buffer, AuUInt32 &len) = 0;
|
||||
virtual bool Read(void *buffer, AuUInt32 &len, bool errorStream = false, bool nonblock = true);
|
||||
virtual bool Write(const void *buffer, AuUInt32 len) = 0;
|
||||
};
|
||||
}
|
@ -107,6 +107,8 @@ namespace Aurora::Process
|
||||
// SELinux gets in the way in some instances
|
||||
// There is no reason we should be searching for the jre binary
|
||||
// I'm also not convined pulling a cached apk path is the best thing to do here
|
||||
// Why should we even bother pulling /system/bin/app_process?
|
||||
|
||||
return false;
|
||||
|
||||
#elif defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
@ -323,6 +323,9 @@ namespace Aurora::Process
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
// Still doesnt stop hotswaps, and idc
|
||||
// Glitching would require software to time the attack
|
||||
// ...requiring a certain degree of access (code execution) + effort
|
||||
AuWin32CloseHandle(mitigateTimeOfUse);
|
||||
#endif
|
||||
|
||||
|
@ -46,7 +46,9 @@ namespace Aurora::Processes
|
||||
|
||||
AuSInt GetExitCode() override;
|
||||
|
||||
bool Read (bool error, void *buffer, AuUInt32 &len) override;
|
||||
bool Read(bool error, void *buffer, AuUInt32 &len) override;
|
||||
bool Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock) override;
|
||||
|
||||
bool Write(const void *buffer, AuUInt32 len) override;
|
||||
|
||||
bool Start(enum ESpawnType type, bool fwdOut, bool fwdErr, bool fwdIn) override;
|
||||
@ -160,12 +162,41 @@ namespace Aurora::Processes
|
||||
}
|
||||
|
||||
bool ProcessImpl::Read(bool error, void *buffer, AuUInt32 &len)
|
||||
{
|
||||
return Read(buffer, len, error, false);
|
||||
}
|
||||
|
||||
bool ProcessImpl::Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock)
|
||||
{
|
||||
len = 0;
|
||||
auto handle = error ? pipeStdErr_[0] : pipeStdOut_[0];
|
||||
if (handle < 0) return false;
|
||||
auto handle = errorStream ? pipeStdErr_[0] : pipeStdOut_[0];
|
||||
if (handle < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto control = fcntl(fd, F_GETFL);
|
||||
auto ref = control;
|
||||
if (nonblock)
|
||||
{
|
||||
control |= O_NONBLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
control &= ~O_NONBLOCK;
|
||||
}
|
||||
|
||||
if (ref != control)
|
||||
{
|
||||
fcntl(fd, F_SETFL, control);
|
||||
}
|
||||
|
||||
auto tmp = read(handle, buffer, len);
|
||||
if (tmp < 0) return false;
|
||||
if (tmp < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
len = tmp;
|
||||
return true;
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ namespace Aurora::Processes
|
||||
void ShutdownPipes();
|
||||
|
||||
bool Read(bool error, void *buffer, AuUInt32 &len) override;
|
||||
bool Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock) override;
|
||||
|
||||
bool Write(const void *buffer, AuUInt32 len) override;
|
||||
|
||||
// TODO: what in the hell this is ugly
|
||||
@ -211,10 +213,36 @@ namespace Aurora::Processes
|
||||
}
|
||||
|
||||
bool ProcessImpl::Read(bool error, void *buffer, AuUInt32 &len)
|
||||
{
|
||||
return Read(buffer, len, error, false);
|
||||
}
|
||||
|
||||
bool ProcessImpl::Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock)
|
||||
{
|
||||
DWORD size = std::exchange(len, 0);
|
||||
auto handle = error ? pipeStdErrRead_ : pipeStdOutRead_;
|
||||
if (handle == INVALID_HANDLE_VALUE) return false;
|
||||
|
||||
auto handle = errorStream ? pipeStdErrRead_ : pipeStdOutRead_;
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nonblock)
|
||||
{
|
||||
DWORD avail {};
|
||||
if (!PeekNamedPipe(handle, NULL, NULL, NULL, &avail, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!avail)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size = std::min(size, avail);
|
||||
}
|
||||
|
||||
auto ret = ReadFile(handle, buffer, size, &size, NULL);
|
||||
len = size;
|
||||
return ret;
|
||||
@ -288,15 +316,17 @@ namespace Aurora::Processes
|
||||
{
|
||||
STARTUPINFOW startupInfo = { 0 };
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
|
||||
bool inheritHandles = fwdIn || fwdErr || fwdOut;
|
||||
|
||||
startupInfo.hStdInput = pipeStdInRead_;
|
||||
startupInfo.hStdError = pipeStdErrWrite_;
|
||||
startupInfo.hStdOutput = pipeStdOutWrite_;
|
||||
startupInfo.dwFlags |= ((fwdIn || fwdErr || fwdOut) ? STARTF_USESTDHANDLES : 0);
|
||||
startupInfo.dwFlags |= (inheritHandles ? STARTF_USESTDHANDLES : 0);
|
||||
|
||||
auto result = CreateProcessW(Locale::ConvertFromUTF8(this->execModule_).c_str(),
|
||||
Locale::ConvertFromUTF8(this->windowsCli_).data(),
|
||||
NULL, NULL, FALSE,
|
||||
NULL, NULL, inheritHandles,
|
||||
NULL,
|
||||
NULL, NULL, &startupInfo, &processInfo);
|
||||
|
||||
@ -309,6 +339,10 @@ namespace Aurora::Processes
|
||||
this->process_ = processInfo.hProcess;
|
||||
this->hthread_ = processInfo.hThread;
|
||||
|
||||
AuWin32CloseHandle(this->pipeStdOutRead_);
|
||||
AuWin32CloseHandle(this->pipeStdErrRead_);
|
||||
AuWin32CloseHandle(this->pipeStdInWrite_);
|
||||
|
||||
if (type == ESpawnType::eSpawnChildProcessWorker)
|
||||
{
|
||||
if (gLeaderJob)
|
||||
|
Loading…
Reference in New Issue
Block a user