1 //===-- SBPlatform.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBPlatform.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBEnvironment.h"
12 #include "lldb/API/SBError.h"
13 #include "lldb/API/SBFileSpec.h"
14 #include "lldb/API/SBLaunchInfo.h"
15 #include "lldb/API/SBPlatform.h"
16 #include "lldb/API/SBUnixSignals.h"
17 #include "lldb/Host/File.h"
18 #include "lldb/Target/Platform.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/ArchSpec.h"
21 #include "lldb/Utility/Args.h"
22 #include "lldb/Utility/Status.h"
23 
24 #include "llvm/Support/FileSystem.h"
25 
26 #include <functional>
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 // PlatformConnectOptions
32 struct PlatformConnectOptions {
PlatformConnectOptionsPlatformConnectOptions33   PlatformConnectOptions(const char *url = nullptr)
34       : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
35 
36         m_local_cache_directory() {
37     if (url && url[0])
38       m_url = url;
39   }
40 
41   ~PlatformConnectOptions() = default;
42 
43   std::string m_url;
44   std::string m_rsync_options;
45   std::string m_rsync_remote_path_prefix;
46   bool m_rsync_enabled = false;
47   bool m_rsync_omit_hostname_from_remote_path = false;
48   ConstString m_local_cache_directory;
49 };
50 
51 // PlatformShellCommand
52 struct PlatformShellCommand {
PlatformShellCommandPlatformShellCommand53   PlatformShellCommand(llvm::StringRef shell_interpreter,
54                        llvm::StringRef shell_command)
55       : m_command(), m_working_dir(), m_status(0), m_signo(0) {
56     if (!shell_interpreter.empty())
57       m_shell = shell_interpreter.str();
58 
59     if (!m_shell.empty() && !shell_command.empty())
60       m_command = shell_command.str();
61   }
62 
PlatformShellCommandPlatformShellCommand63   PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef())
64       : m_shell(), m_command(), m_working_dir() {
65     if (!shell_command.empty())
66       m_command = shell_command.str();
67   }
68 
69   ~PlatformShellCommand() = default;
70 
71   std::string m_shell;
72   std::string m_command;
73   std::string m_working_dir;
74   std::string m_output;
75   int m_status = 0;
76   int m_signo = 0;
77   Timeout<std::ratio<1>> m_timeout = llvm::None;
78 };
79 // SBPlatformConnectOptions
SBPlatformConnectOptions(const char * url)80 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
81     : m_opaque_ptr(new PlatformConnectOptions(url)) {
82   LLDB_RECORD_CONSTRUCTOR(SBPlatformConnectOptions, (const char *), url);
83 }
84 
SBPlatformConnectOptions(const SBPlatformConnectOptions & rhs)85 SBPlatformConnectOptions::SBPlatformConnectOptions(
86     const SBPlatformConnectOptions &rhs)
87     : m_opaque_ptr(new PlatformConnectOptions()) {
88   LLDB_RECORD_CONSTRUCTOR(SBPlatformConnectOptions,
89                           (const lldb::SBPlatformConnectOptions &), rhs);
90 
91   *m_opaque_ptr = *rhs.m_opaque_ptr;
92 }
93 
~SBPlatformConnectOptions()94 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
95 
96 SBPlatformConnectOptions &
operator =(const SBPlatformConnectOptions & rhs)97 SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
98   LLDB_RECORD_METHOD(
99       SBPlatformConnectOptions &,
100       SBPlatformConnectOptions, operator=,(
101                                     const lldb::SBPlatformConnectOptions &),
102       rhs);
103 
104   *m_opaque_ptr = *rhs.m_opaque_ptr;
105   return LLDB_RECORD_RESULT(*this);
106 }
107 
GetURL()108 const char *SBPlatformConnectOptions::GetURL() {
109   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformConnectOptions, GetURL);
110 
111   if (m_opaque_ptr->m_url.empty())
112     return nullptr;
113   return m_opaque_ptr->m_url.c_str();
114 }
115 
SetURL(const char * url)116 void SBPlatformConnectOptions::SetURL(const char *url) {
117   LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, SetURL, (const char *),
118                      url);
119 
120   if (url && url[0])
121     m_opaque_ptr->m_url = url;
122   else
123     m_opaque_ptr->m_url.clear();
124 }
125 
GetRsyncEnabled()126 bool SBPlatformConnectOptions::GetRsyncEnabled() {
127   LLDB_RECORD_METHOD_NO_ARGS(bool, SBPlatformConnectOptions, GetRsyncEnabled);
128 
129   return m_opaque_ptr->m_rsync_enabled;
130 }
131 
EnableRsync(const char * options,const char * remote_path_prefix,bool omit_hostname_from_remote_path)132 void SBPlatformConnectOptions::EnableRsync(
133     const char *options, const char *remote_path_prefix,
134     bool omit_hostname_from_remote_path) {
135   LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, EnableRsync,
136                      (const char *, const char *, bool), options,
137                      remote_path_prefix, omit_hostname_from_remote_path);
138 
139   m_opaque_ptr->m_rsync_enabled = true;
140   m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
141       omit_hostname_from_remote_path;
142   if (remote_path_prefix && remote_path_prefix[0])
143     m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
144   else
145     m_opaque_ptr->m_rsync_remote_path_prefix.clear();
146 
147   if (options && options[0])
148     m_opaque_ptr->m_rsync_options = options;
149   else
150     m_opaque_ptr->m_rsync_options.clear();
151 }
152 
DisableRsync()153 void SBPlatformConnectOptions::DisableRsync() {
154   LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatformConnectOptions, DisableRsync);
155 
156   m_opaque_ptr->m_rsync_enabled = false;
157 }
158 
GetLocalCacheDirectory()159 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
160   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformConnectOptions,
161                              GetLocalCacheDirectory);
162 
163   return m_opaque_ptr->m_local_cache_directory.GetCString();
164 }
165 
SetLocalCacheDirectory(const char * path)166 void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
167   LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, SetLocalCacheDirectory,
168                      (const char *), path);
169 
170   if (path && path[0])
171     m_opaque_ptr->m_local_cache_directory.SetCString(path);
172   else
173     m_opaque_ptr->m_local_cache_directory = ConstString();
174 }
175 
176 // SBPlatformShellCommand
SBPlatformShellCommand(const char * shell_interpreter,const char * shell_command)177 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
178                                                const char *shell_command)
179     : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
180   LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *, const char *),
181                           shell_interpreter, shell_command);
182 }
183 
SBPlatformShellCommand(const char * shell_command)184 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
185     : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
186   LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *),
187                           shell_command);
188 }
189 
SBPlatformShellCommand(const SBPlatformShellCommand & rhs)190 SBPlatformShellCommand::SBPlatformShellCommand(
191     const SBPlatformShellCommand &rhs)
192     : m_opaque_ptr(new PlatformShellCommand()) {
193   LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand,
194                           (const lldb::SBPlatformShellCommand &), rhs);
195 
196   *m_opaque_ptr = *rhs.m_opaque_ptr;
197 }
198 
199 SBPlatformShellCommand &
operator =(const SBPlatformShellCommand & rhs)200 SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {
201 
202   LLDB_RECORD_METHOD(
203       SBPlatformShellCommand &,
204       SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &),
205       rhs);
206 
207   *m_opaque_ptr = *rhs.m_opaque_ptr;
208   return LLDB_RECORD_RESULT(*this);
209 }
210 
~SBPlatformShellCommand()211 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
212 
Clear()213 void SBPlatformShellCommand::Clear() {
214   LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatformShellCommand, Clear);
215 
216   m_opaque_ptr->m_output = std::string();
217   m_opaque_ptr->m_status = 0;
218   m_opaque_ptr->m_signo = 0;
219 }
220 
GetShell()221 const char *SBPlatformShellCommand::GetShell() {
222   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetShell);
223 
224   if (m_opaque_ptr->m_shell.empty())
225     return nullptr;
226   return m_opaque_ptr->m_shell.c_str();
227 }
228 
SetShell(const char * shell_interpreter)229 void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
230   LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetShell, (const char *),
231                      shell_interpreter);
232 
233   if (shell_interpreter && shell_interpreter[0])
234     m_opaque_ptr->m_shell = shell_interpreter;
235   else
236     m_opaque_ptr->m_shell.clear();
237 }
238 
GetCommand()239 const char *SBPlatformShellCommand::GetCommand() {
240   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetCommand);
241 
242   if (m_opaque_ptr->m_command.empty())
243     return nullptr;
244   return m_opaque_ptr->m_command.c_str();
245 }
246 
SetCommand(const char * shell_command)247 void SBPlatformShellCommand::SetCommand(const char *shell_command) {
248   LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetCommand, (const char *),
249                      shell_command);
250 
251   if (shell_command && shell_command[0])
252     m_opaque_ptr->m_command = shell_command;
253   else
254     m_opaque_ptr->m_command.clear();
255 }
256 
GetWorkingDirectory()257 const char *SBPlatformShellCommand::GetWorkingDirectory() {
258   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand,
259                              GetWorkingDirectory);
260 
261   if (m_opaque_ptr->m_working_dir.empty())
262     return nullptr;
263   return m_opaque_ptr->m_working_dir.c_str();
264 }
265 
SetWorkingDirectory(const char * path)266 void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
267   LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetWorkingDirectory,
268                      (const char *), path);
269 
270   if (path && path[0])
271     m_opaque_ptr->m_working_dir = path;
272   else
273     m_opaque_ptr->m_working_dir.clear();
274 }
275 
GetTimeoutSeconds()276 uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
277   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatformShellCommand,
278                              GetTimeoutSeconds);
279 
280   if (m_opaque_ptr->m_timeout)
281     return m_opaque_ptr->m_timeout->count();
282   return UINT32_MAX;
283 }
284 
SetTimeoutSeconds(uint32_t sec)285 void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
286   LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetTimeoutSeconds,
287                      (uint32_t), sec);
288 
289   if (sec == UINT32_MAX)
290     m_opaque_ptr->m_timeout = llvm::None;
291   else
292     m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
293 }
294 
GetSignal()295 int SBPlatformShellCommand::GetSignal() {
296   LLDB_RECORD_METHOD_NO_ARGS(int, SBPlatformShellCommand, GetSignal);
297 
298   return m_opaque_ptr->m_signo;
299 }
300 
GetStatus()301 int SBPlatformShellCommand::GetStatus() {
302   LLDB_RECORD_METHOD_NO_ARGS(int, SBPlatformShellCommand, GetStatus);
303 
304   return m_opaque_ptr->m_status;
305 }
306 
GetOutput()307 const char *SBPlatformShellCommand::GetOutput() {
308   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetOutput);
309 
310   if (m_opaque_ptr->m_output.empty())
311     return nullptr;
312   return m_opaque_ptr->m_output.c_str();
313 }
314 
315 // SBPlatform
SBPlatform()316 SBPlatform::SBPlatform() : m_opaque_sp() {
317   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBPlatform);
318 }
319 
SBPlatform(const char * platform_name)320 SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
321   LLDB_RECORD_CONSTRUCTOR(SBPlatform, (const char *), platform_name);
322 
323   Status error;
324   if (platform_name && platform_name[0])
325     m_opaque_sp = Platform::Create(ConstString(platform_name), error);
326 }
327 
SBPlatform(const SBPlatform & rhs)328 SBPlatform::SBPlatform(const SBPlatform &rhs) {
329   LLDB_RECORD_CONSTRUCTOR(SBPlatform, (const lldb::SBPlatform &), rhs);
330 
331   m_opaque_sp = rhs.m_opaque_sp;
332 }
333 
operator =(const SBPlatform & rhs)334 SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) {
335   LLDB_RECORD_METHOD(SBPlatform &,
336                      SBPlatform, operator=,(const lldb::SBPlatform &), rhs);
337 
338   m_opaque_sp = rhs.m_opaque_sp;
339   return LLDB_RECORD_RESULT(*this);
340 }
341 
342 SBPlatform::~SBPlatform() = default;
343 
GetHostPlatform()344 SBPlatform SBPlatform::GetHostPlatform() {
345   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBPlatform, SBPlatform,
346                                     GetHostPlatform);
347 
348   SBPlatform host_platform;
349   host_platform.m_opaque_sp = Platform::GetHostPlatform();
350   return LLDB_RECORD_RESULT(host_platform);
351 }
352 
IsValid() const353 bool SBPlatform::IsValid() const {
354   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBPlatform, IsValid);
355   return this->operator bool();
356 }
operator bool() const357 SBPlatform::operator bool() const {
358   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBPlatform, operator bool);
359 
360   return m_opaque_sp.get() != nullptr;
361 }
362 
Clear()363 void SBPlatform::Clear() {
364   LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatform, Clear);
365 
366   m_opaque_sp.reset();
367 }
368 
GetName()369 const char *SBPlatform::GetName() {
370   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetName);
371 
372   PlatformSP platform_sp(GetSP());
373   if (platform_sp)
374     return platform_sp->GetName().GetCString();
375   return nullptr;
376 }
377 
GetSP() const378 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
379 
SetSP(const lldb::PlatformSP & platform_sp)380 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
381   m_opaque_sp = platform_sp;
382 }
383 
GetWorkingDirectory()384 const char *SBPlatform::GetWorkingDirectory() {
385   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetWorkingDirectory);
386 
387   PlatformSP platform_sp(GetSP());
388   if (platform_sp)
389     return platform_sp->GetWorkingDirectory().GetCString();
390   return nullptr;
391 }
392 
SetWorkingDirectory(const char * path)393 bool SBPlatform::SetWorkingDirectory(const char *path) {
394   LLDB_RECORD_METHOD(bool, SBPlatform, SetWorkingDirectory, (const char *),
395                      path);
396 
397   PlatformSP platform_sp(GetSP());
398   if (platform_sp) {
399     if (path)
400       platform_sp->SetWorkingDirectory(FileSpec(path));
401     else
402       platform_sp->SetWorkingDirectory(FileSpec());
403     return true;
404   }
405   return false;
406 }
407 
ConnectRemote(SBPlatformConnectOptions & connect_options)408 SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
409   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, ConnectRemote,
410                      (lldb::SBPlatformConnectOptions &), connect_options);
411 
412   SBError sb_error;
413   PlatformSP platform_sp(GetSP());
414   if (platform_sp && connect_options.GetURL()) {
415     Args args;
416     args.AppendArgument(connect_options.GetURL());
417     sb_error.ref() = platform_sp->ConnectRemote(args);
418   } else {
419     sb_error.SetErrorString("invalid platform");
420   }
421   return LLDB_RECORD_RESULT(sb_error);
422 }
423 
DisconnectRemote()424 void SBPlatform::DisconnectRemote() {
425   LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatform, DisconnectRemote);
426 
427   PlatformSP platform_sp(GetSP());
428   if (platform_sp)
429     platform_sp->DisconnectRemote();
430 }
431 
IsConnected()432 bool SBPlatform::IsConnected() {
433   LLDB_RECORD_METHOD_NO_ARGS(bool, SBPlatform, IsConnected);
434 
435   PlatformSP platform_sp(GetSP());
436   if (platform_sp)
437     return platform_sp->IsConnected();
438   return false;
439 }
440 
GetTriple()441 const char *SBPlatform::GetTriple() {
442   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetTriple);
443 
444   PlatformSP platform_sp(GetSP());
445   if (platform_sp) {
446     ArchSpec arch(platform_sp->GetSystemArchitecture());
447     if (arch.IsValid()) {
448       // Const-ify the string so we don't need to worry about the lifetime of
449       // the string
450       return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
451     }
452   }
453   return nullptr;
454 }
455 
GetOSBuild()456 const char *SBPlatform::GetOSBuild() {
457   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetOSBuild);
458 
459   PlatformSP platform_sp(GetSP());
460   if (platform_sp) {
461     std::string s;
462     if (platform_sp->GetOSBuildString(s)) {
463       if (!s.empty()) {
464         // Const-ify the string so we don't need to worry about the lifetime of
465         // the string
466         return ConstString(s.c_str()).GetCString();
467       }
468     }
469   }
470   return nullptr;
471 }
472 
GetOSDescription()473 const char *SBPlatform::GetOSDescription() {
474   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetOSDescription);
475 
476   PlatformSP platform_sp(GetSP());
477   if (platform_sp) {
478     std::string s;
479     if (platform_sp->GetOSKernelDescription(s)) {
480       if (!s.empty()) {
481         // Const-ify the string so we don't need to worry about the lifetime of
482         // the string
483         return ConstString(s.c_str()).GetCString();
484       }
485     }
486   }
487   return nullptr;
488 }
489 
GetHostname()490 const char *SBPlatform::GetHostname() {
491   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetHostname);
492 
493   PlatformSP platform_sp(GetSP());
494   if (platform_sp)
495     return platform_sp->GetHostname();
496   return nullptr;
497 }
498 
GetOSMajorVersion()499 uint32_t SBPlatform::GetOSMajorVersion() {
500   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSMajorVersion);
501 
502   llvm::VersionTuple version;
503   if (PlatformSP platform_sp = GetSP())
504     version = platform_sp->GetOSVersion();
505   return version.empty() ? UINT32_MAX : version.getMajor();
506 }
507 
GetOSMinorVersion()508 uint32_t SBPlatform::GetOSMinorVersion() {
509   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSMinorVersion);
510 
511   llvm::VersionTuple version;
512   if (PlatformSP platform_sp = GetSP())
513     version = platform_sp->GetOSVersion();
514   return version.getMinor().getValueOr(UINT32_MAX);
515 }
516 
GetOSUpdateVersion()517 uint32_t SBPlatform::GetOSUpdateVersion() {
518   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSUpdateVersion);
519 
520   llvm::VersionTuple version;
521   if (PlatformSP platform_sp = GetSP())
522     version = platform_sp->GetOSVersion();
523   return version.getSubminor().getValueOr(UINT32_MAX);
524 }
525 
Get(SBFileSpec & src,SBFileSpec & dst)526 SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
527   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Get,
528                      (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst);
529 
530   SBError sb_error;
531   PlatformSP platform_sp(GetSP());
532   if (platform_sp) {
533     sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
534   } else {
535     sb_error.SetErrorString("invalid platform");
536   }
537   return LLDB_RECORD_RESULT(sb_error);
538 }
539 
Put(SBFileSpec & src,SBFileSpec & dst)540 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
541   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Put,
542                      (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst);
543   return LLDB_RECORD_RESULT(
544       ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
545         if (src.Exists()) {
546           uint32_t permissions =
547               FileSystem::Instance().GetPermissions(src.ref());
548           if (permissions == 0) {
549             if (FileSystem::Instance().IsDirectory(src.ref()))
550               permissions = eFilePermissionsDirectoryDefault;
551             else
552               permissions = eFilePermissionsFileDefault;
553           }
554 
555           return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
556         }
557 
558         Status error;
559         error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
560                                        src.ref().GetPath().c_str());
561         return error;
562       }));
563 }
564 
Install(SBFileSpec & src,SBFileSpec & dst)565 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
566   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Install,
567                      (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst);
568   return LLDB_RECORD_RESULT(
569       ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
570         if (src.Exists())
571           return platform_sp->Install(src.ref(), dst.ref());
572 
573         Status error;
574         error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
575                                        src.ref().GetPath().c_str());
576         return error;
577       }));
578 }
579 
Run(SBPlatformShellCommand & shell_command)580 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
581   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Run,
582                      (lldb::SBPlatformShellCommand &), shell_command);
583   return LLDB_RECORD_RESULT(
584       ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
585         const char *command = shell_command.GetCommand();
586         if (!command)
587           return Status("invalid shell command (empty)");
588 
589         const char *working_dir = shell_command.GetWorkingDirectory();
590         if (working_dir == nullptr) {
591           working_dir = platform_sp->GetWorkingDirectory().GetCString();
592           if (working_dir)
593             shell_command.SetWorkingDirectory(working_dir);
594         }
595         return platform_sp->RunShellCommand(
596             shell_command.m_opaque_ptr->m_shell, command, FileSpec(working_dir),
597             &shell_command.m_opaque_ptr->m_status,
598             &shell_command.m_opaque_ptr->m_signo,
599             &shell_command.m_opaque_ptr->m_output,
600             shell_command.m_opaque_ptr->m_timeout);
601       }));
602 }
603 
Launch(SBLaunchInfo & launch_info)604 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
605   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Launch, (lldb::SBLaunchInfo &),
606                      launch_info);
607   return LLDB_RECORD_RESULT(
608       ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
609         ProcessLaunchInfo info = launch_info.ref();
610         Status error = platform_sp->LaunchProcess(info);
611         launch_info.set_ref(info);
612         return error;
613       }));
614 }
615 
Kill(const lldb::pid_t pid)616 SBError SBPlatform::Kill(const lldb::pid_t pid) {
617   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Kill, (const lldb::pid_t), pid);
618   return LLDB_RECORD_RESULT(
619       ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
620         return platform_sp->KillProcess(pid);
621       }));
622 }
623 
ExecuteConnected(const std::function<Status (const lldb::PlatformSP &)> & func)624 SBError SBPlatform::ExecuteConnected(
625     const std::function<Status(const lldb::PlatformSP &)> &func) {
626   SBError sb_error;
627   const auto platform_sp(GetSP());
628   if (platform_sp) {
629     if (platform_sp->IsConnected())
630       sb_error.ref() = func(platform_sp);
631     else
632       sb_error.SetErrorString("not connected");
633   } else
634     sb_error.SetErrorString("invalid platform");
635 
636   return sb_error;
637 }
638 
MakeDirectory(const char * path,uint32_t file_permissions)639 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
640   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, MakeDirectory,
641                      (const char *, uint32_t), path, file_permissions);
642 
643   SBError sb_error;
644   PlatformSP platform_sp(GetSP());
645   if (platform_sp) {
646     sb_error.ref() =
647         platform_sp->MakeDirectory(FileSpec(path), file_permissions);
648   } else {
649     sb_error.SetErrorString("invalid platform");
650   }
651   return LLDB_RECORD_RESULT(sb_error);
652 }
653 
GetFilePermissions(const char * path)654 uint32_t SBPlatform::GetFilePermissions(const char *path) {
655   LLDB_RECORD_METHOD(uint32_t, SBPlatform, GetFilePermissions, (const char *),
656                      path);
657 
658   PlatformSP platform_sp(GetSP());
659   if (platform_sp) {
660     uint32_t file_permissions = 0;
661     platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
662     return file_permissions;
663   }
664   return 0;
665 }
666 
SetFilePermissions(const char * path,uint32_t file_permissions)667 SBError SBPlatform::SetFilePermissions(const char *path,
668                                        uint32_t file_permissions) {
669   LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, SetFilePermissions,
670                      (const char *, uint32_t), path, file_permissions);
671 
672   SBError sb_error;
673   PlatformSP platform_sp(GetSP());
674   if (platform_sp) {
675     sb_error.ref() =
676         platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
677   } else {
678     sb_error.SetErrorString("invalid platform");
679   }
680   return LLDB_RECORD_RESULT(sb_error);
681 }
682 
GetUnixSignals() const683 SBUnixSignals SBPlatform::GetUnixSignals() const {
684   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBUnixSignals, SBPlatform,
685                                    GetUnixSignals);
686 
687   if (auto platform_sp = GetSP())
688     return LLDB_RECORD_RESULT(SBUnixSignals{platform_sp});
689 
690   return LLDB_RECORD_RESULT(SBUnixSignals());
691 }
692 
GetEnvironment()693 SBEnvironment SBPlatform::GetEnvironment() {
694   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBPlatform, GetEnvironment);
695   PlatformSP platform_sp(GetSP());
696 
697   if (platform_sp) {
698     return LLDB_RECORD_RESULT(SBEnvironment(platform_sp->GetEnvironment()));
699   }
700 
701   return LLDB_RECORD_RESULT(SBEnvironment());
702 }
703 
704 namespace lldb_private {
705 namespace repro {
706 
RegisterMethods(Registry & R)707 template <> void RegisterMethods<SBPlatformConnectOptions>(Registry &R) {
708   LLDB_REGISTER_CONSTRUCTOR(SBPlatformConnectOptions, (const char *));
709   LLDB_REGISTER_CONSTRUCTOR(SBPlatformConnectOptions,
710                             (const lldb::SBPlatformConnectOptions &));
711   LLDB_REGISTER_METHOD(
712       SBPlatformConnectOptions &,
713       SBPlatformConnectOptions, operator=,(
714                                     const lldb::SBPlatformConnectOptions &));
715   LLDB_REGISTER_METHOD(const char *, SBPlatformConnectOptions, GetURL, ());
716   LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, SetURL, (const char *));
717   LLDB_REGISTER_METHOD(bool, SBPlatformConnectOptions, GetRsyncEnabled, ());
718   LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, EnableRsync,
719                        (const char *, const char *, bool));
720   LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, DisableRsync, ());
721   LLDB_REGISTER_METHOD(const char *, SBPlatformConnectOptions,
722                        GetLocalCacheDirectory, ());
723   LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, SetLocalCacheDirectory,
724                        (const char *));
725 }
726 
RegisterMethods(Registry & R)727 template <> void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
728   LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand, (const char *));
729   LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand,
730                             (const lldb::SBPlatformShellCommand &));
731   LLDB_REGISTER_METHOD(
732       SBPlatformShellCommand &,
733       SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &));
734   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, Clear, ());
735   LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetShell, ());
736   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetShell, (const char *));
737   LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetCommand, ());
738   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetCommand,
739                        (const char *));
740   LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand,
741                        GetWorkingDirectory, ());
742   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetWorkingDirectory,
743                        (const char *));
744   LLDB_REGISTER_METHOD(uint32_t, SBPlatformShellCommand, GetTimeoutSeconds, ());
745   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetTimeoutSeconds,
746                        (uint32_t));
747   LLDB_REGISTER_METHOD(int, SBPlatformShellCommand, GetSignal, ());
748   LLDB_REGISTER_METHOD(int, SBPlatformShellCommand, GetStatus, ());
749   LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetOutput, ());
750 }
751 
RegisterMethods(Registry & R)752 template <> void RegisterMethods<SBPlatform>(Registry &R) {
753   LLDB_REGISTER_CONSTRUCTOR(SBPlatform, ());
754   LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const char *));
755   LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const lldb::SBPlatform &));
756   LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand,
757                             (const char *, const char *));
758   LLDB_REGISTER_METHOD(SBPlatform &,
759                        SBPlatform, operator=,(const lldb::SBPlatform &));
760   LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, IsValid, ());
761   LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, operator bool,());
762   LLDB_REGISTER_METHOD(void, SBPlatform, Clear, ());
763   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetName, ());
764   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetWorkingDirectory, ());
765   LLDB_REGISTER_METHOD(bool, SBPlatform, SetWorkingDirectory, (const char *));
766   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, ConnectRemote,
767                        (lldb::SBPlatformConnectOptions &));
768   LLDB_REGISTER_METHOD(void, SBPlatform, DisconnectRemote, ());
769   LLDB_REGISTER_METHOD(bool, SBPlatform, IsConnected, ());
770   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetTriple, ());
771   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetOSBuild, ());
772   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetOSDescription, ());
773   LLDB_REGISTER_METHOD(const char *, SBPlatform, GetHostname, ());
774   LLDB_REGISTER_METHOD(uint32_t, SBPlatform, GetOSMajorVersion, ());
775   LLDB_REGISTER_METHOD(uint32_t, SBPlatform, GetOSMinorVersion, ());
776   LLDB_REGISTER_METHOD(uint32_t, SBPlatform, GetOSUpdateVersion, ());
777   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Get,
778                        (lldb::SBFileSpec &, lldb::SBFileSpec &));
779   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Put,
780                        (lldb::SBFileSpec &, lldb::SBFileSpec &));
781   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Install,
782                        (lldb::SBFileSpec &, lldb::SBFileSpec &));
783   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Run,
784                        (lldb::SBPlatformShellCommand &));
785   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Launch,
786                        (lldb::SBLaunchInfo &));
787   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, Kill, (const lldb::pid_t));
788   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, MakeDirectory,
789                        (const char *, uint32_t));
790   LLDB_REGISTER_METHOD(uint32_t, SBPlatform, GetFilePermissions,
791                        (const char *));
792   LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, SetFilePermissions,
793                        (const char *, uint32_t));
794   LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBPlatform, GetEnvironment, ());
795   LLDB_REGISTER_METHOD_CONST(lldb::SBUnixSignals, SBPlatform, GetUnixSignals,
796                              ());
797   LLDB_REGISTER_STATIC_METHOD(lldb::SBPlatform, SBPlatform, GetHostPlatform,
798                               ());
799 }
800 
801 } // namespace repro
802 } // namespace lldb_private
803