I am using FInteractiveProcess
to use Git LFS to smudge the pointer files into the actual files.
I have got the input redirection working correctly, but when I bind to the output, I appear to be receiving STDERR rather than STDOUT. Specifically, I get from git lfs:
Downloading <unknown file> (30.76 KB)
Which looking at the source code for Git LFS is being printed to STDERR:
fmt.Fprintf(os.Stderr, "Downloading %s (%s)\n", workingfile, pb.FormatBytes(ptr.Size))
The file is being printed to STDOUT as running the command through a terminal yields the correct response.
Full code for launching the command:
FInteractiveProcess SmudgeProcess = FInteractiveProcess(*InPathToGitBinary, *SmudgeCommand, bLaunchHidden);
// SmudgeCommand = lfs smudge
SmudgeProcess.SendWhenReady(ReadInfo);
// ReadInfo = a valid LFS pointer
SmudgeProcess.OnOutput().BindLambda([&](const FString& Output) {
UE_LOG(LogTemp, Log, TEXT("%s"), *Output)
});
SmudgeProcess.Launch();
I don’t understand FInteractiveProcess
enough to say this is definitely a bug, but I’m pretty confident it is.
I think the problem is (but I don’t know why this is resulting in STDERR only) this should be reading ReadPipeChild
rather than ReadPipeParent
but I haven’t had time to test this as I haven’t built the engine from source. This is only based on how the FPlatformProcess::ReadPipe
is used by the git plugin to read the file from git show
.
Update based on a simpler test case - looks like there are some problems with FInteractiveProcess
I set up a simple program that prints STDOUT to STDOUT and STDERR to STDERR. When I then run this program through a FInteractiveProcess I get either both (understandable, but not entirely helpful for what git LFS requires), but more frequently I get no output at all (which I guess is how I lost the STDOUT when running Git lfs. Full code:
const FString ProgramPath = TEXT("E:\\dev\\C#\\BasicInputOutputTestingProgram\\BasicInputOutputTestingProgram\\bin\\x64\\Debug\\a.exe");
FInteractiveProcess SmudgeProcess = FInteractiveProcess(*ProgramPath, TEXT(""), true);
SmudgeProcess.OnOutput().BindLambda([&](const FString& Output) {
UE_LOG(LogTemp, Log, TEXT("%s"), *Output)
});
SmudgeProcess.Launch();
FPlatformProcess::Sleep(1.0);
if (SmudgeProcess.IsRunning())
{
UE_LOG(LogTemp, Log, TEXT("Done?"));
}
Running this gives no output unless I put a breakpoint inside FInteractiveProcess::Run()
. a.exe
is a simple program I wrote to produce the stdout/stderr required:
#include <stdio.h>
int main()
{
fprintf(stdout, "STDOUT\n");
fprintf(stderr, "STDERR\n");
}
The other odd thing I spotted is that even when the process is definitely done (all output sent) SmudgeProcess.IsRunning()
still seems to be returning true.