bool FLinuxPlatformProcess::GetProcReturnCode( FProcHandle& ProcHandle, int32* ReturnCode ) { if (IsProcRunning(ProcHandle)) { return false; } return ProcHandle.GetReturnCode(ReturnCode); }
bool FLinuxPlatformProcess::GetProcReturnCode( FProcHandle& ProcHandle, int32* ReturnCode ) { if (IsProcRunning(ProcHandle)) { return false; } FProcState * ProcInfo = ProcHandle.GetProcessInfo(); return ProcInfo ? ProcInfo->GetReturnCode(ReturnCode) : false; }
/** * Executes a process, returning the return code, stdout, and stderr. This * call blocks until the process has returned. */ bool FWindowsPlatformProcess::ExecProcess( const TCHAR* URL, const TCHAR* Params, int32* OutReturnCode, FString* OutStdOut, FString* OutStdErr ) { PROCESS_INFORMATION ProcInfo; SECURITY_ATTRIBUTES Attr; FString CommandLine = FString::Printf(TEXT("%s %s"), URL, Params); Attr.nLength = sizeof(SECURITY_ATTRIBUTES); Attr.lpSecurityDescriptor = NULL; Attr.bInheritHandle = true; uint32 CreateFlags = NORMAL_PRIORITY_CLASS; CreateFlags |= DETACHED_PROCESS; uint32 dwFlags = STARTF_USESHOWWINDOW; uint16 ShowWindowFlags = SW_SHOWMINNOACTIVE; const int32 MaxPipeCount = 2; HANDLE ReadablePipes[MaxPipeCount] = {0}; HANDLE WritablePipes[MaxPipeCount] = {0}; const bool bRedirectOutput = OutStdOut != NULL || OutStdErr != NULL; if (bRedirectOutput) { dwFlags |= STARTF_USESTDHANDLES; for (int32 PipeIndex = 0; PipeIndex < MaxPipeCount; ++PipeIndex) { verify(::CreatePipe(&ReadablePipes[PipeIndex], &WritablePipes[PipeIndex], &Attr, 0)); verify(::SetHandleInformation(ReadablePipes[PipeIndex], /*dwMask=*/ HANDLE_FLAG_INHERIT, /*dwFlags=*/ 0)); } } bool bSuccess = false; STARTUPINFO StartupInfo = { sizeof(STARTUPINFO), NULL, NULL, NULL, (::DWORD)CW_USEDEFAULT, (::DWORD)CW_USEDEFAULT, (::DWORD)CW_USEDEFAULT, (::DWORD)CW_USEDEFAULT, (::DWORD)0, (::DWORD)0, (::DWORD)0, (::DWORD)dwFlags, ShowWindowFlags, 0, NULL, ::GetStdHandle((::DWORD)ProcessConstants::WIN_STD_INPUT_HANDLE), WritablePipes[0], WritablePipes[1] }; if (CreateProcess(NULL, CommandLine.GetCharArray().GetData(), &Attr, &Attr, true, CreateFlags, NULL, NULL, &StartupInfo, &ProcInfo)) { if (bRedirectOutput) { FString* OutStrings[MaxPipeCount] = { OutStdOut, OutStdErr }; FProcHandle ProcHandle(ProcInfo.hProcess); do { ReadFromPipes(OutStrings, ReadablePipes, MaxPipeCount); FPlatformProcess::Sleep(0); } while (IsProcRunning(ProcHandle)); ReadFromPipes(OutStrings, ReadablePipes, MaxPipeCount); } else { ::WaitForSingleObject(ProcInfo.hProcess, INFINITE); } if (OutReturnCode) { verify(::GetExitCodeProcess(ProcInfo.hProcess, (::DWORD*)OutReturnCode)); } ::CloseHandle(ProcInfo.hProcess); ::CloseHandle(ProcInfo.hThread); bSuccess = true; } else { // if CreateProcess failed, we should return a useful error code, which GetLastError will have if (OutReturnCode) { *OutReturnCode = GetLastError(); } if (bRedirectOutput) { for (int32 PipeIndex = 0; PipeIndex < MaxPipeCount; ++PipeIndex) { verify(::CloseHandle(WritablePipes[PipeIndex])); } } } if (bRedirectOutput) { for (int32 PipeIndex = 0; PipeIndex < MaxPipeCount; ++PipeIndex) { verify(::CloseHandle(ReadablePipes[PipeIndex])); } } return bSuccess; }