Refactor platform process startup with CreateProcessSettings
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "Engine/Platform/StringUtils.h"
|
||||
#include "Engine/Platform/MessageBox.h"
|
||||
#include "Engine/Platform/WindowsManager.h"
|
||||
#include "Engine/Platform/CreateProcessSettings.h"
|
||||
#include "Engine/Platform/Clipboard.h"
|
||||
#include "Engine/Platform/IGuiData.h"
|
||||
#include "Engine/Platform/Base/PlatformUtils.h"
|
||||
@@ -2799,11 +2800,19 @@ bool LinuxPlatform::SetEnvironmentVariable(const String& name, const String& val
|
||||
return setenv(StringAsANSI<>(*name).Get(), StringAsANSI<>(*value).Get(), true) != 0;
|
||||
}
|
||||
|
||||
int32 LinuxProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String>& environment, bool waitForEnd, bool logOutput)
|
||||
int32 LinuxPlatform::CreateProcess(CreateProcessSettings& settings)
|
||||
{
|
||||
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
|
||||
if (settings.WorkingDirectory.HasChars())
|
||||
{
|
||||
LOG(Info, "Working directory: {0}", settings.WorkingDirectory);
|
||||
}
|
||||
const bool captureStdOut = settings.LogOutput || settings.SaveOutput;
|
||||
const String cmdLine = settings.FileName + TEXT(" ") + settings.Arguments;
|
||||
|
||||
int fildes[2];
|
||||
int32 returnCode = 0;
|
||||
if (logOutput && pipe(fildes) < 0)
|
||||
if (captureStdOut && pipe(fildes) < 0)
|
||||
{
|
||||
LOG(Warning, "Failed to create a pipe, errno={}", errno);
|
||||
}
|
||||
@@ -2821,16 +2830,16 @@ int32 LinuxProcess(const StringView& cmdLine, const StringView& workingDir, cons
|
||||
const char* const cmd[] = { "sh", "-c", StringAnsi(cmdLine).GetText(), (char *)0 };
|
||||
// we could use the execve and supply a list of variable assignments but as we would have to build
|
||||
// and quote the values there is hardly any benefit over using setenv() calls
|
||||
for (auto& e : environment)
|
||||
for (auto& e : settings.Environment)
|
||||
{
|
||||
setenv(StringAnsi(e.Key).GetText(), StringAnsi(e.Value).GetText(), 1);
|
||||
}
|
||||
|
||||
if (workingDir.HasChars() && chdir(StringAnsi(workingDir).GetText()) != 0)
|
||||
if (settings.WorkingDirectory.HasChars() && chdir(StringAnsi(settings.WorkingDirectory).GetText()) != 0)
|
||||
{
|
||||
LOG(Warning, "Failed to set working directory to {}, errno={}", workingDir, errno);
|
||||
LOG(Warning, "Failed to set working directory to {}, errno={}", settings.WorkingDirectory, errno);
|
||||
}
|
||||
if (logOutput)
|
||||
if (captureStdOut)
|
||||
{
|
||||
close(fildes[0]); // close the reading end of the pipe
|
||||
dup2(fildes[1], STDOUT_FILENO); // redirect stdout to pipe
|
||||
@@ -2850,21 +2859,25 @@ int32 LinuxProcess(const StringView& cmdLine, const StringView& workingDir, cons
|
||||
{
|
||||
// parent process
|
||||
LOG(Info, "{} started, pid={}", cmdLine, pid);
|
||||
if (waitForEnd)
|
||||
if (settings.WaitForEnd)
|
||||
{
|
||||
int stat_loc;
|
||||
if (logOutput)
|
||||
if (captureStdOut)
|
||||
{
|
||||
char lineBuffer[1024];
|
||||
close(fildes[1]); // close the writing end of the pipe
|
||||
FILE* stdPipe = fdopen(fildes[0], "r");
|
||||
while (fgets(lineBuffer, sizeof(lineBuffer), stdPipe) != NULL)
|
||||
{
|
||||
char *p = lineBuffer + strlen(lineBuffer)-1;
|
||||
if (*p == '\n') *p=0;
|
||||
Log::Logger::Write(LogType::Info, String(lineBuffer));
|
||||
char *p = lineBuffer + strlen(lineBuffer) - 1;
|
||||
if (*p == '\n') *p = 0;
|
||||
String line(lineBuffer);
|
||||
if (settings.SaveOutput)
|
||||
settings.Output.Add(line.Get(), line.Length());
|
||||
if (settings.LogOutput)
|
||||
Log::Logger::Write(LogType::Info, line);
|
||||
}
|
||||
}
|
||||
int stat_loc;
|
||||
if (waitpid(pid, &stat_loc, 0) < 0)
|
||||
{
|
||||
LOG(Warning, "Waiting for pid {} failed, errno={}", pid, errno);
|
||||
@@ -2899,24 +2912,6 @@ int32 LinuxProcess(const StringView& cmdLine, const StringView& workingDir, cons
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
int32 LinuxPlatform::StartProcess(const StringView& filename, const StringView& args, const StringView& workingDir, bool hiddenWindow, bool waitForEnd)
|
||||
{
|
||||
// hiddenWindow has hardly any meaning on UNIX/Linux/OSX as the program that is called decides whether it has a GUI or not
|
||||
String cmdLine(filename);
|
||||
if (args.HasChars()) cmdLine = cmdLine + TEXT(" ") + args;
|
||||
return LinuxProcess(cmdLine, workingDir, Dictionary<String, String>(), waitForEnd, false);
|
||||
}
|
||||
|
||||
int32 LinuxPlatform::RunProcess(const StringView& cmdLine, const StringView& workingDir, bool hiddenWindow)
|
||||
{
|
||||
return LinuxProcess(cmdLine, workingDir, Dictionary<String, String>(), true, true);
|
||||
}
|
||||
|
||||
int32 LinuxPlatform::RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String>& environment, bool hiddenWindow)
|
||||
{
|
||||
return LinuxProcess(cmdLine, workingDir, environment, true, true);
|
||||
}
|
||||
|
||||
void* LinuxPlatform::LoadLibrary(const Char* filename)
|
||||
{
|
||||
const StringAsANSI<> filenameANSI(filename);
|
||||
|
||||
@@ -134,9 +134,7 @@ public:
|
||||
static void GetEnvironmentVariables(Dictionary<String, String, HeapAllocation>& result);
|
||||
static bool GetEnvironmentVariable(const String& name, String& value);
|
||||
static bool SetEnvironmentVariable(const String& name, const String& value);
|
||||
static int32 StartProcess(const StringView& filename, const StringView& args, const StringView& workingDir, bool hiddenWindow = false, bool waitForEnd = false);
|
||||
static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, bool hiddenWindow = true);
|
||||
static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String, HeapAllocation>& environment, bool hiddenWindow = true);
|
||||
static int32 CreateProcess(CreateProcessSettings& settings);
|
||||
static void* LoadLibrary(const Char* filename);
|
||||
static void FreeLibrary(void* handle);
|
||||
static void* GetProcAddress(void* handle, const char* symbol);
|
||||
|
||||
Reference in New Issue
Block a user