1b952cd58SEd Maste //===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===//
2b952cd58SEd Maste //
3b952cd58SEd Maste //                     The LLVM Compiler Infrastructure
4b952cd58SEd Maste //
5b952cd58SEd Maste // This file is distributed under the University of Illinois Open Source
6b952cd58SEd Maste // License. See LICENSE.TXT for details.
7b952cd58SEd Maste //
8b952cd58SEd Maste //===----------------------------------------------------------------------===//
9b952cd58SEd Maste 
10b952cd58SEd Maste #include "lldb/API/SBPlatform.h"
11b952cd58SEd Maste #include "lldb/API/SBError.h"
12b952cd58SEd Maste #include "lldb/API/SBFileSpec.h"
131c3bbb01SEd Maste #include "lldb/API/SBLaunchInfo.h"
14b91a7dfcSDimitry Andric #include "lldb/API/SBUnixSignals.h"
15b952cd58SEd Maste #include "lldb/Host/File.h"
16b952cd58SEd Maste #include "lldb/Target/Platform.h"
17435933ddSDimitry Andric #include "lldb/Target/Target.h"
18acac075bSDimitry Andric #include "lldb/Utility/ArchSpec.h"
194ba319b5SDimitry Andric #include "lldb/Utility/Args.h"
205517e702SDimitry Andric #include "lldb/Utility/Status.h"
21f678e45dSDimitry Andric 
22f678e45dSDimitry Andric #include "llvm/Support/FileSystem.h"
23b952cd58SEd Maste 
241c3bbb01SEd Maste #include <functional>
251c3bbb01SEd Maste 
26b952cd58SEd Maste using namespace lldb;
27b952cd58SEd Maste using namespace lldb_private;
28b952cd58SEd Maste 
29b952cd58SEd Maste //----------------------------------------------------------------------
30b952cd58SEd Maste // PlatformConnectOptions
31b952cd58SEd Maste //----------------------------------------------------------------------
32b952cd58SEd Maste struct PlatformConnectOptions {
PlatformConnectOptionsPlatformConnectOptions33435933ddSDimitry Andric   PlatformConnectOptions(const char *url = NULL)
34435933ddSDimitry Andric       : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
35435933ddSDimitry Andric         m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false),
36435933ddSDimitry Andric         m_local_cache_directory() {
37b952cd58SEd Maste     if (url && url[0])
38b952cd58SEd Maste       m_url = url;
39b952cd58SEd Maste   }
40b952cd58SEd Maste 
~PlatformConnectOptionsPlatformConnectOptions41435933ddSDimitry Andric   ~PlatformConnectOptions() {}
42b952cd58SEd Maste 
43b952cd58SEd Maste   std::string m_url;
44b952cd58SEd Maste   std::string m_rsync_options;
45b952cd58SEd Maste   std::string m_rsync_remote_path_prefix;
46b952cd58SEd Maste   bool m_rsync_enabled;
47b952cd58SEd Maste   bool m_rsync_omit_hostname_from_remote_path;
48b952cd58SEd Maste   ConstString m_local_cache_directory;
49b952cd58SEd Maste };
50b952cd58SEd Maste 
51b952cd58SEd Maste //----------------------------------------------------------------------
52b952cd58SEd Maste // PlatformShellCommand
53b952cd58SEd Maste //----------------------------------------------------------------------
54b952cd58SEd Maste struct PlatformShellCommand {
PlatformShellCommandPlatformShellCommand55435933ddSDimitry Andric   PlatformShellCommand(const char *shell_command = NULL)
564ba319b5SDimitry Andric       : m_command(), m_working_dir(), m_status(0), m_signo(0) {
57b952cd58SEd Maste     if (shell_command && shell_command[0])
58b952cd58SEd Maste       m_command = shell_command;
59b952cd58SEd Maste   }
60b952cd58SEd Maste 
~PlatformShellCommandPlatformShellCommand61435933ddSDimitry Andric   ~PlatformShellCommand() {}
62b952cd58SEd Maste 
63b952cd58SEd Maste   std::string m_command;
64b952cd58SEd Maste   std::string m_working_dir;
65b952cd58SEd Maste   std::string m_output;
66b952cd58SEd Maste   int m_status;
67b952cd58SEd Maste   int m_signo;
684ba319b5SDimitry Andric   Timeout<std::ratio<1>> m_timeout = llvm::None;
69b952cd58SEd Maste };
70b952cd58SEd Maste //----------------------------------------------------------------------
71b952cd58SEd Maste // SBPlatformConnectOptions
72b952cd58SEd Maste //----------------------------------------------------------------------
SBPlatformConnectOptions(const char * url)73435933ddSDimitry Andric SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
74435933ddSDimitry Andric     : m_opaque_ptr(new PlatformConnectOptions(url)) {}
75b952cd58SEd Maste 
SBPlatformConnectOptions(const SBPlatformConnectOptions & rhs)76435933ddSDimitry Andric SBPlatformConnectOptions::SBPlatformConnectOptions(
77435933ddSDimitry Andric     const SBPlatformConnectOptions &rhs)
78435933ddSDimitry Andric     : m_opaque_ptr(new PlatformConnectOptions()) {
79b952cd58SEd Maste   *m_opaque_ptr = *rhs.m_opaque_ptr;
80b952cd58SEd Maste }
81b952cd58SEd Maste 
~SBPlatformConnectOptions()82435933ddSDimitry Andric SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
83b952cd58SEd Maste 
operator =(const SBPlatformConnectOptions & rhs)84435933ddSDimitry Andric void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
85b952cd58SEd Maste   *m_opaque_ptr = *rhs.m_opaque_ptr;
86b952cd58SEd Maste }
87b952cd58SEd Maste 
GetURL()88435933ddSDimitry Andric const char *SBPlatformConnectOptions::GetURL() {
89b952cd58SEd Maste   if (m_opaque_ptr->m_url.empty())
90b952cd58SEd Maste     return NULL;
91b952cd58SEd Maste   return m_opaque_ptr->m_url.c_str();
92b952cd58SEd Maste }
93b952cd58SEd Maste 
SetURL(const char * url)94435933ddSDimitry Andric void SBPlatformConnectOptions::SetURL(const char *url) {
95b952cd58SEd Maste   if (url && url[0])
96b952cd58SEd Maste     m_opaque_ptr->m_url = url;
97b952cd58SEd Maste   else
98b952cd58SEd Maste     m_opaque_ptr->m_url.clear();
99b952cd58SEd Maste }
100b952cd58SEd Maste 
GetRsyncEnabled()101435933ddSDimitry Andric bool SBPlatformConnectOptions::GetRsyncEnabled() {
102b952cd58SEd Maste   return m_opaque_ptr->m_rsync_enabled;
103b952cd58SEd Maste }
104b952cd58SEd Maste 
EnableRsync(const char * options,const char * remote_path_prefix,bool omit_hostname_from_remote_path)105435933ddSDimitry Andric void SBPlatformConnectOptions::EnableRsync(
106435933ddSDimitry Andric     const char *options, const char *remote_path_prefix,
107435933ddSDimitry Andric     bool omit_hostname_from_remote_path) {
108b952cd58SEd Maste   m_opaque_ptr->m_rsync_enabled = true;
109435933ddSDimitry Andric   m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
110435933ddSDimitry Andric       omit_hostname_from_remote_path;
111b952cd58SEd Maste   if (remote_path_prefix && remote_path_prefix[0])
112b952cd58SEd Maste     m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
113b952cd58SEd Maste   else
114b952cd58SEd Maste     m_opaque_ptr->m_rsync_remote_path_prefix.clear();
115b952cd58SEd Maste 
116b952cd58SEd Maste   if (options && options[0])
117b952cd58SEd Maste     m_opaque_ptr->m_rsync_options = options;
118b952cd58SEd Maste   else
119b952cd58SEd Maste     m_opaque_ptr->m_rsync_options.clear();
120b952cd58SEd Maste }
121b952cd58SEd Maste 
DisableRsync()122435933ddSDimitry Andric void SBPlatformConnectOptions::DisableRsync() {
123b952cd58SEd Maste   m_opaque_ptr->m_rsync_enabled = false;
124b952cd58SEd Maste }
125b952cd58SEd Maste 
GetLocalCacheDirectory()126435933ddSDimitry Andric const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
127b952cd58SEd Maste   return m_opaque_ptr->m_local_cache_directory.GetCString();
128b952cd58SEd Maste }
129b952cd58SEd Maste 
SetLocalCacheDirectory(const char * path)130435933ddSDimitry Andric void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
131b952cd58SEd Maste   if (path && path[0])
132b952cd58SEd Maste     m_opaque_ptr->m_local_cache_directory.SetCString(path);
133b952cd58SEd Maste   else
134b952cd58SEd Maste     m_opaque_ptr->m_local_cache_directory = ConstString();
135b952cd58SEd Maste }
136b952cd58SEd Maste 
137b952cd58SEd Maste //----------------------------------------------------------------------
138b952cd58SEd Maste // SBPlatformShellCommand
139b952cd58SEd Maste //----------------------------------------------------------------------
SBPlatformShellCommand(const char * shell_command)140435933ddSDimitry Andric SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
141435933ddSDimitry Andric     : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
142b952cd58SEd Maste 
SBPlatformShellCommand(const SBPlatformShellCommand & rhs)143435933ddSDimitry Andric SBPlatformShellCommand::SBPlatformShellCommand(
144435933ddSDimitry Andric     const SBPlatformShellCommand &rhs)
145435933ddSDimitry Andric     : m_opaque_ptr(new PlatformShellCommand()) {
146b952cd58SEd Maste   *m_opaque_ptr = *rhs.m_opaque_ptr;
147b952cd58SEd Maste }
148b952cd58SEd Maste 
~SBPlatformShellCommand()149435933ddSDimitry Andric SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
150b952cd58SEd Maste 
Clear()151435933ddSDimitry Andric void SBPlatformShellCommand::Clear() {
1529f2f44ceSEd Maste   m_opaque_ptr->m_output = std::string();
153b952cd58SEd Maste   m_opaque_ptr->m_status = 0;
154b952cd58SEd Maste   m_opaque_ptr->m_signo = 0;
155b952cd58SEd Maste }
156b952cd58SEd Maste 
GetCommand()157435933ddSDimitry Andric const char *SBPlatformShellCommand::GetCommand() {
158b952cd58SEd Maste   if (m_opaque_ptr->m_command.empty())
159b952cd58SEd Maste     return NULL;
160b952cd58SEd Maste   return m_opaque_ptr->m_command.c_str();
161b952cd58SEd Maste }
162b952cd58SEd Maste 
SetCommand(const char * shell_command)163435933ddSDimitry Andric void SBPlatformShellCommand::SetCommand(const char *shell_command) {
164b952cd58SEd Maste   if (shell_command && shell_command[0])
165b952cd58SEd Maste     m_opaque_ptr->m_command = shell_command;
166b952cd58SEd Maste   else
167b952cd58SEd Maste     m_opaque_ptr->m_command.clear();
168b952cd58SEd Maste }
169b952cd58SEd Maste 
GetWorkingDirectory()170435933ddSDimitry Andric const char *SBPlatformShellCommand::GetWorkingDirectory() {
171b952cd58SEd Maste   if (m_opaque_ptr->m_working_dir.empty())
172b952cd58SEd Maste     return NULL;
173b952cd58SEd Maste   return m_opaque_ptr->m_working_dir.c_str();
174b952cd58SEd Maste }
175b952cd58SEd Maste 
SetWorkingDirectory(const char * path)176435933ddSDimitry Andric void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
177b952cd58SEd Maste   if (path && path[0])
178b952cd58SEd Maste     m_opaque_ptr->m_working_dir = path;
179b952cd58SEd Maste   else
180b952cd58SEd Maste     m_opaque_ptr->m_working_dir.clear();
181b952cd58SEd Maste }
182b952cd58SEd Maste 
GetTimeoutSeconds()183435933ddSDimitry Andric uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
1844ba319b5SDimitry Andric   if (m_opaque_ptr->m_timeout)
1854ba319b5SDimitry Andric     return m_opaque_ptr->m_timeout->count();
1864ba319b5SDimitry Andric   return UINT32_MAX;
187b952cd58SEd Maste }
188b952cd58SEd Maste 
SetTimeoutSeconds(uint32_t sec)189435933ddSDimitry Andric void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
1904ba319b5SDimitry Andric   if (sec == UINT32_MAX)
1914ba319b5SDimitry Andric     m_opaque_ptr->m_timeout = llvm::None;
1924ba319b5SDimitry Andric   else
1934ba319b5SDimitry Andric     m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
194b952cd58SEd Maste }
195b952cd58SEd Maste 
GetSignal()196435933ddSDimitry Andric int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
197b952cd58SEd Maste 
GetStatus()198435933ddSDimitry Andric int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
199b952cd58SEd Maste 
GetOutput()200435933ddSDimitry Andric const char *SBPlatformShellCommand::GetOutput() {
201b952cd58SEd Maste   if (m_opaque_ptr->m_output.empty())
202b952cd58SEd Maste     return NULL;
203b952cd58SEd Maste   return m_opaque_ptr->m_output.c_str();
204b952cd58SEd Maste }
205b952cd58SEd Maste 
206b952cd58SEd Maste //----------------------------------------------------------------------
207b952cd58SEd Maste // SBPlatform
208b952cd58SEd Maste //----------------------------------------------------------------------
SBPlatform()209435933ddSDimitry Andric SBPlatform::SBPlatform() : m_opaque_sp() {}
210b952cd58SEd Maste 
SBPlatform(const char * platform_name)211435933ddSDimitry Andric SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
2125517e702SDimitry Andric   Status error;
2137aa51b79SEd Maste   if (platform_name && platform_name[0])
2147aa51b79SEd Maste     m_opaque_sp = Platform::Create(ConstString(platform_name), error);
215b952cd58SEd Maste }
216b952cd58SEd Maste 
~SBPlatform()217435933ddSDimitry Andric SBPlatform::~SBPlatform() {}
218b952cd58SEd Maste 
IsValid() const219435933ddSDimitry Andric bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
220b952cd58SEd Maste 
Clear()221435933ddSDimitry Andric void SBPlatform::Clear() { m_opaque_sp.reset(); }
222b952cd58SEd Maste 
GetName()223435933ddSDimitry Andric const char *SBPlatform::GetName() {
224b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
225b952cd58SEd Maste   if (platform_sp)
226b952cd58SEd Maste     return platform_sp->GetName().GetCString();
227b952cd58SEd Maste   return NULL;
228b952cd58SEd Maste }
229b952cd58SEd Maste 
GetSP() const230435933ddSDimitry Andric lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
231b952cd58SEd Maste 
SetSP(const lldb::PlatformSP & platform_sp)232435933ddSDimitry Andric void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
233b952cd58SEd Maste   m_opaque_sp = platform_sp;
234b952cd58SEd Maste }
235b952cd58SEd Maste 
GetWorkingDirectory()236435933ddSDimitry Andric const char *SBPlatform::GetWorkingDirectory() {
237b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
238b952cd58SEd Maste   if (platform_sp)
239b952cd58SEd Maste     return platform_sp->GetWorkingDirectory().GetCString();
240b952cd58SEd Maste   return NULL;
241b952cd58SEd Maste }
242b952cd58SEd Maste 
SetWorkingDirectory(const char * path)243435933ddSDimitry Andric bool SBPlatform::SetWorkingDirectory(const char *path) {
244b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
245435933ddSDimitry Andric   if (platform_sp) {
246b952cd58SEd Maste     if (path)
247*b5893f02SDimitry Andric       platform_sp->SetWorkingDirectory(FileSpec(path));
248b952cd58SEd Maste     else
249*b5893f02SDimitry Andric       platform_sp->SetWorkingDirectory(FileSpec());
250b952cd58SEd Maste     return true;
251b952cd58SEd Maste   }
252b952cd58SEd Maste   return false;
253b952cd58SEd Maste }
254b952cd58SEd Maste 
ConnectRemote(SBPlatformConnectOptions & connect_options)255435933ddSDimitry Andric SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
256b952cd58SEd Maste   SBError sb_error;
257b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
258435933ddSDimitry Andric   if (platform_sp && connect_options.GetURL()) {
259b952cd58SEd Maste     Args args;
260435933ddSDimitry Andric     args.AppendArgument(
261435933ddSDimitry Andric         llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
262b952cd58SEd Maste     sb_error.ref() = platform_sp->ConnectRemote(args);
263435933ddSDimitry Andric   } else {
264b952cd58SEd Maste     sb_error.SetErrorString("invalid platform");
265b952cd58SEd Maste   }
266b952cd58SEd Maste   return sb_error;
267b952cd58SEd Maste }
268b952cd58SEd Maste 
DisconnectRemote()269435933ddSDimitry Andric void SBPlatform::DisconnectRemote() {
270b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
271b952cd58SEd Maste   if (platform_sp)
272b952cd58SEd Maste     platform_sp->DisconnectRemote();
273b952cd58SEd Maste }
274b952cd58SEd Maste 
IsConnected()275435933ddSDimitry Andric bool SBPlatform::IsConnected() {
276b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
277b952cd58SEd Maste   if (platform_sp)
2784ba319b5SDimitry Andric     return platform_sp->IsConnected();
279b952cd58SEd Maste   return false;
280b952cd58SEd Maste }
281b952cd58SEd Maste 
GetTriple()282435933ddSDimitry Andric const char *SBPlatform::GetTriple() {
283b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
284435933ddSDimitry Andric   if (platform_sp) {
2851c3bbb01SEd Maste     ArchSpec arch(platform_sp->GetSystemArchitecture());
286435933ddSDimitry Andric     if (arch.IsValid()) {
287435933ddSDimitry Andric       // Const-ify the string so we don't need to worry about the lifetime of
288435933ddSDimitry Andric       // the string
289b952cd58SEd Maste       return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
290b952cd58SEd Maste     }
291b952cd58SEd Maste   }
292b952cd58SEd Maste   return NULL;
293b952cd58SEd Maste }
294b952cd58SEd Maste 
GetOSBuild()295435933ddSDimitry Andric const char *SBPlatform::GetOSBuild() {
296b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
297435933ddSDimitry Andric   if (platform_sp) {
298b952cd58SEd Maste     std::string s;
299435933ddSDimitry Andric     if (platform_sp->GetOSBuildString(s)) {
300435933ddSDimitry Andric       if (!s.empty()) {
301435933ddSDimitry Andric         // Const-ify the string so we don't need to worry about the lifetime of
302435933ddSDimitry Andric         // the string
303b952cd58SEd Maste         return ConstString(s.c_str()).GetCString();
304b952cd58SEd Maste       }
305b952cd58SEd Maste     }
306b952cd58SEd Maste   }
307b952cd58SEd Maste   return NULL;
308b952cd58SEd Maste }
309b952cd58SEd Maste 
GetOSDescription()310435933ddSDimitry Andric const char *SBPlatform::GetOSDescription() {
311b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
312435933ddSDimitry Andric   if (platform_sp) {
313b952cd58SEd Maste     std::string s;
314435933ddSDimitry Andric     if (platform_sp->GetOSKernelDescription(s)) {
315435933ddSDimitry Andric       if (!s.empty()) {
316435933ddSDimitry Andric         // Const-ify the string so we don't need to worry about the lifetime of
317435933ddSDimitry Andric         // the string
318b952cd58SEd Maste         return ConstString(s.c_str()).GetCString();
319b952cd58SEd Maste       }
320b952cd58SEd Maste     }
321b952cd58SEd Maste   }
322b952cd58SEd Maste   return NULL;
323b952cd58SEd Maste }
324b952cd58SEd Maste 
GetHostname()325435933ddSDimitry Andric const char *SBPlatform::GetHostname() {
326b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
327b952cd58SEd Maste   if (platform_sp)
328b952cd58SEd Maste     return platform_sp->GetHostname();
329b952cd58SEd Maste   return NULL;
330b952cd58SEd Maste }
331b952cd58SEd Maste 
GetOSMajorVersion()332435933ddSDimitry Andric uint32_t SBPlatform::GetOSMajorVersion() {
3334ba319b5SDimitry Andric   llvm::VersionTuple version;
3344ba319b5SDimitry Andric   if (PlatformSP platform_sp = GetSP())
3354ba319b5SDimitry Andric     version = platform_sp->GetOSVersion();
3364ba319b5SDimitry Andric   return version.empty() ? UINT32_MAX : version.getMajor();
337b952cd58SEd Maste }
338b952cd58SEd Maste 
GetOSMinorVersion()339435933ddSDimitry Andric uint32_t SBPlatform::GetOSMinorVersion() {
3404ba319b5SDimitry Andric   llvm::VersionTuple version;
3414ba319b5SDimitry Andric   if (PlatformSP platform_sp = GetSP())
3424ba319b5SDimitry Andric     version = platform_sp->GetOSVersion();
3434ba319b5SDimitry Andric   return version.getMinor().getValueOr(UINT32_MAX);
344b952cd58SEd Maste }
345b952cd58SEd Maste 
GetOSUpdateVersion()346435933ddSDimitry Andric uint32_t SBPlatform::GetOSUpdateVersion() {
3474ba319b5SDimitry Andric   llvm::VersionTuple version;
3484ba319b5SDimitry Andric   if (PlatformSP platform_sp = GetSP())
3494ba319b5SDimitry Andric     version = platform_sp->GetOSVersion();
3504ba319b5SDimitry Andric   return version.getSubminor().getValueOr(UINT32_MAX);
351b952cd58SEd Maste }
352b952cd58SEd Maste 
Get(SBFileSpec & src,SBFileSpec & dst)353435933ddSDimitry Andric SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
354b952cd58SEd Maste   SBError sb_error;
355b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
356435933ddSDimitry Andric   if (platform_sp) {
357b952cd58SEd Maste     sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
358435933ddSDimitry Andric   } else {
359b952cd58SEd Maste     sb_error.SetErrorString("invalid platform");
360b952cd58SEd Maste   }
361b952cd58SEd Maste   return sb_error;
362b952cd58SEd Maste }
363b952cd58SEd Maste 
Put(SBFileSpec & src,SBFileSpec & dst)364435933ddSDimitry Andric SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
365435933ddSDimitry Andric   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
366435933ddSDimitry Andric     if (src.Exists()) {
367*b5893f02SDimitry Andric       uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
368435933ddSDimitry Andric       if (permissions == 0) {
369*b5893f02SDimitry Andric         if (FileSystem::Instance().IsDirectory(src.ref()))
370b952cd58SEd Maste           permissions = eFilePermissionsDirectoryDefault;
371b952cd58SEd Maste         else
372b952cd58SEd Maste           permissions = eFilePermissionsFileDefault;
373b952cd58SEd Maste       }
374b952cd58SEd Maste 
3751c3bbb01SEd Maste       return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
376b952cd58SEd Maste     }
3771c3bbb01SEd Maste 
3785517e702SDimitry Andric     Status error;
379435933ddSDimitry Andric     error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
380435933ddSDimitry Andric                                    src.ref().GetPath().c_str());
3811c3bbb01SEd Maste     return error;
3821c3bbb01SEd Maste   });
383b952cd58SEd Maste }
384b952cd58SEd Maste 
Install(SBFileSpec & src,SBFileSpec & dst)385435933ddSDimitry Andric SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
386435933ddSDimitry Andric   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
387b952cd58SEd Maste     if (src.Exists())
3881c3bbb01SEd Maste       return platform_sp->Install(src.ref(), dst.ref());
3891c3bbb01SEd Maste 
3905517e702SDimitry Andric     Status error;
391435933ddSDimitry Andric     error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
392435933ddSDimitry Andric                                    src.ref().GetPath().c_str());
3931c3bbb01SEd Maste     return error;
3941c3bbb01SEd Maste   });
395b952cd58SEd Maste }
396b952cd58SEd Maste 
Run(SBPlatformShellCommand & shell_command)397435933ddSDimitry Andric SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
398435933ddSDimitry Andric   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
399b952cd58SEd Maste     const char *command = shell_command.GetCommand();
4001c3bbb01SEd Maste     if (!command)
4015517e702SDimitry Andric       return Status("invalid shell command (empty)");
4021c3bbb01SEd Maste 
403b952cd58SEd Maste     const char *working_dir = shell_command.GetWorkingDirectory();
404435933ddSDimitry Andric     if (working_dir == NULL) {
405b952cd58SEd Maste       working_dir = platform_sp->GetWorkingDirectory().GetCString();
406b952cd58SEd Maste       if (working_dir)
407b952cd58SEd Maste         shell_command.SetWorkingDirectory(working_dir);
408b952cd58SEd Maste     }
409*b5893f02SDimitry Andric     return platform_sp->RunShellCommand(command, FileSpec(working_dir),
410b952cd58SEd Maste                                         &shell_command.m_opaque_ptr->m_status,
411b952cd58SEd Maste                                         &shell_command.m_opaque_ptr->m_signo,
412b952cd58SEd Maste                                         &shell_command.m_opaque_ptr->m_output,
4134ba319b5SDimitry Andric                                         shell_command.m_opaque_ptr->m_timeout);
4141c3bbb01SEd Maste   });
415b952cd58SEd Maste }
4161c3bbb01SEd Maste 
Launch(SBLaunchInfo & launch_info)417435933ddSDimitry Andric SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
418435933ddSDimitry Andric   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
4194ba319b5SDimitry Andric     ProcessLaunchInfo info = launch_info.ref();
4204ba319b5SDimitry Andric     Status error = platform_sp->LaunchProcess(info);
4214ba319b5SDimitry Andric     launch_info.set_ref(info);
4224ba319b5SDimitry Andric     return error;
4231c3bbb01SEd Maste   });
4241c3bbb01SEd Maste }
4251c3bbb01SEd Maste 
Kill(const lldb::pid_t pid)426435933ddSDimitry Andric SBError SBPlatform::Kill(const lldb::pid_t pid) {
427435933ddSDimitry Andric   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
4281c3bbb01SEd Maste     return platform_sp->KillProcess(pid);
4291c3bbb01SEd Maste   });
4301c3bbb01SEd Maste }
4311c3bbb01SEd Maste 
ExecuteConnected(const std::function<Status (const lldb::PlatformSP &)> & func)432435933ddSDimitry Andric SBError SBPlatform::ExecuteConnected(
4335517e702SDimitry Andric     const std::function<Status(const lldb::PlatformSP &)> &func) {
4341c3bbb01SEd Maste   SBError sb_error;
4351c3bbb01SEd Maste   const auto platform_sp(GetSP());
436435933ddSDimitry Andric   if (platform_sp) {
4371c3bbb01SEd Maste     if (platform_sp->IsConnected())
4381c3bbb01SEd Maste       sb_error.ref() = func(platform_sp);
4391c3bbb01SEd Maste     else
440b952cd58SEd Maste       sb_error.SetErrorString("not connected");
441435933ddSDimitry Andric   } else
442b952cd58SEd Maste     sb_error.SetErrorString("invalid platform");
4431c3bbb01SEd Maste 
444b952cd58SEd Maste   return sb_error;
445b952cd58SEd Maste }
446b952cd58SEd Maste 
MakeDirectory(const char * path,uint32_t file_permissions)447435933ddSDimitry Andric SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
448b952cd58SEd Maste   SBError sb_error;
449b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
450435933ddSDimitry Andric   if (platform_sp) {
451435933ddSDimitry Andric     sb_error.ref() =
452*b5893f02SDimitry Andric         platform_sp->MakeDirectory(FileSpec(path), file_permissions);
453435933ddSDimitry Andric   } else {
454b952cd58SEd Maste     sb_error.SetErrorString("invalid platform");
455b952cd58SEd Maste   }
456b952cd58SEd Maste   return sb_error;
457b952cd58SEd Maste }
458b952cd58SEd Maste 
GetFilePermissions(const char * path)459435933ddSDimitry Andric uint32_t SBPlatform::GetFilePermissions(const char *path) {
460b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
461435933ddSDimitry Andric   if (platform_sp) {
462b952cd58SEd Maste     uint32_t file_permissions = 0;
463*b5893f02SDimitry Andric     platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
464b952cd58SEd Maste     return file_permissions;
465b952cd58SEd Maste   }
466b952cd58SEd Maste   return 0;
467b952cd58SEd Maste }
468b952cd58SEd Maste 
SetFilePermissions(const char * path,uint32_t file_permissions)469435933ddSDimitry Andric SBError SBPlatform::SetFilePermissions(const char *path,
470435933ddSDimitry Andric                                        uint32_t file_permissions) {
471b952cd58SEd Maste   SBError sb_error;
472b952cd58SEd Maste   PlatformSP platform_sp(GetSP());
473435933ddSDimitry Andric   if (platform_sp) {
474*b5893f02SDimitry Andric     sb_error.ref() =
475*b5893f02SDimitry Andric         platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
476435933ddSDimitry Andric   } else {
477b952cd58SEd Maste     sb_error.SetErrorString("invalid platform");
478b952cd58SEd Maste   }
479b952cd58SEd Maste   return sb_error;
480b952cd58SEd Maste }
481b952cd58SEd Maste 
GetUnixSignals() const482435933ddSDimitry Andric SBUnixSignals SBPlatform::GetUnixSignals() const {
483b91a7dfcSDimitry Andric   if (auto platform_sp = GetSP())
484b91a7dfcSDimitry Andric     return SBUnixSignals{platform_sp};
485b91a7dfcSDimitry Andric 
486b91a7dfcSDimitry Andric   return {};
487b91a7dfcSDimitry Andric }
488