Пример #1
0
bool FLinuxPlatformProcess::GetProcReturnCode( FProcHandle& ProcHandle, int32* ReturnCode )
{
	if (IsProcRunning(ProcHandle))
	{
		return false;
	}

	return ProcHandle.GetReturnCode(ReturnCode);
}
Пример #2
0
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;
}