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