2014-03-14 14:13:41 -04:00
|
|
|
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
/*=============================================================================
|
|
|
|
|
LinuxTargetDevice.cpp: Implements the LinuxTargetDevice class.
|
|
|
|
|
=============================================================================*/
|
|
|
|
|
|
|
|
|
|
#include "LinuxTargetPlatformPrivatePCH.h"
|
|
|
|
|
|
|
|
|
|
#include "LinuxTargetDevice.h"
|
|
|
|
|
|
2014-08-04 21:21:35 -04:00
|
|
|
#if PLATFORM_LINUX
|
|
|
|
|
#include <signal.h> // for process termination
|
|
|
|
|
#include <pwd.h> // for getting uid/gid
|
|
|
|
|
#endif // PLATFORM_LINUX
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
/* ITargetDevice interface
|
2014-08-04 21:21:35 -04:00
|
|
|
*****************************************************************************/
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::Deploy( const FString& SourceFolder, FString& OutAppId )
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
#if PLATFORM_LINUX // if running natively, support simplified, local deployment
|
|
|
|
|
OutAppId = TEXT("");
|
|
|
|
|
|
|
|
|
|
FString PlatformName = TEXT("Linux");
|
|
|
|
|
FString DeploymentDir = FPaths::EngineIntermediateDir() / TEXT("Devices") / PlatformName;
|
|
|
|
|
|
|
|
|
|
// delete previous build
|
|
|
|
|
IFileManager::Get().DeleteDirectory(*DeploymentDir, false, true);
|
|
|
|
|
|
|
|
|
|
// copy files into device directory
|
|
|
|
|
TArray<FString> FileNames;
|
|
|
|
|
|
|
|
|
|
IFileManager::Get().FindFilesRecursive(FileNames, *SourceFolder, TEXT("*.*"), true, false);
|
|
|
|
|
|
|
|
|
|
for (int32 FileIndex = 0; FileIndex < FileNames.Num(); ++FileIndex)
|
|
|
|
|
{
|
|
|
|
|
const FString& SourceFilePath = FileNames[FileIndex];
|
|
|
|
|
FString DestFilePath = DeploymentDir + SourceFilePath.RightChop(SourceFolder.Len());
|
|
|
|
|
|
|
|
|
|
IFileManager::Get().Copy(*DestFilePath, *SourceFilePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
#else
|
|
|
|
|
// @todo: support deployment to a remote machine
|
|
|
|
|
STUBBED("FLinuxTargetDevice::Deploy");
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
2014-08-04 21:21:35 -04:00
|
|
|
#endif // PLATFORM_LINUX
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32 FLinuxTargetDevice::GetProcessSnapshot( TArray<FTargetDeviceProcessInfo>& OutProcessInfos )
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
STUBBED("FLinuxTargetDevice::GetProcessSnapshot");
|
2014-03-14 14:13:41 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::Launch( const FString& AppId, EBuildConfigurations::Type BuildConfiguration, EBuildTargets::Type BuildTarget, const FString& Params, uint32* OutProcessId )
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
#if PLATFORM_LINUX // if running natively, support launching in place
|
|
|
|
|
// build executable path
|
|
|
|
|
FString PlatformName = TEXT("Linux");
|
|
|
|
|
FString ExecutablePath = FPaths::EngineIntermediateDir() / TEXT("Devices") / PlatformName / TEXT("Engine") / TEXT("Binaries") / PlatformName;
|
|
|
|
|
|
|
|
|
|
if (BuildTarget == EBuildTargets::Game)
|
|
|
|
|
{
|
|
|
|
|
ExecutablePath /= TEXT("UE4Game");
|
|
|
|
|
}
|
|
|
|
|
else if (BuildTarget == EBuildTargets::Server)
|
|
|
|
|
{
|
|
|
|
|
ExecutablePath /= TEXT("UE4Server");
|
|
|
|
|
}
|
|
|
|
|
else if (BuildTarget == EBuildTargets::Editor)
|
|
|
|
|
{
|
|
|
|
|
ExecutablePath /= TEXT("UE4Editor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BuildConfiguration != EBuildConfigurations::Development)
|
|
|
|
|
{
|
|
|
|
|
ExecutablePath += FString::Printf(TEXT("-%s-%s"), *PlatformName, EBuildConfigurations::ToString(BuildConfiguration));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// launch the game
|
|
|
|
|
FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*ExecutablePath, *Params, true, false, false, OutProcessId, 0, NULL, NULL);
|
|
|
|
|
return ProcessHandle.Close();
|
|
|
|
|
#else
|
|
|
|
|
// @todo: support launching on a remote machine
|
|
|
|
|
STUBBED("FLinuxTargetDevice::Launch");
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
2014-08-04 21:21:35 -04:00
|
|
|
#endif // PLATFORM_LINUX
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::Reboot( bool bReconnect)
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
STUBBED("FLinuxTargetDevice::Reboot");
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::Run( const FString& ExecutablePath, const FString& Params, uint32* OutProcessId )
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
#if PLATFORM_LINUX // if running natively, support simplified, local deployment
|
|
|
|
|
FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*ExecutablePath, *Params, true, false, false, OutProcessId, 0, NULL, NULL);
|
|
|
|
|
return ProcessHandle.Close();
|
|
|
|
|
#else
|
|
|
|
|
// @todo: support remote run
|
|
|
|
|
STUBBED("FLinuxTargetDevice::Run");
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
2014-08-04 21:21:35 -04:00
|
|
|
#endif // PLATFORM_LINUX
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
2014-10-10 20:14:21 -04:00
|
|
|
bool FLinuxTargetDevice::SupportsFeature( ETargetDeviceFeatures Feature ) const
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
switch (Feature)
|
|
|
|
|
{
|
|
|
|
|
case ETargetDeviceFeatures::MultiLaunch:
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// @todo to be implemented
|
|
|
|
|
case ETargetDeviceFeatures::PowerOff:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// @todo to be implemented turning on remote PCs (wake on LAN)
|
|
|
|
|
case ETargetDeviceFeatures::PowerOn:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// @todo to be implemented
|
|
|
|
|
case ETargetDeviceFeatures::ProcessSnapshot:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// @todo to be implemented
|
|
|
|
|
case ETargetDeviceFeatures::Reboot:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::SupportsSdkVersion( const FString& VersionString ) const
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
STUBBED("FLinuxTargetDevice::SupportsSdkVersion");
|
2014-03-14 14:13:41 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-04 21:21:35 -04:00
|
|
|
void FLinuxTargetDevice::SetUserCredentials( const FString& InUserName, const FString& InUserPassword )
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
STUBBED("FLinuxTargetDevice::SetUserCredentials");
|
2014-03-14 14:13:41 -04:00
|
|
|
UserName = InUserName;
|
|
|
|
|
UserPassword = InUserPassword;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-04 21:21:35 -04:00
|
|
|
bool FLinuxTargetDevice::GetUserCredentials( FString& OutUserName, FString& OutUserPassword )
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
STUBBED("FLinuxTargetDevice::GetUserCredentials");
|
2014-03-14 14:13:41 -04:00
|
|
|
OutUserName = UserName;
|
|
|
|
|
OutUserPassword = UserPassword;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FLinuxTargetDevice::TerminateProcess( const int32 ProcessId )
|
|
|
|
|
{
|
2014-08-04 21:21:35 -04:00
|
|
|
#if PLATFORM_LINUX // if running natively, just terminate the local process
|
|
|
|
|
// get process path from the ProcessId
|
|
|
|
|
const int32 ReadLinkSize = 1024;
|
|
|
|
|
char ReadLinkCmd[ReadLinkSize] = {0};
|
|
|
|
|
FCStringAnsi::Sprintf(ReadLinkCmd, "/proc/%d/exe", ProcessId);
|
|
|
|
|
char ProcessPath[ MAX_PATH + 1 ] = {0};
|
|
|
|
|
int32 Ret = readlink(ReadLinkCmd, ProcessPath, ARRAY_COUNT(ProcessPath) - 1);
|
|
|
|
|
if (Ret != -1)
|
|
|
|
|
{
|
|
|
|
|
struct stat st;
|
|
|
|
|
uid_t euid;
|
|
|
|
|
stat(ProcessPath, &st);
|
|
|
|
|
euid = geteuid(); // get effective uid of current application, as this user is asking to kill a process
|
|
|
|
|
|
|
|
|
|
// now check if we own the process
|
|
|
|
|
if (st.st_uid == euid)
|
|
|
|
|
{
|
|
|
|
|
// terminate it (will this terminate children as well because we set their pgid?)
|
|
|
|
|
kill(ProcessId, SIGTERM);
|
|
|
|
|
sleep(2); // sleep in case process still remains then send a more strict signal
|
|
|
|
|
kill(ProcessId, SIGKILL);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
// @todo: support remote termination
|
|
|
|
|
STUBBED("FLinuxTargetDevice::TerminateProcess");
|
|
|
|
|
#endif // PLATFORM_LINUX
|
2014-03-14 14:13:41 -04:00
|
|
|
return false;
|
|
|
|
|
}
|