2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 14:27:42 +00:00

Add hecl::PathRelative()

This commit is contained in:
Jack Andersen
2017-02-24 21:58:36 -10:00
parent 8c3a7da616
commit 89f216d94f
7 changed files with 136 additions and 18 deletions

View File

@@ -761,6 +761,117 @@ const SystemChar* GetTmpDir()
int RunProcess(const SystemChar* path, const SystemChar* const args[])
{
#ifdef _WIN32
SECURITY_ATTRIBUTES sattrs = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
HANDLE consoleOutReadTmp, consoleOutWrite, consoleErrWrite, consoleOutRead;
if (!CreatePipe(&consoleOutReadTmp, &consoleOutWrite, &sattrs, 0))
{
LogModule.report(logvisor::Fatal, "Error with CreatePipe");
return -1;
}
if (!DuplicateHandle(GetCurrentProcess(), consoleOutWrite,
GetCurrentProcess(), &consoleErrWrite, 0,
TRUE,DUPLICATE_SAME_ACCESS))
{
LogModule.report(logvisor::Fatal, "Error with DuplicateHandle");
CloseHandle(consoleOutReadTmp);
CloseHandle(consoleOutWrite);
return -1;
}
if (!DuplicateHandle(GetCurrentProcess(), consoleOutReadTmp,
GetCurrentProcess(),
&consoleOutRead, // Address of new handle.
0, FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
{
LogModule.report(logvisor::Fatal, "Error with DupliateHandle");
CloseHandle(consoleOutReadTmp);
CloseHandle(consoleOutWrite);
CloseHandle(consoleErrWrite);
return -1;
}
CloseHandle(consoleOutReadTmp);
hecl::SystemString cmdLine;
const SystemChar* const* arg = &args[1];
while (*arg)
{
cmdLine += _S(" \"");
cmdLine += *arg++;
cmdLine += _S('"');
}
STARTUPINFO sinfo = {sizeof(STARTUPINFO)};
HANDLE nulHandle = CreateFileW(L"nul", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
&sattrs, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
sinfo.dwFlags = STARTF_USESTDHANDLES;
sinfo.hStdInput = nulHandle;
sinfo.hStdError = consoleErrWrite;
sinfo.hStdOutput = consoleOutWrite;
PROCESS_INFORMATION pinfo = {};
if (!CreateProcessW(path, (LPWSTR)cmdLine.c_str(), NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo))
{
LPWSTR messageBuffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
LogModule.report(logvisor::Error, L"unable to launch process from %s: %s", path, messageBuffer);
LocalFree(messageBuffer);
CloseHandle(nulHandle);
CloseHandle(consoleErrWrite);
CloseHandle(consoleOutWrite);
CloseHandle(consoleOutRead);
return -1;
}
CloseHandle(nulHandle);
CloseHandle(consoleErrWrite);
CloseHandle(consoleOutWrite);
bool consoleThreadRunning = true;
auto consoleThread = std::thread([=, &consoleThreadRunning]()
{
CHAR lpBuffer[256];
DWORD nBytesRead;
DWORD nCharsWritten;
while (consoleThreadRunning)
{
if (!ReadFile(consoleOutRead, lpBuffer, sizeof(lpBuffer),
&nBytesRead, NULL) || !nBytesRead)
{
DWORD err = GetLastError();
if (err == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
LogModule.report(logvisor::Error, "Error with ReadFile: %08X", err); // Something bad happened.
}
// Display the character read on the screen.
auto lk = logvisor::LockLog();
if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer,
nBytesRead, &nCharsWritten, NULL))
LogModule.report(logvisor::Error, "Error with WriteConsole: %08X", GetLastError());
}
CloseHandle(consoleOutRead);
});
WaitForSingleObject(pinfo.hProcess, INFINITE);
DWORD ret;
if (!GetExitCodeProcess(pinfo.hProcess, &ret))
ret = -1;
consoleThreadRunning = false;
if (consoleThread.joinable())
consoleThread.join();
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
return ret;
#else
pid_t pid = fork();
if (!pid)